Run it
Updating and recovering the outbound schema
Migration 0006_signals_outreach.sql preserves all existing outbound columns and states. It expands by renaming the old table and creating the extended schema, migrates every row with the same ID and draft/revision, and contracts by dropping the old table after the copy succeeds. Contact IDs come from the retained draft. Existing message IDs become durable idempotency keys; the stable RFC message ID is derived from the same ID. Approval time uses the original creation time. It does not send or resubmit messages.
Before applying migrations, stop application writes and scheduled processing. Save the current deployed edition commit, .rer/ and the database name it records (sales-orbit-<environment>-db), then create a D1 SQL backup outside the checkout with an account token in CLOUDFLARE_API_TOKEN:
pnpm exec wrangler d1 export sales-orbit-production-db --remote --output /secure-backups/orbit-before-update.sql
Protect the backup like the live database: it contains customer data and authentication state. Keep writes stopped until the migration and application checks pass. Deploy the candidate with rer deploy, which applies its migrations and uploads the matching Worker, and verify customer records, draft bodies, outbound states, provider IDs, audit history, and foreign keys before resuming processing. Do not replay messages to check this update.
If migration or application validation fails, keep processing stopped. Provision a clean D1 database, import the pre-update SQL backup, bind the saved previous Worker to that restored database, and verify the same records and outbound states before resuming. Import into a clean database, not over a partially migrated schema. Locally, rer export --output exports/ before pulling an update and rer reset --yes followed by import --input exports/ give the same recovery for the local installation.
For a remote recovery use the explicit recovery database binding and --remote. Restore the previous deployment’s secret configuration separately; SQL does not restore Worker secrets. Preserve the failed database for diagnosis. Changes accepted after the backup would need explicit reconciliation, which is why writes remain stopped during this procedure. Do not run an older Worker against the newer schema as an improvised rollback.
The standard verification (rer verify) runs tests/ without external inputs. It checks the SHA-256 digests of the original four migrations against Sales commit dbcb9a40ac7df23e8810a229603b3cc81bd735d6, provisions separate temporary databases, and exercises the same sample migration and SQL recovery checks. A test-owned fault immediately before the old outbound table is dropped must fail the migration, roll back its partial table expansion, and leave all four original messages intact. Removing the injected fault then allows the unmodified migration to complete. Both temporary databases are disposed after the test.
For a full application JSON archive recovery, first wait for active source sends and reconciliation to settle, then export through the authenticated API. Deploy a separate environment (rer deploy --environment recovery) so the source remains intact, with only native authentication mail in its environment; keep provider relays, AI, and customer-outreach configuration inactive. Deploy claims a temporary recovery owner; sign in using the actual emailed native link. Restore the archive through Records or rer import --target remote, compare every exported domain table with the source (allowing the one restore audit entry), and sign in again using an active operator restored from the archive. Restore deliberately revokes the temporary recovery session and replaces its setup metadata. Verify this fresh native access before considering activation. Reconfigure source/provider secrets and customer delivery only after a deliberate current review; do not use a recovery test to replay pending customer messages or subscribe a second Worker to production relays.
For authoritative edition updates, identify the actual edition commits and source locks. Preserve the same migration names, contents and recorded owner intent; choose the integration method that verifies those requirements.