# Cleo Minimarket Back-office minimarket berbasis Next.js 16, pengganti aplikasi PHP lama di `old-source/`. Stack: Next.js 16 (App Router), React 19, TypeScript, Tailwind CSS 4, shadcn/ui, Drizzle ORM, Better Auth, Postgres (data aplikasi dan login), MariaDB `cleo` (data bisnis lama). ## Setup di laptop baru ### Yang perlu terpasang - [Node.js](https://nodejs.org) 24 atau lebih baru - [pnpm](https://pnpm.io/installation) 11 (`npm install -g pnpm`) - [Docker Desktop](https://www.docker.com/products/docker-desktop/), dalam keadaan menyala - Git ### Langkah 1. **Clone repo dan install dependency** ```bash git clone https://git.amigogroup.id/deardo/nextjs-cleo-minimarket.git cd nextjs-cleo-minimarket pnpm install ``` 2. **Buat `.env` dari contoh** ```bash cp .env.example .env ``` Lalu isi nilainya: | Variabel | Isi | | --------------------- | --------------------------------------------------------------------- | | `POSTGRES_PASSWORD` | Password bebas untuk Postgres lokal. | | `DATABASE_URL` | Ganti `` dengan password yang sama seperti di atas. | | `MARIADB_ROOT_PASSWORD` | Password bebas untuk `root` MariaDB lokal. Jangan pakai password server asli. | | `AMIGO_DATABASE_URL` | Ganti `` dengan password bebas; user ini dibuat di langkah 6. | | `BETTER_AUTH_SECRET` | String acak, buat dengan perintah di bawah. | | `SEED_ADMIN_PASSWORD` | Password akun admin pertama (minimal 8 karakter). | ```bash node -e "console.log(require('crypto').randomBytes(32).toString('base64'))" ``` Buat `BETTER_AUTH_SECRET` baru di setiap laptop dan server, jangan disalin dari tempat lain. Password di `AMIGO_DATABASE_URL` jangan mengandung `@ : / # ? %`, atau tulis dalam bentuk URL-encoded (mis. `@` menjadi `%40`). 3. **Nyalakan Postgres dan MariaDB** ```bash docker compose up -d ``` Container `cleo-postgres` dan `cleo-mariadb` akan muncul di Docker Desktop. Data tersimpan di volume `cleo-pgdata` dan `cleo-mariadb-data`, jadi tidak hilang walaupun container dimatikan atau dibuat ulang. 4. **Buat tabel** ```bash pnpm db:migrate ``` 5. **Buat akun admin pertama** ```bash pnpm db:seed ``` Username dan password diambil dari `SEED_ADMIN_*` di `.env`. Aman dijalankan berulang kali: kalau akun sudah ada, seed dilewati. 6. **Isi MariaDB lokal dengan salinan data `cleo`** Aplikasi tidak pernah terhubung ke server asli (`192.168.3.3`) saat development. Data bisnis disalin sekali ke MariaDB di Docker, lalu semua CRUD dicoba di salinan itu. Langkah ini butuh jaringan kantor dan password `root` server `192.168.3.3` (minta ke admin), hanya untuk membaca. Perintah di bawah untuk PowerShell. Jalankan blok per blok. Kalau menyalin dari file mentah (bukan tampilan README di Git), buang spasi di awal baris: penutup `'@` di blok c dan d harus berada di kolom pertama. a. Dump dari server kantor ke file di dalam container (diminta password `root` server kantor; ~260 MB, beberapa menit, jangan biarkan laptop sleep): ```powershell docker exec -it cleo-mariadb sh -c 'mysqldump -h 192.168.3.3 -u root -p --single-transaction --triggers cleo > /tmp/cleo.sql' docker exec cleo-mariadb sh -c 'tail -n 1 /tmp/cleo.sql' ``` Baris terakhir harus `-- Dump completed on ...`. Jangan tambahkan `--routines`: tabel sistem `mysql.proc` di server kantor rusak sejak upgrade dari 10.1 dan membuat dump berhenti di akhir, padahal database `cleo` tidak punya stored procedure. b. Import ke MariaDB lokal (tanpa output kalau berhasil): ```powershell docker exec cleo-mariadb sh -c 'mysql -uroot -p$MARIADB_ROOT_PASSWORD cleo < /tmp/cleo.sql' ``` c. Buat user aplikasi `cleo_next`. Ganti `` dengan password yang sama seperti di `AMIGO_DATABASE_URL`: ```powershell $sql = @' CREATE USER IF NOT EXISTS 'cleo_next'@'%' IDENTIFIED BY ''; GRANT LOCK TABLES ON cleo.* TO 'cleo_next'@'%'; '@ $sql | docker exec -i cleo-mariadb sh -c 'mysql -uroot -p$MARIADB_ROOT_PASSWORD' ``` d. Beri `cleo_next` hak baca/tulis data (tanpa hak mengubah struktur tabel) hanya di tabel bisnis. Tabel milik aplikasi lain di database yang sama (Laravel, Prisma, Better Auth lama) sengaja tidak diberi akses: ```powershell $gen = @' SELECT CONCAT('GRANT SELECT, INSERT, UPDATE, DELETE ON cleo.`', table_name, '` TO ''cleo_next''@''%'';') FROM information_schema.tables WHERE table_schema = 'cleo' AND table_name NOT IN ( 'users', 'sessions', 'jobs', 'failed_jobs', 'job_batches', 'migrations', 'cache', 'cache_locks', 'password_reset_tokens', 'akuns', 'user', 'account', 'session', 'verification', '_prisma_migrations' ); '@ $gen | docker exec -i cleo-mariadb sh -c 'mysql -uroot -p$MARIADB_ROOT_PASSWORD -N' | docker exec -i cleo-mariadb sh -c 'mysql -uroot -p$MARIADB_ROOT_PASSWORD' ``` e. Cek. Login sebagai `cleo_next`: ```powershell docker exec -it cleo-mariadb mysql -ucleo_next -p cleo ``` Lalu jalankan `SELECT COUNT(*) FROM pelanggan;` (harus ada angkanya) dan `SELECT COUNT(*) FROM users;` (harus `SELECT command denied`). Keluar dengan `exit`. Langkah c sampai e aman diulang. `db/amigo/schema.ts` sudah ada di repo, jadi `pnpm db:amigo:pull` tidak perlu dijalankan di laptop baru. 7. **Jalankan aplikasi** ```bash pnpm dev ``` Buka http://localhost:3000. Untuk mengecek koneksi auth, buka http://localhost:3000/api/auth/get-session, hasilnya `null` kalau belum login. ### Catatan - Server MariaDB kantor (`192.168.3.3`) masih dipakai aplikasi PHP di toko. Saat development hanya dibaca sekali untuk dump (langkah 6a); `AMIGO_DATABASE_URL` selalu menunjuk ke `localhost:3307`. Fitur login tidak membutuhkan MariaDB. - Mengembalikan salinan lokal ke kondisi awal (mis. setelah data uji berantakan): ulangi langkah 6a dan 6b. Untuk mulai dari nol, hapus dulu container dan volume-nya (`docker compose rm -sf mariadb`, lalu `docker volume rm cleo-minimarket_cleo-mariadb-data`, lalu `docker compose up -d mariadb`), kemudian ulangi langkah 6a sampai 6e. Jangan pakai `docker compose down -v`: perintah itu juga menghapus data Postgres. - `MARIADB_ROOT_PASSWORD` hanya dibaca saat volume MariaDB masih kosong. Mengubahnya di `.env` setelah itu tidak berpengaruh, kecuali volume dihapus seperti di atas. - Di PowerShell 5.1 jangan kirim query lewat `mysql -e "..."`: tanda kutip ganda dibuang oleh PowerShell. Kirim lewat pipe: `'SELECT 1' | docker exec -i cleo-mariadb sh -c 'mysql -uroot -p$MARIADB_ROOT_PASSWORD -N cleo'`. - Pendaftaran akun lewat web sengaja ditutup (`disableSignUp` di `lib/auth.ts`). Akun pertama dibuat lewat `pnpm db:seed`. - Kalau port 5432 sudah dipakai Postgres lain di laptop itu, matikan dulu Postgres tersebut, atau ganti port kiri di `docker-compose.yml` (mis. `"5433:5432"`) beserta port di `DATABASE_URL`. MariaDB lokal sengaja di port 3307 supaya tidak bentrok dengan XAMPP/MySQL di 3306. ## Perintah | Perintah | Fungsi | | ---------------------- | -------------------------------------------------------- | | `pnpm dev` | Dev server di http://localhost:3000 | | `pnpm build` | Build production | | `pnpm lint` | ESLint | | `pnpm exec tsc --noEmit` | Type-check | | `docker compose up -d` | Nyalakan Postgres dan MariaDB lokal | | `pnpm db:generate` | Buat file migrasi dari `db/schema.ts` | | `pnpm db:migrate` | Jalankan migrasi ke Postgres | | `pnpm db:seed` | Buat akun admin pertama | | `pnpm db:studio` | Lihat isi Postgres di https://local.drizzle.studio | | `pnpm db:amigo:pull` | Baca ulang struktur MariaDB ke `db/amigo/schema.ts` (hanya kalau struktur tabel berubah) |