Production readiness hardening and ops tooling

This commit is contained in:
2026-05-29 10:10:12 +07:00
parent e0b8f9af9a
commit 648e77cee9
68 changed files with 12222 additions and 848 deletions

View File

@ -0,0 +1,55 @@
# Export Storage Readiness
## Current Mode
Async export result files are written to `EXPORT_STORAGE_DIR`. Metadata remains in Postgres table `export_jobs`.
Required production properties:
- Absolute path, for example `/var/lib/qris/exports`.
- Writable by the app/worker process.
- Included in backup or mounted on durable storage.
- Same mount visible to all app instances that serve `GET /admin/exports/:jobId/download`.
## Single-Node Pilot
Recommended:
```bash
EXPORT_STORAGE_DIR=/var/lib/qris/exports
EXPORT_RETENTION_DAYS=7
```
Filesystem setup example:
```bash
sudo mkdir -p /var/lib/qris/exports
sudo chown <app-user>:<app-group> /var/lib/qris/exports
sudo chmod 750 /var/lib/qris/exports
```
## Multi-Node Production
Do not use node-local disk unless traffic is sticky to the same node that processed the export job.
Preferred options:
- Shared filesystem mounted at the same `EXPORT_STORAGE_DIR` on every app node.
- S3-compatible object storage adapter in a future implementation.
Until object storage exists, run one export worker/app instance or ensure all download-serving instances share the export directory.
## Retention
Worker clears downloadable file references after `EXPORT_RETENTION_DAYS`. If a finance user needs an expired file, create a new export job.
## Validation
```bash
npm run deploy:check-env
POST /admin/exports/settlement-adjustments
GET /admin/exports/:jobId
GET /admin/exports/:jobId/download
```
Check `/admin/observability/summary` for worker state and export job counts.