Repository navigation
Release Migrations and Seeding
Canonical source:
docs/08-runtime-devops/release-migrations-and-seeding.md— this page is rendered from it on every publish; edit the source.
How schema and data changes reach production without corrupting it.
| Path | When | Guard |
|---|---|---|
| Container start | every service boot |
_prisma_migrations ledger + PostgreSQL advisory lock |
| One-shot release job | before a deploy rolls | the same guards, run once, ahead of the fleet |
Both are safe. The release job exists because running migrations before any replica starts means a rolling deploy never has two schema versions live at the same moment, and a failed migration aborts the release rather than half-starting the fleet.
npm run migrate:all # prisma migrate deploy for all 14 database-owning services
npm run seed:versioned # versioned data seeders, exactly once each
npm run release:prepare # both, in orderThe service list is derived from which apps ship a prisma/schema.prisma,
so a newly added service cannot be forgotten here.
Every seeder is keyed (name, version) in a seed_executions table with a
checksum. Two independent guards, because either alone is insufficient:
- A PostgreSQL advisory lock serialises concurrent starters. Without it two replicas booting together both read "not yet seeded" and both insert.
-
The
seed_executionsrow makes the second run a no-op. The lock only orders the racers; this is what stops re-execution.
A completed seeder never runs again. That is what makes it safe to leave seeding in the startup path — restarting a production replica cannot re-seed over administrator-edited rows.
A changed seed requires a NEW version. Editing a completed seeder and hoping it re-runs is the exact failure mode this design prevents; the checksum turns that mistake into a loud warning instead of silent drift.
The plan-catalog seeder compares each existing row against the pre-billing system-seed fingerprint:
- still matching → safely upgraded to the new baseline
- edited by an administrator → left exactly as set, with only genuinely new columns backfilled, and the preservation reported in the logs
Pre-billing manual plan assignments become MIGRATION grants. They are not
converted into paid subscriptions — fabricating a payment that never happened
would corrupt every revenue report downstream.
Proven against real PostgreSQL 16 rather than asserted:
| Property | Result |
|---|---|
| First run applies the catalog | 7 plans, 13 price versions, 49 feature rules |
| Second run | skipped (already-completed) |
| Two concurrent runs | both skipped, no duplicate rows |
| Second ACTIVE price for one plan+interval | rejected by the database unique index |
Administrator-edited pro
|
quota and description preserved verbatim |
Untouched free
|
upgraded to the new baseline |
migrate deploy twice |
second run reports no pending migrations |
- Back up databases.
- Build immutable images.
-
npm run migrate:all— abort the release if it fails. -
npm run seed:versioned. - Deploy the payment service; verify
/healthreports each gateway'sconfiguredboolean. - Deploy auth and routing.
- Deploy frontend and nginx.
- Enable gateways in sandbox; run smoke tests.
- Enable production gateways only after merchant approval and a verified webhook round-trip.
- Watch reconciliation and margin dashboards.
Distinguish the cases — they have different answers:
| Situation | Action |
|---|---|
| Bad application build | roll the image back; schema stays forward |
| Bad migration | forward-only repair, never a destructive down-migration |
| Gateway misbehaving | disable that gateway's credentials; the other keeps serving |
| Entitlement drift | re-run reconciliation; the inbox is idempotent |
Financial records are never destructively rolled back. Payment tables are append-oriented; corrections are compensating transactions, not rewrites. A refund is a new row, not an edited one — otherwise the ledger stops matching the money that actually moved.
ClawAI Wiki · source-controlled under wiki/ · generated/mirrored from the current repository knowledge layer.
ClawAI Wiki
Product
- Product-Vision
- Flagship-Features
- Business-Overview
- Requirements-Register
- Drift-Log
- Runtime-Managed-Connector-Providers
- Threads
- ADR-Index
Architecture
- System-at-a-Glance
- Architecture-Map
- System-Architecture
- Message-Flow
- End-to-End-Data-Flow
- Routing-Engine
- Event-Bus
- Security-Architecture
Platform
- Backend-Services
- Frontend-Architecture
- Shared-Packages
- Database-Reference
- API-Reference
- Provider-Catalog
- Memory-and-Context-Architecture
- File-Support-Architecture
- Research-and-Web-Crawling
Runtime & Ops
- Docker-Guide
- Nginx-Reference
- CI-CD-Pipeline
- Logging-and-Observability
- Operational-Runbooks
- Troubleshooting
Quality
Engineering OS
- AI-Native-Engineering-OS
- Generated-Manifests
- Rules-Catalog
- Skills-Catalog
- Context-Layer
- Engineering-Memory
- Tooling-and-Automation
- Scripts-and-Operations
- ESLint-and-Architecture-Enforcement
- Extended-Work-Skills
Agents
Reference