mirror of
https://github.com/Such-Software/wownerogue.git
synced 2026-10-23 00:58:33 +02:00
80 lines
4.0 KiB
Markdown
80 lines
4.0 KiB
Markdown
# Disposable clone migration gate
|
|
|
|
`npm run db:migrate:clone` applies the release's normal ordered migrations to an existing,
|
|
disposable PostgreSQL clone. It is the migration step for a restored production dump before an
|
|
immutable release is eligible for activation. It never creates, restores, drops, audits, or
|
|
activates a database.
|
|
|
|
## Hard target contract
|
|
|
|
The runner refuses to open a connection unless all of these conditions hold:
|
|
|
|
- `DB_HOST` is explicit loopback (`127.0.0.1`, `::1`, or `localhost`) or the standard local Unix
|
|
socket directory `/run/postgresql` or `/var/run/postgresql`;
|
|
- `DB_NAME` starts with `monerogue_`, `wownerogue_`, or `wowngeon_` and contains a complete
|
|
underscore-delimited `clone`, `restore`, or `canary` token;
|
|
- the name contains no live marker beginning with `prd`, `prod`, `production`, `live`, `mainnet`,
|
|
`master`, `primary`, `current`, or `active`;
|
|
- `CLONE_MIGRATION_EXPECT_DATABASE` exactly equals `DB_NAME`;
|
|
- `CLONE_MIGRATION_CONFIRM` exactly equals `MIGRATE_DISPOSABLE_CLONE:<DB_NAME>`;
|
|
- `DB_PORT` and `DB_USER` are explicit, `DATABASE_URL` is absent, and the process receives no
|
|
command-line arguments.
|
|
|
|
After connecting, the runner checks PostgreSQL's `current_database()` before any DDL. It then calls
|
|
the same `DatabaseManager.runMigrations()` used by application startup: lexical filename order,
|
|
the `schema_migrations` ledger, and one transaction per newly applied file. Finally, it requires the
|
|
ledger to equal the complete repository migration manifest, in order, with no missing or extra
|
|
entry. The manifest is discovered from the candidate release and must be contiguous from 001; the
|
|
current floor is migration 043. A successful current release reports:
|
|
|
|
```text
|
|
clone_migration_status=ok
|
|
database=monerogue_restore_20260721t220048z_28d513b29b36
|
|
migration_count=43
|
|
latest_migration=043_durable_solo_restart_snapshots.sql
|
|
```
|
|
|
|
## Invocation
|
|
|
|
Create and restore the clone with the reviewed backup procedure first. Keep the target variables in
|
|
a protected operator-owned environment file and database credentials in a mode-0600 `PGPASSFILE`;
|
|
do not type a password, connection URL, or target as a command argument. For example, the inherited
|
|
non-secret target environment is:
|
|
|
|
```dotenv
|
|
DB_HOST=127.0.0.1
|
|
DB_PORT=5432
|
|
DB_NAME=monerogue_restore_20260721t220048z_28d513b29b36
|
|
DB_USER=monerogue
|
|
PGPASSFILE=/run/wowngeon/clone-migration.pgpass
|
|
CLONE_MIGRATION_EXPECT_DATABASE=monerogue_restore_20260721t220048z_28d513b29b36
|
|
CLONE_MIGRATION_CONFIRM=MIGRATE_DISPOSABLE_CLONE:monerogue_restore_20260721t220048z_28d513b29b36
|
|
```
|
|
|
|
Database names use lowercase letters, digits, and underscores only. Normalize a release ID into a
|
|
separate safe tag rather than copying a hyphenated artifact ID into `DB_NAME`.
|
|
|
|
Load that protected environment through the reviewed service/wrapper, change into the extracted
|
|
candidate's `src` directory, and run only:
|
|
|
|
```bash
|
|
npm run db:migrate:clone
|
|
```
|
|
|
|
Do not append `--` arguments. The runner never logs host, role, password, connection URL, or
|
|
`PGPASSFILE` contents. `DB_PASSWORD` is supported only for an already-protected inherited service
|
|
environment and is kept in memory; `PGPASSFILE` is preferred.
|
|
|
|
## Required follow-on gates and limits
|
|
|
|
Run `scripts/deploy/financial-audit.sql` and the restored-data constraint validation gate against
|
|
the same clone after migration. Compare the result with the pre-migration audit, then test the
|
|
candidate and predecessor against the migrated clone as required by the fleet runbook.
|
|
|
|
This runner does not prove that a database with a disposable-looking name is operationally
|
|
disposable, does not prevent another application process from connecting, and does not acquire an
|
|
activation-wide drain lock. The operator must create the clone from the intended fresh dump, keep
|
|
it outside public service configuration, and destroy it separately after the release decision. A
|
|
successful result authorizes only the next audit/test gate; it does not authorize a symlink switch,
|
|
wallet action, payout, or traffic restoration.
|