You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

6.7 KiB

@AGENTS.md

Cleo Minimarket

Aplikasi Next.js 16 (App Router) untuk menggantikan aplikasi back-office minimarket lama berbasis PHP di old-source/. Kode baru ditulis ulang dari nol; old-source/ hanya referensi.

Stack

  • Next.js 16.4 + React 19, TypeScript strict, Tailwind CSS 4, pnpm 11.
  • Drizzle ORM + pg untuk database aplikasi (Postgres).
  • Better Auth 1.7 untuk login: Drizzle adapter ke Postgres, plugin username, sign-up publik ditutup (disableSignUp). CLI-nya package auth (bukan @better-auth/cli yang berhenti di 1.4).
  • shadcn/ui 4 preset base-nova (di atas Base UI, bukan Radix). cn() dari package cn milik shadcn, pengganti clsx + tailwind-merge.

Dua database

Env var Database Isi
DATABASE_URL Postgres (Docker lokal) Milik aplikasi ini: user, session, auth.
AMIGO_DATABASE_URL MariaDB 10.4 cleo (LAN) Data bisnis lama: barang, transaksi, dll.
  • Postgres dikelola penuh oleh Drizzle migration (db:generate lalu db:migrate).
  • MariaDB cleo masih dipakai aplikasi PHP lama. Jangan pernah generate, migrate, atau push ke database ini. Schema Drizzle-nya hanya boleh berasal dari drizzle-kit pull (introspeksi), dengan config terpisah.
  • Server MariaDB 10.4, bukan MySQL 8: hindari fitur yang tidak didukung (mis. sebagian fungsi JSON dan CTE tertentu). Driver: mysql2.

Struktur folder

Tanpa folder src/. Kode aplikasi di root, sejajar config.

app/
  (auth)/login/page.tsx           halaman publik (belum login)
  (dashboard)/layout.tsx          cek session; semua halaman di dalamnya wajib login
  (dashboard)/<fitur>/
    page.tsx                      Server Component: ambil data lewat data/, render
    actions.ts                    Server Actions fitur ini ('use server')
    _components/                  komponen khusus fitur ini
  api/auth/[...all]/route.ts      handler Better Auth (satu-satunya route handler yang wajar)
components/
  ui/                             komponen shadcn (generated, jangan diedit manual kecuali perlu)
  <nama>.tsx                      komponen yang dipakai lintas fitur
data/                             Data Access Layer: fungsi baca/tulis DB, selalu 'server-only'
db/
  index.ts, schema.ts             koneksi + schema Postgres
  amigo/index.ts, amigo/schema.ts koneksi + schema MariaDB (hasil `drizzle-kit pull`)
lib/
  auth.ts                         config Better Auth (server)
  auth-client.ts                  client Better Auth
  utils.ts                        helper umum (dibuat shadcn)
drizzle/                          file migrasi Postgres (generated, ikut di-commit)
proxy.ts                          pengganti middleware di Next 16; hanya cek ringan (redirect)
  • Nama folder route dan file: kebab-case. Komponen React: PascalCase untuk nama fungsinya.
  • Folder berawalan _ tidak menjadi route; pakai untuk komponen yang dikolokasikan.
  • Route group (nama) hanya untuk mengelompokkan layout, tidak muncul di URL.
  • Import pakai alias @/ (mis. @/db, @/data/barang).

Aturan data dan Server Actions

  • Mutasi (create/update/delete, submit form) wajib lewat Server Action. Tidak membuat route handler app/api/* untuk hal yang bisa dikerjakan Server Action.
  • Membaca data tidak lewat Server Action. Server Action adalah POST dan dijalankan berurutan, jadi tidak cocok untuk fetch. Data dibaca di Server Component dengan memanggil fungsi di data/.
  • Setiap file actions.ts diawali 'use server'. Setiap action:
    1. Cek session dan hak akses di dalam action itu sendiri. Menyembunyikan tombol di UI bukan pengaman, karena action bisa dipanggil langsung lewat POST.
    2. Validasi input (FormData/argumen) dengan zod sebelum menyentuh DB.
    3. Panggil fungsi di data/, bukan query langsung dari action.
    4. Kembalikan objek kecil yang dibutuhkan UI (mis. { ok: true } atau { ok: false, error: string }), bukan baris DB mentah.
    5. Segarkan cache dengan revalidatePath/updateTag sebelum redirect, karena redirect melempar exception dan kode sesudahnya tidak jalan.
  • Form di client memakai useActionState untuk menampilkan error/pending dari action.
  • File di data/ diawali import "server-only" supaya tidak bisa ter-import ke client component. db/ dan lib/auth.ts sengaja tanpa itu karena dibaca CLI auth di luar Next.js (package server-only tidak di-install; Next.js menanganinya sendiri). Hanya data/, db/, dan lib/auth.ts yang membaca process.env untuk secret.
  • proxy.ts hanya untuk redirect cepat berdasarkan ada/tidaknya cookie session. Pemeriksaan session yang sebenarnya tetap di layout/page dan di setiap action.
  • Query selalu lewat Drizzle query builder atau sql template tag (parameterized). Jangan menyusun SQL dengan string concatenation.

Kode lama (old-source/)

Read-only, jangan diedit dan jangan di-import. Dipakai untuk memahami fitur dan aturan bisnis.

  • PHP prosedural + jQuery, akses DB lewat mysqli/mysql_* langsung di tiap halaman. Banyak query disusun dengan string concatenation (rentan SQL injection); jangan tiru polanya.
  • Peta fitur ada di old-source/menu.php: Data Master (pelanggan, karyawan, group/sub group product, rak, supplier, satuan), Barang, Pengadaan, Barcode, Retur Pembelian, Transfer Barang, Revisi, Laporan Persediaan/Beli/Jual, BON, Pembayaran.
  • Helper bisnis di old-source/func_lib.php. Hal yang tidak terlihat dari namanya:
    • Login lama mencocokkan karyawan.username dan karyawan.password (hash MD5), lalu mengisi session useracc, nik, job (id_pekerjaan), namatoko.
    • Jabatan dibaca dari karyawan.id_pekerjaan berupa teks: Pemimpin Toko, Asisten Pemimpin Toko, Petugas Administrasi.
    • Harga pokok ditampilkan dalam kode huruf: convHrgP/DeconvHrgP memetakan angka 1-0 ke B R A W N F O X E S; profit dipetakan convProfit ke D J U N G K A R E T.
    • Format tanggal tampilan dd-mm-yyyy (encTgl), DB yyyy-mm-dd (decTgl).
    • bukaKoneksiPusat() merujuk konstanta *_PUSAT yang tidak didefinisikan di db_login.inc.php; fitur koneksi ke DB pusat kemungkinan sudah mati.
  • File *~ dan (copy) adalah sisa backup editor, abaikan.

Perintah

pnpm dev            jalankan dev server
pnpm build          build production
pnpm lint           eslint
pnpm exec tsc --noEmit   type-check
pnpm db:generate    buat migrasi dari db/schema.ts (Postgres)
pnpm db:migrate     jalankan migrasi ke Postgres
pnpm db:studio      lihat isi Postgres di https://local.drizzle.studio

Postgres lokal: container Docker cleo-postgres (image postgres:17, port 5432).