# Codex Handoff - 2026-05-23

Dokumen ini adalah snapshot terbaru setelah penambahan halaman profile user, perapihan dashboard, penyiapan deploy Alpine Linux tanpa compile di server, release artifact `amd64` untuk Alpine `x86_64`, export master data lokal ke SQL, dan pemisahan alur purchase submit dari finalisasi penerimaan/lot.

## Status Umum

- App aktif dikembangkan di `Next.js + Prisma + PostgreSQL`.
- Branch aktif:
  `main`
- Repo remote utama:
  `https://git.iptek.co/wirabasalamah/AbelBirdNest-Stock.git`
- Local workspace:
  `/Users/wirabasalamah/Documents/Codex/abelbirdnest-web`
- Server deploy terbaru yang sedang dibahas:
  Alpine Linux `x86_64`, RAM `1 GB`, tanpa compile di server.

## Ringkasan Perubahan Terbaru

### 0. Alur Purchase, Penerimaan, Lot, dan Realisasi Dipisah

- Alur lama:
  - klik `Ajukan` di purchase langsung membuat `receipts`, `receipt_lines`, `inventory_lots`, allocation, dan ledger realisasi.
  - efek sampingnya, purchase yang sudah diajukan tidak aman diedit karena `receipt_lines.purchase_line_id` masih mengarah ke `purchase_lines` lama.
- Alur baru:
  - `Purchase` dibuat/edit dulu seperti biasa.
  - Klik `Ajukan` hanya mengubah status purchase menjadi `SUBMITTED`.
  - Menu `Penerimaan` dipakai untuk membuat `receipt` dan `receipt_lines` dari purchase yang sudah `SUBMITTED`.
  - Tombol `Buat lot` di detail receipt yang membuat:
    - `inventory_lots`
    - `lot_purchase_allocations`
    - `purchase_realization_entries`
    - `purchase_realization_summaries`
  - Receipt ikut berubah menjadi `FINALIZED`.
- Purchase masih bisa diedit selama belum punya `receipt` atau `lot`.
- Jika purchase sudah punya `receipt` atau `lot`, endpoint update purchase sekarang menolak dengan pesan domain yang jelas, bukan error Prisma foreign key mentah.
- Menu `Penerimaan` sekarang tampil di sidebar pada grup `Pembelian`.
- Akses `Penerimaan` dibuka untuk:
  - `ADMIN`
  - `SYSTEM_ADMIN`
  - `OWNER`
  - `PURCHASING`
  - `WAREHOUSE`
- Label dan copy halaman `Penerimaan` sudah dirapikan agar mengikuti dictionary dua bahasa `ID/EN`, termasuk label tabel, tombol `Buat lot`/`Generate lots`, detail receipt, dan teks kosong lot.
- Commit terkait:
  - `44146a4 Split purchase submit from receipt finalization`
  - `57896d3 Add receipt menu access`
  - `1217529 Complete receipt translations`
- File utama:
  - [src/app/api/v1/purchases/[id]/route.ts](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/src/app/api/v1/purchases/[id]/route.ts)
  - [src/app/api/v1/purchases/[id]/submit/route.ts](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/src/app/api/v1/purchases/[id]/submit/route.ts)
  - [src/app/api/v1/receipts/route.ts](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/src/app/api/v1/receipts/route.ts)
  - [src/app/api/v1/receipts/[id]/generate-lots/route.ts](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/src/app/api/v1/receipts/[id]/generate-lots/route.ts)
  - [src/features/receipts/components/receipts-client.tsx](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/src/features/receipts/components/receipts-client.tsx)
  - [src/features/purchases/components/purchases-client.tsx](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/src/features/purchases/components/purchases-client.tsx)
  - [src/config/navigation.ts](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/src/config/navigation.ts)
  - [src/config/access-control.ts](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/src/config/access-control.ts)
  - [src/lib/i18n.ts](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/src/lib/i18n.ts)
  - [src/types/purchase.ts](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/src/types/purchase.ts)

### 1. Halaman Profile User

- Area nama/avatar di topbar sekarang menjadi link ke `/profile`.
- Halaman profile baru memungkinkan user update:
  - `name`
  - `email`
  - `phone`
- `username` sengaja dibuat read-only, tampil sebagai informasi akun tapi tidak bisa diedit.
- Halaman profile juga menampilkan:
  - role
  - status akun
  - status verifikasi email
  - `user id`
  - waktu `created_at`
  - waktu `updated_at`
- Setelah profile diupdate, session cookie ikut di-refresh agar nama di topbar langsung sinkron tanpa logout-login ulang.
- File utama:
  - [src/app/profile/page.tsx](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/src/app/profile/page.tsx)
  - [src/features/auth/components/profile-client.tsx](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/src/features/auth/components/profile-client.tsx)
  - [src/app/api/v1/auth/profile/route.ts](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/src/app/api/v1/auth/profile/route.ts)
  - [src/components/layout/topbar.tsx](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/src/components/layout/topbar.tsx)
  - [src/config/access-control.ts](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/src/config/access-control.ts)
  - [src/lib/i18n.ts](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/src/lib/i18n.ts)

### 2. Dashboard Spacing Fix

- Dashboard sebelumnya punya section yang saling menempel vertikal.
- Perbaikan dilakukan dengan wrapper `space-y-6` dan sedikit memperbesar gap pada grid metric.
- Tujuannya murni visual: card-card lebih lega dan border panel tidak menumpuk.
- File utama:
  - [src/app/dashboard/page.tsx](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/src/app/dashboard/page.tsx)

### 3. Deploy Alpine Linux Kosong

- Sudah disiapkan panduan deploy khusus untuk server Alpine Linux kosong dengan RAM kecil.
- Asumsi utama:
  - server `x86_64`
  - tidak ada build di server
  - release diupload sebagai artifact siap jalan
  - service manager memakai `OpenRC`
- Dokumen baru:
  - [docs/deploy-alpine-empty-server.md](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/docs/deploy-alpine-empty-server.md)
- Service OpenRC baru:
  - [deploy/openrc/abelbirdnest-web](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/deploy/openrc/abelbirdnest-web)
- Service ini me-load `.env` sebelum menjalankan `node server.js`.

### 4. Workflow Build Artifact Alpine

- Ditambahkan script build artifact khusus Alpine:
  - [deploy/scripts/build-alpine-release.sh](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/deploy/scripts/build-alpine-release.sh)
- Script ini:
  - build di Docker `node:22-alpine`
  - copy output `standalone`
  - memasukkan `.next/static`, `public`, `prisma`, `deploy`, dan doc deploy
  - tidak membawa `.env` production nyata
- Script sekarang mendukung:
  - `DOCKER_PLATFORM=linux/amd64`
- Ini penting karena server target adalah Alpine `x86_64`.

### 5. Prisma Binary Targets untuk Alpine

- Error deploy sempat muncul:
  - Prisma client di artifact lama terbentuk untuk `linux-musl-arm64-openssl-3.0.x`
  - server nyata butuh `linux-musl-openssl-3.0.x`
- `binaryTargets` Prisma sekarang mencakup:
  - `native`
  - `darwin-arm64`
  - `debian-openssl-3.0.x`
  - `linux-musl-openssl-3.0.x`
  - `linux-musl-arm64-openssl-3.0.x`
- File utama:
  - [prisma/schema.prisma](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/prisma/schema.prisma)

### 6. User Production Awal `SYSTEM_ADMIN`

- Sudah disiapkan SQL khusus untuk membuat user awal production:
  - email: `wirabasalamah@gmail.com`
  - username: `wirabasalamah`
  - role: `SYSTEM_ADMIN`
  - password: `P@ssw0rd`
- File:
  - [deploy/sql/seed-system-admin-wirabasalamah.sql](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/deploy/sql/seed-system-admin-wirabasalamah.sql)
- Di server, user ini sudah diverifikasi ada, `ACTIVE`, dan `email_verified_at` terisi.

### 7. Master Data Lokal Dibawa ke Server via SQL

- Diputuskan tidak perlu build ulang hanya untuk membawa bank, currency, dan grade.
- Data master lokal sudah diexport ke file SQL:
  - [deploy/sql/master-seed-from-local-20260522.sql](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/deploy/sql/master-seed-from-local-20260522.sql)
- Isi dump saat dibuat:
  - `147` bank
  - `48` currency
  - `348` grade
  - `0` grade buy price standards
  - `0` grade sell price standards
- Tabel yang dibawa:
  - `banks`
  - `currencies`
  - `grades`
  - `grade_buy_price_standards`
  - `grade_sell_price_standards`

## Artifact Release Penting

- Artifact Linux historis:
  - `abelbirdnest-release.tar.gz`
  - `abelbirdnest-release-20260521-0841.tar.gz`
- Artifact Alpine musl awal:
  - `abelbirdnest-release-alpine-20260522-0508.tar.gz`
  Catatan:
  ini masih belum aman untuk server `x86_64` karena mismatch Prisma engine.
- Artifact Alpine final yang benar untuk server `x86_64`:
  - `abelbirdnest-release-alpine-amd64-20260522-0635.tar.gz`
- File ini yang harus dipakai untuk deploy Alpine `x86_64`.

## Temuan Deploy Server Alpine

### 1. Port Runtime

- Di lapangan, app berjalan di `3000`, bukan `3007`.
- Redirect root `/` ke `/login` lalu setelah login aktif, `/login` akan redirect ke `/dashboard`.
- Jadi jika `curl https://abelbirdnest.id/` menghasilkan payload redirect ke dashboard/login, itu berarti app sebenarnya hidup.

### 2. Perilaku `/login`

- `/login` memang otomatis redirect ke `/dashboard` kalau cookie session valid.
- File:
  - [middleware.ts](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/middleware.ts)
  - [src/app/login/page.tsx](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/src/app/login/page.tsx)

### 3. Certbot di Alpine

- Untuk Alpine, pendekatan yang dipakai:
  - `apk add certbot certbot-nginx`
- Jika repo `community` belum aktif, perlu ditambahkan dulu di `/etc/apk/repositories`.

## Verifikasi yang Sudah Dilakukan

- `npm run typecheck` lolos setelah patch profile dan dashboard.
- `npm run typecheck -- --pretty false` lolos setelah patch purchase/receipt/menu/translasi.
- `npm run build` lokal Mac lolos.
- Build artifact Alpine `amd64` melalui Docker emulasi berhasil dibuat.
- Artifact `amd64` diverifikasi mengandung Prisma engine:
  - `libquery_engine-linux-musl-openssl-3.0.x.so.node`
- File SQL master data berhasil dibuat dari DB lokal.
- User `wirabasalamah@gmail.com` di server sudah dicek via SQL dan memang ada.

## Risiko / Catatan Penting

- Jangan menghapus `purchase_lines` dari purchase yang sudah punya `receipt_lines`; gunakan flow baru lewat menu `Penerimaan` atau koreksi stok/reversal jika barang sudah masuk.
- Untuk membersihkan satu purchase test beserta lot/receipt terkait, gunakan SQL transaksi terkontrol dan biarkan proses rollback jika lot sudah dipakai transaksi lain.
- `psql` tidak menerima query param Prisma `?schema=public`; untuk akses manual gunakan URL DB tanpa query param itu, atau `options=-csearch_path%3Dpublic`.
- Jangan pakai artifact Alpine non-`amd64` di server `x86_64`.
- Jangan pakai artifact lama yang hanya punya engine `linux-musl-arm64`.
- Untuk import master data:
  - paling aman di database fresh
  - kalau tabel sudah terisi, bisa bentrok `id` atau `unique key`
- Build Alpine di Mac via emulasi `amd64` sangat lambat, jadi hindari rebuild jika cukup dengan upload SQL.
- Build Next standalone masih mengeluarkan warning Prisma saat static generation jika DB lokal di builder tidak hidup; warning ini tidak menggagalkan artifact.

## File yang Perlu Diperhatikan Pada Turn Berikutnya

- [src/app/api/v1/purchases/[id]/submit/route.ts](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/src/app/api/v1/purchases/[id]/submit/route.ts)
- [src/app/api/v1/receipts/[id]/generate-lots/route.ts](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/src/app/api/v1/receipts/[id]/generate-lots/route.ts)
- [src/features/receipts/components/receipts-client.tsx](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/src/features/receipts/components/receipts-client.tsx)
- [src/config/navigation.ts](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/src/config/navigation.ts)
- [src/config/access-control.ts](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/src/config/access-control.ts)
- [prisma/schema.prisma](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/prisma/schema.prisma)
- [src/app/api/v1/auth/profile/route.ts](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/src/app/api/v1/auth/profile/route.ts)
- [src/features/auth/components/profile-client.tsx](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/src/features/auth/components/profile-client.tsx)
- [src/app/dashboard/page.tsx](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/src/app/dashboard/page.tsx)
- [deploy/scripts/build-alpine-release.sh](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/deploy/scripts/build-alpine-release.sh)
- [deploy/openrc/abelbirdnest-web](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/deploy/openrc/abelbirdnest-web)
- [deploy/sql/master-seed-from-local-20260522.sql](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/deploy/sql/master-seed-from-local-20260522.sql)
- [deploy/sql/seed-system-admin-wirabasalamah.sql](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/deploy/sql/seed-system-admin-wirabasalamah.sql)
- [docs/deploy-alpine-empty-server.md](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/docs/deploy-alpine-empty-server.md)

## Langkah Lanjutan Paling Masuk Akal

1. Untuk server dev, update dari Git dan rebuild:
   - `git pull origin main`
   - `npm install --include=dev`
   - `npx prisma generate`
   - `npm run build`
   - restart service dev.
2. Verifikasi flow baru:
   - buat/edit purchase
   - klik `Ajukan`
   - buka `Pembelian -> Penerimaan`
   - buat receipt
   - klik `Buat lot`
   - cek lot dan realisasi terbentuk.
3. Jika server Alpine belum diupdate, upload:
   - `abelbirdnest-release-alpine-amd64-20260522-0635.tar.gz`
   - `master-seed-from-local-20260522.sql`
   - `seed-system-admin-wirabasalamah.sql`
4. Import master data lokal jika database fresh.
5. Verifikasi login `SYSTEM_ADMIN`.
6. Verifikasi halaman `/profile`:
   - `name`, `email`, `phone` editable
   - `username` readonly
7. Verifikasi dashboard spacing.
8. Kalau perlu artifact baru lagi, pakai script Alpine dengan `DOCKER_PLATFORM=linux/amd64`.

## Catatan Penutup

- Handoff sebelumnya:
  - [docs/codex-handoff-2026-05-19.md](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/docs/codex-handoff-2026-05-19.md)
  - [docs/codex-handoff-2026-05-21.md](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/docs/codex-handoff-2026-05-21.md)
- Handoff `2026-05-23` ini adalah konteks terbaru dan seharusnya dipakai sebagai acuan utama lanjutan.
