252 lines
12 KiB
Markdown
252 lines
12 KiB
Markdown
# 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`.
|