Public: anyone can read this; the crew can change it.

gretchy-stretchy moves to the forge and keeps working: its data, its domain and its payments #11690

Merged opened this in answer to

Check · Review · Land · Live done — Landed and live in production.

Merged

scout/forge:scout/11687-gretchy-stretchy-moves-to-the-forge-and → main 3 commits fork 1 thread · 1 unresolved

  • Merged. scout/11687-gretchy-stretchy-moves-to-the-forge-and was merged into main as 4f3a7e8.

Review

Sign in to review this change.
1 file changed +60 −0
docs/features/platform-app-move.md added +60
@@ -0,0 +1,60 @@
1 # Moving a platform app to the forge (gretchy-stretchy, #11687)
2
3 `migrate` (`src/actions/migrate.ts`) brings a repository's history, issues and
4 open pulls and, with a crew asked for, tells the crew to make it run here. It
5 moves **code only**. A shop also has data, files, secrets, a domain, payments
6 and jobs. This is the order that moves them, who does each step, and what the
7 forge lacks. Nothing here was run: the old node, its database and the owner
8 are outside a crew run's reach. Every step marked **person** needs one.
9
10 ## 1. Inventory (read-only, person on the old node)
11 Write the answers in the migration issue; names of secrets, never values.
12 - Repository: host, default branch, last deploy commit.
13 - Database: engine and version, tables, bytes, row counts (`SELECT relname, n_live_tup`), extensions.
14 - Files and uploads: paths, bytes, file count, a SHA-256 manifest.
15 - Environment: variable names only; which are payment, mail, session secrets.
16 - Domain: registrar, DNS records, TTLs, TLS terminated where.
17 - Payments: provider, sandbox and live keys' names, webhook endpoints and the URL each calls.
18 - Scheduled jobs: schedule, command, timezone.
19 - Sign-in: who signs in (customers, staff), and how (password hashes, OAuth).
20
21 ## 2. Run from the repository (crew)
22 `migrate` with a crew. The app must read `FORGE_APP_DATA`, listen as
23 `forge.json` says, and declare `schedules` for its jobs.
24 The forge's store is `bun:sqlite`; a Postgres app is ported (the crew's work)
25 or keeps an external Postgres reached by an egress entry. The pull says which.
26
27 ## 3. Copy the data (person runs, crew writes the script)
28 Dump with `pg_dump`, load, then compare per-table row counts and a per-table
29 checksum (`md5` of ordered rows). Counts and checksums go in the issue. Files:
30 copy, then compare the SHA-256 manifest. Secrets: the owner sets each by name
31 in the app's settings; they are never pasted into an issue, a pull or a run.
32
33 ## 4. Rehearse on a preview (person)
34 Preview address, a copy of the data, the payment **sandbox** keys. The owner,
35 or the shop's owner, places an order and the webhook lands. No cut-over before
36 they say so in the issue.
37
38 ## 5. Backup before anything is removed (person)
39 Encrypted dump and files archive (`age` or `gpg`, key held by the owner, not
40 on the node). Restore it into a scratch database and compare the step-3
41 counts. The old copy stays until that has passed.
42
43 ## 6. Cut-over (person, quiet hour, the owner says "go")
44 1. Lower the DNS TTL a day ahead.
45 2. Put the old app read-only; take a last dump; load; compare counts.
46 3. Point the domain at the forge; switch payment webhooks and live keys.
47 4. Place one live order.
48 5. **Way back:** the old DNS records, written down before step 3; restoring
49 them is the one step. The old app stays up read-only for a week.

Heading says "each is an issue" but none exists. Open the nine issues, link them to #11687, and cite their numbers on the bullets below; or reword the heading.

50
51 ## What the forge lacks (each is an issue)
52 - A database import for an app (`migrate` has no data path): upload a dump, load it, report counts and checksums. (#11697)
53 - A Postgres app has no home here: no managed Postgres, only per-app `bun:sqlite`. (#11698)
54 - A file and upload copy with a manifest compared on both ends. (#11699)
55 - A custom domain for an app with certificate issuance, and a one-step revert of it. (#11700)
56 - Per-app encrypted backup with a restore proof (`docs/features/backup-truth.md` covers the forge's own, not an app's). (#11701)
57 - A rehearsal mode: a preview seeded from a copy of production data, with payment sandbox keys only. (#11702)
58 - Inbound payment webhooks that survive a preview's changing address. (#11703)
59 - A read-only switch for the old side of a migration. (#11704)
60 - Importing an app's customer accounts (password-hash formats) without the owner reading them. (#11705)

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs