feat(ops): erp-sandbox iso-prod seed + documents sync tooling (ADR-0003 E2) #15
Reference in New Issue
Block a user
Delete Branch "claude/e2-sandbox-lifecycle"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Productionizes the
erp-sandboxstate-lifecycle mechanisms from ADR-0003, validated live against the running sandbox. Addsops/sandbox/sandbox-lifecycle.sh+ README.refresh-from-prod— read-onlypg_dumpof proderp→DROP OWNED BY erp_sandbox_role CASCADE→pg_restoreintoerp-sandbox, with the sandbox's own membership creds (noDROP/CREATE DATABASE, noCREATEDB, no superuser). Dumps the fullpublicschema (so app helper functions + triggers likeupdate_modified_column_tms()come over) and filters the provisioner-owned pgbounceruser_lookupfrom the restore TOC. Scales the pod to 0 for exclusive access; prod creds are copied into a transient secret deleted on exit.sync-documents— tar-pipesdocuments/mycompany(company logo + uploads) prod → sandbox, since files live on the PVC not the DB.Proven live
I ran both against
erp-sandbox: it now carries prod's 295llx_*tables, real data (societe/facture rows), company config (Arcodange,fr_FR, theme),MAIN_MODULE_API=1, all owned byerp_sandbox_role; the login renders identically to prod and the company logo returns HTTP 200. Prod was read-only throughout (default_transaction_read_only=on), and the restore credential is structurally unable to touch proderp(owns onlyerp-sandbox).Caveats documented (ADR-0003)
Encryption (API keys are instance-uuid-bound →
ai_agent_sandboxkey must be generated in-sandbox) and the PVC/file fidelity (logo image needssync-documents). README also lists the hardening backlog: a dedicated read-only dump role + a golden-cache PVC for fast BDD resets.🤖 Generated with Claude Code
Productionizes the sandbox state-lifecycle mechanisms validated live against erp-sandbox. `ops/sandbox/sandbox-lifecycle.sh`: - refresh-from-prod: read-only pg_dump of prod erp (default_transaction_read_only) -> DROP OWNED BY erp_sandbox_role CASCADE -> pg_restore into erp-sandbox, using the sandbox's own membership creds (no DROP/CREATE DATABASE, no CREATEDB, no superuser). Dumps the full public schema (so app helper functions + triggers come over) and filters the provisioner-owned pgbouncer user_lookup function from the restore TOC. Scales the pod to 0 for exclusive access; copies prod creds into a transient secret that is deleted on exit. - sync-documents: tar-pipe the documents/mycompany tree (company logo + uploads) prod -> sandbox, since uploaded files live on the PVC, not the DB. Prod integrity is structural: prod is read-only during dump; the restore can only write erp-sandbox (erp_sandbox_role owns only the sandbox DB and cannot drop prod erp/erp_role); the platform's only prod-capable superuser stays behind the human-gated postgres.yaml CI and is never used here. README documents the integrity guarantee, the encryption + PVC fidelity caveats, the BDD reset loop, and the hardening backlog (dedicated read-only dump role, golden-cache PVC). Refs ADR-0003 (factory#19). Chart owner-role fix = erp#13. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>