Skip to main content

Database reset and reinstall

Choose the procedure by environment. Local validation state is disposable and has its own lifecycle command. The Cloud Spanner scripts accept any project, instance, and database, so they are operator tools and must never be used as a convenient local-test fix.

Local validation reset

To stop the integrated local stack and remove its generated state under .dev-logs/local-validation:

./scripts/local-validation.sh reset
./scripts/local-validation.sh up

This boundary is local emulators, local containers, and generated validation state. It does not authorize or perform a staging or production reset. Rerun ./scripts/local-validation.sh seed when only the deterministic local seed needs refreshing.

Cloud Spanner rebuild boundary

The rest of this page performs a full Cloud Spanner PostgreSQL-dialect schema rebuild. It is appropriate only for an explicitly approved disposable or rebuildable database.

Destructive operation. Do not use this procedure on production. Do not use it on staging without an approved reset window, named owner, backup/recovery decision, exact target identifiers, and downstream re-seed plan. A dry run is review evidence, not permission to apply it.

Prerequisites:

  • authenticated gcloud access to the exact target;
  • jq, base64, Python 3, mktemp, and uuidgen as required by the scripts;
  • an approved target project, instance, and database recorded outside shell history;
  • confirmation that no migration workflow is already operating on the database.

Set identifiers deliberately; do not copy production values from another runbook:

export TARGET_PROJECT='<approved-non-production-project>'
export TARGET_INSTANCE='<approved-spanner-instance>'
export TARGET_DATABASE='<approved-database>'

Every script prints the active Google Cloud account and target. Stop if either is unexpected.

1. Review the drop plan

drop-all-spanner-tables.sh discovers tables from current database DDL and emits reverse-order DROP TABLE statements. Without --apply it does not submit DDL:

infra/scripts/drop-all-spanner-tables.sh \
--project "$TARGET_PROJECT" \
--instance "$TARGET_INSTANCE" \
--database "$TARGET_DATABASE"

Review the account, target, complete table list, and generated DDL. Preserve the output in the approved change evidence.

2. Drop discovered tables

Only the authorized operator may repeat the reviewed command with --apply:

infra/scripts/drop-all-spanner-tables.sh \
--project "$TARGET_PROJECT" \
--instance "$TARGET_INSTANCE" \
--database "$TARGET_DATABASE" \
--apply

The script generates a random confirmation phrase and aborts unless it is typed exactly. That prompt is the final accident guard, not the approval mechanism. The command submits real DDL and destroys all discovered table data.

3. Review schema generation

The canonical schema input is the SQLDelight tree at apps/specifications/schema/src/main/sqldelight/com/myriad/schema. apply-init-sql.sh uses tools/sqldelight/spanner_ddl.py to extract CREATE TABLE and CREATE INDEX statements, order tables by foreign-key dependencies, and print the generated DDL:

infra/scripts/apply-init-sql.sh \
--project "$TARGET_PROJECT" \
--instance "$TARGET_INSTANCE" \
--database "$TARGET_DATABASE"

The default is dry-run. Review the source directory, statement counts, ordering report, target, and generated DDL before continuing.

4. Install the schema

The apply script has no interactive confirmation. --apply immediately submits the generated DDL, so recheck all identifiers first:

infra/scripts/apply-init-sql.sh \
--project "$TARGET_PROJECT" \
--instance "$TARGET_INSTANCE" \
--database "$TARGET_DATABASE" \
--apply

This is a clean initialization path, not an incremental migration. Do not run it over a populated schema and do not substitute it for the controlled Azure PostgreSQL revision workflows.

5. Bootstrap the first support superuser only when needed

bootstrap-first-superuser.sh writes immediately; it has no dry-run or --apply gate. It is only for initial platform bootstrap after the schema exists and management-api has seeded the mgmt_super_admin management-IAM role:

infra/scripts/bootstrap-first-superuser.sh \
--project "$TARGET_PROJECT" \
--instance "$TARGET_INSTANCE" \
--database "$TARGET_DATABASE" \
--email '<approved-support-email>' \
--first-name '<first-name>' \
--last-name '<last-name>' \
--firebase-id '<firebase-uid>'

The script refuses to add a new address when support_users already has rows unless --allow-existing is supplied. Do not use that override without a separate review of the existing users and intended identity. The current bootstrap role is admin, with a mgmt_super_admin assignment in mgmt_iam_*; merchant IAM is separate.

6. Verify the rebuilt environment

Verification is environment-specific and must remain non-destructive:

  1. confirm the schema operation completed and expected tables exist;
  2. start the relevant services through the approved environment lane;
  3. run their health and authentication smoke checks;
  4. verify the intended seed/bootstrap identity only;
  5. record target identifiers, workflow or command output, and rollback/recovery disposition.

Do not send receipts, activate terminals, move payment value, apply another migration, or deploy unrelated services as part of database verification.