- db-backup sidecar: pg_dump -Fc of procurement+casdoor every
BACKUP_INTERVAL_SECONDS into BACKUP_DIR, retention via BACKUP_KEEP_DAYS
- audit_log table (migration.sql + runtime ensure_audit_table) with
model + transactional helper (utils/audit.record) — wired into user
create/role-change and inventory transaction creation
- get_actor: quote_events.actor now stores the VERIFIED user's display
name instead of the raw bearer token
- remove the separate casdoor-postgres container; casdoor uses the main
postgres (db casdoor, created by sql/02-casdoor-db.sql on fresh volumes);
data migrated via pg_dump/pg_restore (backups kept outside the repo)
- Traefik v3.6 as the public edge (ports 80/443): docker provider pinned to
the dedicated traefik_network (fixed-name network), host rules for
app/api/auth/s3/storage (env-overridable, localhost defaults), frontend
nginx demoted to internal SPA server; docker-compose.prod.yml adds real
domains + Let's Encrypt + HTTP→HTTPS redirect (redirect middleware in
infra/traefik-dynamic.yml)
- v3.6 required (Traefik <=3.3 fails against Docker Engine 29.x); socket
mounted rw (Docker Desktop rejects :ro)
- start.ps1: app URL now http://localhost, casdoor + db notes