ReviewOS

also looking at this

stacks/ts-cloud

fix(fleet): carry the on-box database when a site moves

#178
Merged chrisbbreuer wants to merge feat/site-move-database into main
4 files +295 -0
docs/cli.mdmodified+31-0
Changes to docs/cli.md
@@ -202,6 +202,37 @@ command. Background units are enabled but not started on the target until the
202202source is drained, so the two boxes can never both run a scheduler against one
203203dataset.
204204
205#### The database
206
207A **SQLite** database rides along in the tree: it lives under `shared/`, which is
208the whole point of `sharedPaths`. An **external** database (RDS, a managed host)
209needs nothing either the target reaches the same endpoint the source did.
210
211An **on-box Postgres or MySQL** database is different. It lives in the engine's
212own data directory, which belongs to the box rather than to the site, so the move
213carries it explicitly: dump on the source while background work is stopped, carry
214the file, then create the role and database on the target and load it using the
215same dump, setup, and restore scripts `cloud db:backup`/`db:restore` and
216provisioning use, so a moved database is built exactly like a provisioned one.
217
218The dump is loaded **before** the app starts on the target, so its first request
219finds its data.
220
221Two rules keep this safe:
222
223- If the project has an on-box database and the move has no way to carry it, the
224 move **refuses to run**. Moving the tree alone would pass every check in the
225 plan the app starts, answers its health gate, takes the DNS cutover and
226 then serve production an empty database.
227- If the target already has a database of that name **with tables in it**, the
228 move refuses. Loading a dump over someone else's data is the one genuinely
229 destructive thing this operation could do, so it is a precondition the operator
230 resolves rather than a step behind a confirmation flag.
231
232Like the tree snapshot, the dump is re-taken on a resume rather than skipped: one
233from an earlier attempt predates whatever the source has committed since, and
234shipping stale rows is worse than dumping twice.
235
205236The archive travels through the machine running the command rather than directly
206237between the boxes: a direct hop would need the target to hold a credential for
207238the source, which is the same credential-radius problem consolidation already