# Codex Handoff - QRIS Soundbox Platform Tanggal update: 2026-05-29, Asia/Jakarta. Dokumen ini adalah snapshot kerja terakhir untuk melanjutkan project tanpa perlu membaca ulang seluruh chat. ## Status Terakhir - Estimasi MVP / early pilot: 92-94%. - Estimasi production-ready penuh: 82-85%. - Platform sudah bukan prototype docs-only. Backend, UI operasional, migration, smoke test, rate limiting, audit logging, async export, runbook, dan script deployment sudah tersedia. - Fokus terakhir yang selesai: rate limiting + security polish, login audit, admin audit UI real-data, placeholder nav cleanup, dan runbook/checklist produksi. - Worktree kemungkinan masih dirty karena banyak perubahan aktif. Jangan revert perubahan yang tidak eksplisit diminta. ## Verifikasi Terakhir - `npm run typecheck`: pass. - `npm run db:migrate`: pass dan idempotent sampai migration `003_export_job_storage.sql`. - `npm audit --json`: pass, 0 vulnerability. - `npm run ui:qa`: pass setelah cleanup placeholder navigation. - `npm run smoke:e2e`: pass setelah rate limiting dan login audit. - Quick rate limit test: pass. Login admin salah pertama menghasilkan `401` dengan `RateLimit-Remaining: 0`, request berikutnya menghasilkan `429 RATE_LIMITED`. - Quick login audit test: pass. Event `admin.login.success`, `admin.login.failed`, `merchant.login.success`, dan `merchant.login.failed` tercatat. - Quick audit UI API test: pass. `GET /admin/audit-logs?action_contains=.login.&limit=10` mengembalikan event login. - Production-like env check dummy: pass via `npm run deploy:check-env`, hanya warning opsional untuk `MQTT_SUBSCRIBE`. - Staging/load/MQTT real sebelumnya sudah pernah diverifikasi: load level 2 1610 requests 0 errors, MQTT broker `mqtts://mqtt.iptek.co:8883` publish/subscribe OK. ## Implementasi Selesai ### 1. Auth, RBAC, dan Security - Admin session login tersedia lewat `/admin/login`, `/admin/logout`, `/admin/me`. - Merchant session login tersedia lewat `/merchant/login`, `/merchant/logout`, `/merchant/me`. - Legacy dev auth bisa dimatikan via env dan production check memblokir konfigurasi yang tidak aman. - Admin dan merchant bootstrap script tersedia: - `scripts/create-admin-user.mjs` - `scripts/create-merchant-user.mjs` - Password policy bootstrap diperketat: - minimal 14 karakter; - wajib lowercase, uppercase, angka, dan simbol; - menolak kata mudah ditebak seperti product/default/password/admin/merchant/qris/soundbox. - Rate limiting middleware baru: - [src/shared/middleware/rateLimit.ts](/home/wira/work/codex/qris-soundbox-platform/src/shared/middleware/rateLimit.ts) - dipasang ke `/admin/login`, `/merchant/login`, admin write routes, `/device`, dan `/integrations`. - Env security baru: - `TRUST_PROXY` - `JSON_BODY_LIMIT` - `RATE_LIMIT_ENABLED` - `RATE_LIMIT_AUTH_WINDOW_MS` - `RATE_LIMIT_AUTH_MAX` - `RATE_LIMIT_ADMIN_WRITE_WINDOW_MS` - `RATE_LIMIT_ADMIN_WRITE_MAX` - `RATE_LIMIT_WRITE_WINDOW_MS` - `RATE_LIMIT_WRITE_MAX` - Error code baru `RATE_LIMITED` di [src/shared/errors/index.ts](/home/wira/work/codex/qris-soundbox-platform/src/shared/errors/index.ts). ### 2. Audit, Monitoring, dan Logging - Audit logging login admin: - `admin.login.success` - `admin.login.failed` - Audit logging login merchant: - `merchant.login.success` - `merchant.login.failed` - `auditLogStore` mendukung `actor_type: merchant`. - Filter audit baru `action_contains` tersedia di: - [src/shared/store/auditLogStore.ts](/home/wira/work/codex/qris-soundbox-platform/src/shared/store/auditLogStore.ts) - [src/routes/admin.ts](/home/wira/work/codex/qris-soundbox-platform/src/routes/admin.ts) - Admin audit UI sudah memakai real API, bukan mock: - [ui/admin-system-audit-logs/index.html](/home/wira/work/codex/qris-soundbox-platform/ui/admin-system-audit-logs/index.html) - Audit UI memiliki filter action/entity/date/search, preset login events, KPI count, dan drawer JSON detail. - Observability/health sebelumnya sudah tersedia: - `/health` - `/health/ready` - `/admin/observability/summary` - `/admin/observability/dead-letter-replays` - `/admin/observability/mqtt-status` ### 3. MQTT dan Device Operations - MQTT worker dan policy production sudah diperketat. - Wildcard subscribe default production dicegah oleh env check. - MQTT ACL tooling tersedia: - `scripts/check-mqtt-acl.mjs` - `scripts/smoke-mqtt-acl.mjs` - `scripts/provision-mqtt-device.mjs` - Package scripts: - `npm run mqtt:provision-device` - `npm run mqtt:check-acl` - `npm run smoke:mqtt-acl` - `npm run smoke:mqtt-real` - Real MQTT smoke pernah pass dengan broker `mqtts://mqtt.iptek.co:8883`. ### 4. Settlement, Reconciliation, dan Finance Ops - Settlement batch, merchant settlement history, reconciliation management, adjustment approval, dan device technical detail UI sudah tersedia. - Admin reconciliation UI sudah menggunakan async export flow dan export history. - Key UI pages: - [ui/admin-reconciliation-management/index.html](/home/wira/work/codex/qris-soundbox-platform/ui/admin-reconciliation-management/index.html) - [ui/settlement-batch-management/index.html](/home/wira/work/codex/qris-soundbox-platform/ui/settlement-batch-management/index.html) - [ui/merchant-settlement-history/index.html](/home/wira/work/codex/qris-soundbox-platform/ui/merchant-settlement-history/index.html) - [ui/device-technical-detail/index.html](/home/wira/work/codex/qris-soundbox-platform/ui/device-technical-detail/index.html) - Placeholder `href="#"` sudah dibersihkan dari UI yang masuk QA. ### 5. Async Export dan Storage - Async export job sudah tersedia untuk settlement adjustment export. - Export job worker: - [src/shared/services/exportJobWorker.ts](/home/wira/work/codex/qris-soundbox-platform/src/shared/services/exportJobWorker.ts) - Export job store: - [src/shared/store/exportJobStore.ts](/home/wira/work/codex/qris-soundbox-platform/src/shared/store/exportJobStore.ts) - Migration: - [migrations/002_export_jobs.sql](/home/wira/work/codex/qris-soundbox-platform/migrations/002_export_jobs.sql) - [migrations/003_export_job_storage.sql](/home/wira/work/codex/qris-soundbox-platform/migrations/003_export_job_storage.sql) - Export file storage memakai `EXPORT_STORAGE_DIR`, dengan metadata path/size/expiry. - Export retention cleanup tersedia via worker. - Admin endpoints: - `POST /admin/exports/settlement-adjustments` - `GET /admin/exports` - `GET /admin/exports/:jobId` - `GET /admin/exports/:jobId/download` ### 6. Deployment, Backup, Restore, dan Runbook - Production env checker diperketat: - [scripts/check-production-env.mjs](/home/wira/work/codex/qris-soundbox-platform/scripts/check-production-env.mjs) - Backup/restore tooling: - [scripts/backup-production.mjs](/home/wira/work/codex/qris-soundbox-platform/scripts/backup-production.mjs) - [scripts/restore-plan.mjs](/home/wira/work/codex/qris-soundbox-platform/scripts/restore-plan.mjs) - [scripts/restore-drill-validate.mjs](/home/wira/work/codex/qris-soundbox-platform/scripts/restore-drill-validate.mjs) - Load testing/report tooling: - [scripts/load-test.mjs](/home/wira/work/codex/qris-soundbox-platform/scripts/load-test.mjs) - [scripts/run-staging-load-report.mjs](/home/wira/work/codex/qris-soundbox-platform/scripts/run-staging-load-report.mjs) - Operational docs baru: - [OPERATIONAL_RUNBOOK.md](/home/wira/work/codex/qris-soundbox-platform/OPERATIONAL_RUNBOOK.md) - [PILOT_EXECUTION_CHECKLIST.md](/home/wira/work/codex/qris-soundbox-platform/PILOT_EXECUTION_CHECKLIST.md) - [EXPORT_STORAGE_READINESS.md](/home/wira/work/codex/qris-soundbox-platform/EXPORT_STORAGE_READINESS.md) - README dan deployment readiness docs sudah direferensikan ke runbook/checklist tersebut. ## Endpoint Penting - Health: - `GET /health` - `GET /health/ready` - Admin auth/session: - `POST /admin/login` - `POST /admin/logout` - `GET /admin/me` - Admin audit/observability: - `GET /admin/audit-logs` - `GET /admin/observability/summary` - `GET /admin/observability/dead-letter-replays` - `GET /admin/observability/mqtt-status` - Admin export: - `POST /admin/exports/settlement-adjustments` - `GET /admin/exports` - `GET /admin/exports/:jobId` - `GET /admin/exports/:jobId/download` - Merchant auth/session: - `POST /merchant/login` - `POST /merchant/logout` - `GET /merchant/me` - Device and integration routes remain rate-limited for write-heavy paths: - `/device` - `/integrations` ## Package Scripts Penting - `npm run typecheck` - `npm run db:migrate` - `npm run smoke:e2e` - `npm run ui:qa` - `npm run deploy:check-env` - `npm run load:test` - `npm run load:test:staging` - `npm run backup:production` - `npm run restore:plan` - `npm run restore:validate` - `npm run admin:create-user` - `npm run merchant:create-user` - `npm run mqtt:provision-device` - `npm run mqtt:check-acl` - `npm run smoke:mqtt-acl` - `npm run smoke:mqtt-real` ## File Kunci yang Sering Disentuh - App bootstrap: [src/app.ts](/home/wira/work/codex/qris-soundbox-platform/src/app.ts) - Env config: [src/config/env.ts](/home/wira/work/codex/qris-soundbox-platform/src/config/env.ts) - Admin routes: [src/routes/admin.ts](/home/wira/work/codex/qris-soundbox-platform/src/routes/admin.ts) - Merchant routes: [src/routes/merchant.ts](/home/wira/work/codex/qris-soundbox-platform/src/routes/merchant.ts) - Audit store: [src/shared/store/auditLogStore.ts](/home/wira/work/codex/qris-soundbox-platform/src/shared/store/auditLogStore.ts) - Export worker: [src/shared/services/exportJobWorker.ts](/home/wira/work/codex/qris-soundbox-platform/src/shared/services/exportJobWorker.ts) - Export store: [src/shared/store/exportJobStore.ts](/home/wira/work/codex/qris-soundbox-platform/src/shared/store/exportJobStore.ts) - Rate limit middleware: [src/shared/middleware/rateLimit.ts](/home/wira/work/codex/qris-soundbox-platform/src/shared/middleware/rateLimit.ts) - UI QA script: [scripts/ui-qa-check.mjs](/home/wira/work/codex/qris-soundbox-platform/scripts/ui-qa-check.mjs) - Admin audit UI: [ui/admin-system-audit-logs/index.html](/home/wira/work/codex/qris-soundbox-platform/ui/admin-system-audit-logs/index.html) - Env sample: [.env.example](/home/wira/work/codex/qris-soundbox-platform/.env.example) ## Decision Log Ringkas - D-026 sampai D-049: dasar auth, merchant/admin flows, migration, UI awal, dan smoke testing. - D-050 sampai D-059: production hardening awal, MQTT policy, finance/reconciliation UI, settlement flows. - D-060 sampai D-069: merchant auth productionization, DB migration idempotent, monitoring/logging, load test, async export. - D-070 sampai D-074: export storage/history, MQTT ACL, backup/restore, staging load report. - D-075 sampai D-080: rate limiting/security polish, login audit, audit UI real data, UI QA cleanup, runbook/checklist produksi. Rujukan utama: [DECISIONS_LOG.md](/home/wira/work/codex/qris-soundbox-platform/DECISIONS_LOG.md). ## Sisa Gap Utama 1. Eksekusi staging nyata dari checklist: - deploy dengan env final; - jalankan `deploy:check-env`, migration, smoke, UI QA, load report; - simpan artefak hasil staging. 2. Pilot real device: - provisioning device real; - validasi MQTT ACL per device; - transaksi QRIS test end-to-end; - validasi soundbox delivery dan dead-letter handling. 3. Restore drill nyata: - backup production/staging; - restore ke database disposable; - jalankan `restore:validate`; - dokumentasikan RTO/RPO aktual. 4. Export storage production topology: - pastikan `EXPORT_STORAGE_DIR` durable, absolute, writable, dan di-backup; - jika multi-node, perlu shared filesystem/object storage strategy. 5. Manual visual QA: - buka halaman admin utama di browser; - cek layout mobile/desktop; - cek login/session expiry state; - cek empty/error/loading state. 6. Operational readiness: - isi PIC, escalation contact, broker credential, backup location, dan pilot merchant list di runbook/checklist. ## Prioritas Lanjutan Disarankan 1. Jalankan full staging rehearsal dari `PILOT_EXECUTION_CHECKLIST.md`. 2. Lakukan manual visual QA admin UI dengan browser. 3. Jalankan restore drill sungguhan pada database disposable. 4. Finalisasi export storage production strategy. 5. Siapkan pilot real merchant/device dan rekam hasilnya di runbook. ## Catatan Penting - Jangan hidupkan legacy auth di production. - Jangan gunakan wildcard MQTT subscribe di production kecuali sedang maintenance terkontrol. - `EXPORT_STORAGE_DIR` harus absolute path dan durable untuk production. - Rate limiting sekarang aktif secara default jika `RATE_LIMIT_ENABLED=true`; hati-hati saat smoke test berulang pada login endpoint. - `CODEX_HANDOFF.md` ini adalah snapshot operasional terbaru; untuk detail historis keputusan, baca `DECISIONS_LOG.md`.