# Codex Handoff - 2026-05-21 Dokumen ini menyimpan konteks kerja terbaru setelah rangkaian patch mobile, login publik, global search, locking satuan, dan workflow deploy artifact Linux. ## Status Umum - App aktif dikembangkan di `Next.js + Prisma + PostgreSQL`. - Branch aktif: `main` - Repo remote utama: `https://git.iptek.co/wirabasalamah/AbelBirdNest-Stock.git` - Server target production saat ini: `/var/www/abelbirdnest-web/AbelBirdNest-Stock` ## Ringkasan Perubahan Terbaru ### 0. Update Pembelian, Penerimaan, Label Lot, dan Navigasi - 2026-05-29 - Branch `main` sudah sinkron dengan `origin/main`. - Commit terakhir saat handoff ini diperbarui: `4c5b62d Prefer specific active navigation links` - Commit terkait patch terbaru: - `44146a4` `Split purchase submit from receipt finalization` - `57896d3` `Add receipt menu access` - `1217529` `Complete receipt translations` - `d0bdd4b` `Refine purchase receipt and lot label flow` - `2df1752` `Render receipt lot labels with QR and barcode` - `3a52d29` `Keep receipt action labels on one line` - `4c5b62d` `Prefer specific active navigation links` #### Pembelian Reguler - Halaman `Pembelian Reguler` tidak lagi meminta input `Gudang` dan `Lokasi`. - Tombol submit lama yang langsung membuat receipt/lot sudah tidak dipakai dari halaman pembelian. - Pembelian sekarang disimpan sebagai draft/data purchase, lalu proses penerimaan dilakukan dari menu: `Pembelian > Penerimaan`. - Payload purchase tetap kompatibel dengan API lama, tetapi `warehouse_id` dan `warehouse_location_id` dikirim kosong/null. - File utama: - [src/features/purchases/components/purchases-client.tsx](/home/wira/work/codex/AbelBirdNest-Stock/src/features/purchases/components/purchases-client.tsx) #### Penerimaan dan Generate Lot - Menu `Pembelian > Penerimaan` menjadi tempat utama untuk: - memilih pembelian yang belum punya receipt - mengisi qty diterima/valid/ditolak - memilih gudang dan lokasi - membuat receipt - generate lot dari receipt - API receipt mencegah receipt/lot dobel untuk pembelian yang sama. - Saat `Buat lot`, status purchase ikut menjadi `SUBMITTED`. - Generate lot dari receipt mempertahankan logic realization/allocation terbaru: - membuat `inventory_lots` - membuat `lot_purchase_allocations` - membuat `purchase_realization_entries` - recalculation summary realization - Kode lot dari satu receipt dibuat berurutan dalam satu transaksi agar tidak bentrok untuk receipt multi-line. - File utama: - [src/features/receipts/components/receipts-client.tsx](/home/wira/work/codex/AbelBirdNest-Stock/src/features/receipts/components/receipts-client.tsx) - [src/app/api/v1/receipts/route.ts](/home/wira/work/codex/AbelBirdNest-Stock/src/app/api/v1/receipts/route.ts) - [src/app/api/v1/receipts/[id]/generate-lots/route.ts](/home/wira/work/codex/AbelBirdNest-Stock/src/app/api/v1/receipts/[id]/generate-lots/route.ts) - [src/features/receipts/lib/serialize-receipt.ts](/home/wira/work/codex/AbelBirdNest-Stock/src/features/receipts/lib/serialize-receipt.ts) - [src/types/receipt.ts](/home/wira/work/codex/AbelBirdNest-Stock/src/types/receipt.ts) #### Cetak Receipt dan Label Lot dari Penerimaan - Daftar/detail penerimaan sekarang punya tombol: - `Receipt` / `Cetak receipt` - `Label lot` / `Cetak label lot` - Cetak label lot dari penerimaan sudah memakai QR code dan barcode sungguhan, dengan library yang sama seperti halaman detail lot: - `qrcode` - `jsbarcode` - Tombol aksi daftar penerimaan dipaksa satu baris agar label `Label lot` tidak wrap. - Label lot dari receipt mengambil nilai scan dari: - `qr_code_value` - `barcode_value` - fallback ke `lot_code` #### Navigasi Aktif - Sidebar dan mobile nav sebelumnya bisa menandai `Pembelian Reguler` aktif saat user berada di: `/purchases/office-buyout` - Active state sekarang memilih href paling spesifik/paling panjang ketika beberapa route cocok. - File utama: - [src/components/layout/sidebar.tsx](/home/wira/work/codex/AbelBirdNest-Stock/src/components/layout/sidebar.tsx) - [src/components/layout/mobile-nav.tsx](/home/wira/work/codex/AbelBirdNest-Stock/src/components/layout/mobile-nav.tsx) #### Script Seed Lokal - File `scripts/seed-local-superadmin.mjs` sudah ikut masuk git sesuai kebutuhan dev/test. - Script ini membuat role dan user `SYSTEM_ADMIN` lokal. - Catatan keamanan: script berisi password hardcoded `password`, jadi pakai hanya untuk environment lokal/dev, bukan production. #### Verifikasi Patch Terbaru - `npx tsc --noEmit` lolos setelah patch: - split pembelian/penerimaan - cetak receipt - cetak label lot QR/barcode - active navigation fix #### Update Server Dev - Untuk server dev boleh compile langsung di server via npm. - Command umum: ```bash cd /path/ke/AbelBirdNest-Stock git pull origin main npm ci npm run prisma:generate npm run build sudo rc-service abelbirdnest-web restart sudo rc-service abelbirdnest-web status curl -I http://127.0.0.1:3007/login ``` - Jika server dev memakai systemd: ```bash sudo systemctl restart abelbirdnest-web sudo systemctl status abelbirdnest-web --no-pager ``` - Tidak ada migration Prisma baru dari patch ini. ### 1. Flow Mobile Purchase - Menu `Receipt` di mobile sudah dikeluarkan dari bootstrap mobile. - Submit purchase sekarang langsung: - membuat `receipt` - membuat `receipt_lines` - membuat `lot` - membuat alokasi realization terkait - Endpoint utama: - [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/mobile/bootstrap/route.ts](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/src/app/api/v1/mobile/bootstrap/route.ts) - Dokumen mobile sudah disesuaikan: - [docs/mobile-api-blueprint.md](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/docs/mobile-api-blueprint.md) ### 2. Formatting Qty dan Currency - Formatting `kg` sekarang locale-aware. - Angka hasil konversi gram ke kilogram tampil dengan format Indonesia yang benar, misalnya `10,5 kg`. - Currency di beberapa modul tidak lagi hardcoded dan mengikuti `currency_code` sistem. - File sentral: - [src/lib/formatters.ts](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/src/lib/formatters.ts) ### 3. Dashboard Qty Fix - Dashboard sebelumnya salah menampilkan angka seperti `94.290 kg` untuk data gram yang seharusnya dibaca sebagai `94,29 kg`. - Perbaikan dilakukan dengan konversi qty berbasis `unit.code` sebelum agregasi. - File utama: - [src/lib/dashboard.ts](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/src/lib/dashboard.ts) ### 4. Login Publik, Contact Admin, dan Halaman Legal - Login sekarang punya link publik yang benar-benar aktif: - `Hubungi Admin` - `Bantuan` - `Kebijakan Privasi` - `Syarat & Ketentuan` - `Hubungi Admin` sekarang menuju halaman publik dengan form kirim email. - Form ini memakai: - CAPTCHA aritmatika server-side - honeypot anti-spam - Halaman publik legal/help tersedia tanpa login: - `/contact-admin` - `/help-public` - `/privacy-policy` - `/terms-and-conditions` - Semua halaman publik ini sudah dua bahasa `ID/EN`. - Email admin tidak lagi ditampilkan langsung di halaman publik; user diarahkan memakai form kontak admin. - File utama: - [src/features/auth/components/login-client.tsx](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/src/features/auth/components/login-client.tsx) - [src/features/auth/components/contact-admin-client.tsx](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/src/features/auth/components/contact-admin-client.tsx) - [src/app/api/v1/public/contact-admin/route.ts](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/src/app/api/v1/public/contact-admin/route.ts) - [src/lib/public-captcha.ts](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/src/lib/public-captcha.ts) - [middleware.ts](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/middleware.ts) ### 5. Global Search Header - Search di topbar sebelumnya hanya placeholder. - Sekarang search desktop: - full width sampai mendekati switch bahasa - real-time - menampilkan dropdown hasil - bisa klik hasil - bisa Enter untuk fallback ke halaman lot - Search lintas: - `lot` - `purchase` - supplier/agent terkait - Endpoint baru: - [src/app/api/v1/global-search/route.ts](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/src/app/api/v1/global-search/route.ts) - Komponen utama: - [src/components/layout/topbar-search.tsx](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/src/components/layout/topbar-search.tsx) - [src/components/layout/topbar.tsx](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/src/components/layout/topbar.tsx) - Halaman lot sudah membaca query URL `?search=` agar fallback search juga benar-benar terpakai. ### 6. Master Satuan Dikunci - Master `Satuan` sekarang dibuat fixed dan tidak lagi editable. - Hanya dua satuan yang diizinkan: - `gr` - `kg` - `GET /api/v1/units` akan memastikan dua unit itu selalu ada. - `POST`, `PUT`, dan `DELETE` unit sekarang ditolak `403`. - Submenu `Satuan` disembunyikan dari sidebar. - Kalau halaman `/units` dibuka langsung, tampilannya read-only. - File utama: - [src/features/units/lib/fixed-units.ts](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/src/features/units/lib/fixed-units.ts) - [src/app/api/v1/units/route.ts](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/src/app/api/v1/units/route.ts) - [src/app/api/v1/units/[id]/route.ts](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/src/app/api/v1/units/[id]/route.ts) - [src/components/master-data/units-client.tsx](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/src/components/master-data/units-client.tsx) - [src/config/navigation.ts](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/src/config/navigation.ts) ## Prisma dan Build Cross-Platform - Local Mac sempat rusak karena build Linux menimpa hasil `prisma generate`. - Generator Prisma sekarang mencakup: - `native` - `darwin-arm64` - `debian-openssl-3.0.x` - `linux-musl-openssl-3.0.x` - File: - [prisma/schema.prisma](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/prisma/schema.prisma) ## Workflow Deploy Artifact Linux - Build di server sempat berat dan tidak stabil. - Sekarang ada workflow artifact standalone Linux. - Script: - [deploy/scripts/build-linux-release.sh](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/deploy/scripts/build-linux-release.sh) - Karakteristik workflow ini: - build di Docker Alpine Linux agar cocok dengan server Alpine - install `openssl` di container - pakai `NODE_OPTIONS=--max-old-space-size=4096` - copy source ke `/work` agar tidak menimpa `node_modules` lokal Mac - artifact final memakai timestamp: `abelbirdnest-release-YYYYMMDD-HHMMSS.tar.gz` - Artifact final tidak membawa `.env.production` lokal. ### Catatan Tambahan 2026-05-26 - Server production memakai Alpine Linux dengan RAM sekitar 1 GB. - Jangan compile/build di server. - Artifact harus dibuat dari container Alpine, default script sekarang memakai `node:20-alpine`. - Runtime server Alpine perlu `nodejs` dan `openssl`. - Ukuran artifact runtime-only yang normal sekitar `43 MB`. - Jika artifact membengkak sekitar `120 MB+`, kemungkinan Prisma CLI atau `node_modules` lengkap ikut terbawa. Jangan pakai varian besar itu untuk server 1 GB kecuali memang sengaja. - Artifact runtime-only tidak dipakai untuk menjalankan `prisma migrate deploy` di server. Untuk update UI/app tanpa perubahan schema DB, cukup extract release baru lalu restart service. - Jika nanti ada migration database, jalankan migration dari mesin build/admin yang punya dependency lengkap dan akses DB production, bukan dari server kecil. ## Catatan Deploy Server Saat Ini - Path app aktif di server production saat ini: `/opt/abelbirdnest-web` - Struktur release yang dipakai sekarang diasumsikan: - upload artifact ke root app server: `/opt/abelbirdnest-web` - extract ke `releases/` - symlink `current` diarahkan ke release aktif - Folder aktif runtime: `/opt/abelbirdnest-web/current` - Service server memakai OpenRC, bukan systemd. - Service OpenRC production yang ditemukan: - `directory="/opt/abelbirdnest-web/current"` - `command="/usr/bin/node"` - `command_args="/opt/abelbirdnest-web/current/server.js"` - env yang dicek service: `/opt/abelbirdnest-web/current/.env` - Karena service mencari `.env` di folder `current`, setiap release baru perlu copy `.env` dari release/current lama ke folder release baru sebelum `current` diarahkan ke release baru. - Jangan gunakan path lama `/var/www/abelbirdnest-web/AbelBirdNest-Stock` untuk server ini kecuali service production memang sudah diubah. ### Command Manual Deploy Yang Dipakai Di lokal: ```bash scp abelbirdnest-release-YYYYMMDD-HHMMSS.tar.gz abelbirdnest@SERVER_IP:/opt/abelbirdnest-web/ ``` Di server: ```bash cd /opt/abelbirdnest-web RELEASE_NAME=YYYYMMDD-HHMMSS mkdir -p /opt/abelbirdnest-web/releases/$RELEASE_NAME tar -xzf /opt/abelbirdnest-web/abelbirdnest-release-$RELEASE_NAME.tar.gz -C /opt/abelbirdnest-web/releases/$RELEASE_NAME cp /opt/abelbirdnest-web/current/.env /opt/abelbirdnest-web/releases/$RELEASE_NAME/.env mv /opt/abelbirdnest-web/current /opt/abelbirdnest-web/current-backup-$(date +%Y%m%d-%H%M%S) 2>/dev/null || true ln -sfn /opt/abelbirdnest-web/releases/$RELEASE_NAME /opt/abelbirdnest-web/current sudo chown -R abelbirdnest:abelbirdnest /opt/abelbirdnest-web sudo rc-service abelbirdnest-web restart sudo rc-service abelbirdnest-web status curl -I http://127.0.0.1:3007/login ``` Jika `ln -sfn ... current` gagal dengan pesan `File exists`, berarti `current` masih folder biasa. Backup/rename folder itu dulu, lalu ulangi `ln -sfn`. ## Verifikasi yang Sudah Dilakukan - `npx tsc --noEmit` lolos setelah patch terbaru. - Global search endpoint mengembalikan hasil yang benar untuk sample data lokal. - `GET /api/v1/units` sekarang hanya mengembalikan `gr` dan `kg`. - `POST /api/v1/units` sekarang ditolak dengan pesan lock master. ## Risiko / Catatan yang Masih Relevan - Build standalone lokal tetap menampilkan warning Prisma saat static generation jika DB lokal tidak aktif; warning ini tidak menggagalkan artifact. - Production deploy sekarang punya dua mode historis: - mode lama `repo root + npm run start` - mode baru `artifact standalone + node server.js` Jangan campur keduanya pada instruksi deploy. - Beberapa endpoint `mobile/receipts/**` masih ada untuk kompatibilitas lama, walaupun flow mobile baru tidak lagi menampilkan menu receipt. ## Langkah Lanjutan Paling Masuk Akal 1. Deploy artifact terbaru ke server production. 2. Verifikasi: - search header aktif - halaman publik login aktif - `Satuan` tidak muncul di menu - `GET /api/v1/units` hanya `gr` dan `kg` 3. Jika perlu, lanjut bersihkan endpoint legacy yang sudah tidak dipakai lagi, terutama sekitar receipt mobile lama. ## Catatan Penutup - Handoff sebelumnya: - [docs/codex-handoff-2026-05-19.md](/Users/wirabasalamah/Documents/Codex/abelbirdnest-web/docs/codex-handoff-2026-05-19.md) - Handoff `2026-05-21` ini adalah snapshot terbaru dan seharusnya dipakai sebagai konteks utama lanjutan.