# 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 ### 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.