Backups and releases
This page points to the key operational SOPs and summarises the release and rollback model.
Operators and Release Managers responsible for deploying or recovering Better Comply.
Release classification
Every change to Better Comply is classified before it ships:
| Class | What it covers | Who approves |
|---|---|---|
| Routine | Internal change, no user-visible behaviour, no schema | Engineering review |
| Standard | User-visible feature or non-regulated bug fix | Engineering review |
| Regulated | Migrations, audit trail, signature flow, RLS policies, certificate emission | Engineering review + Quality Lead written approval |
| Emergency | Production incident remediation | Engineer on call; retrospective review within 48 hours |
The classification is set on the pull request and recorded in the release notes.
Deploy procedure at a glance
Backend (Cloud Run)
gcloud builds submit --config packages/backend/cloudbuild.yamltriggers a build tagged with the commit SHA.- The Release Manager promotes the revision:
gcloud run services update-traffic better-comply-backend --to-revisions <NEW>=100. - Smoke-test the production journey from a fresh browser session: login, assignment, quiz, signature, certificate.
- Watch Cloud Logging and the error rate for 15 minutes.
Web (Netlify)
Netlify builds automatically on every push to main. The Release Manager promotes the build preview to production via the Netlify UI or netlify deploy --prod.
Database migrations
Migrations are applied via supabase db push against the production project, in lexical order. After pushing:
- Run
./scripts/verify-schema.sh "<prod-connection-string>"to confirm every migration landed.supabase db pushcan silently skip out-of-order or duplicate-version files. - Deploy code that tolerates both the old and new schema before deploying code that requires the new schema (backwards-compatible deploys).
Rollback
Rollback triggers: production error rate above 2% for 10 minutes, any compliance-bearing path (signature, audit logs, certificate) failing, or a confirmed regression in a regulated workflow.
| Component | Rollback method |
|---|---|
| Backend | gcloud run services update-traffic better-comply-backend --to-revisions <PREV>=100 - effective in under a minute. This is the only HTTP rollback path; Supabase Edge Functions were retired in May 2026. |
| Web | Redeploy the previous successful Netlify build (one click). |
| Migrations | Run the documented down-migration. If none exists, restore from Supabase PITR (point-in-time recovery). PITR is the last-resort path for data. |
After any rollback that affected signature, certificate, or audit rows, treat the event as a data-integrity incident and follow the data-integrity runbook (docs/quality/data-integrity-incident-runbook.md).
Release notes
Every production release produces a release note at docs/releases/<YYYY-MM-DD>-<slug>.md recording:
- Date, commit SHA, Release Manager, on-call engineer.
- Classification.
- Summary of user-facing changes.
- Regulatory impact (if any).
- Migrations applied.
- Rollback plan.
- Approval signatures (PO and, for regulated changes, Quality Lead).
For regulated releases, this document serves as Part 11 §11.10(a) "validated software" evidence and is retained for 7 years.
CI gates (required before merging)
| Gate | Command |
|---|---|
| Types, lint, i18n parity, migration naming, tests | npm run verify |
pgtap invariants (needs npx supabase start) | npm run test:pgtap |
| Backend coverage thresholds | npm run test:coverage -w @betterknow/better-comply-backend |
Types parity (Supabase schema vs types.ts) | npm run check:types-parity |
The CI pipeline enforces all four gates. types-parity is a required gate with no continue-on-error. The pgtap job also validates that every migration applies cleanly from scratch.
Migration naming rules
Migration files follow the pattern <YYYYMMDDHHMMSS>_<name>.sql. The 14-digit timestamp must be:
- Unique across all files.
- Monotonic with merge order, not the branch authoring date.
npm run lint:migrations fails CI on duplicate or invalid prefixes. A wrong ordering only surfaces at supabase db push or supabase db reset time - the lint catches it early.
Further reading
- Release management SOP:
docs/quality/release-management.md- full RACI, pre-release checklist, deploy steps, rollback triggers. - Data-integrity incident runbook:
docs/quality/data-integrity-incident-runbook.md- response steps for any event affecting regulated rows. - Compliance and audit readiness: Compliance overview - 21 CFR Part 11 and ISO 9001 compliance posture.