mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-15 15:02:04 +00:00
refactor(backup): run the restore as ordered steps from per-domain modules
restoreBackup becomes an orchestrator: the checks before the first delete move to restore-preflight.ts, and the transaction runs the steps listed in backup-domains.ts in dependency order, emptying the account first and then rebuilding it domain by domain. The inline restores for measurements, medications, mood, labs, illness, allergies, family history, workouts, nutrient days, documents, the instance settings and the cleared notification channels move into one module per domain, beside the existing section modules. Cross-domain references travel through one typed context instead of local variables. The order of every write, the refusals and their audit rows, the skip report, the cleared counts and the reported phases are unchanged; the golden copies of the restored account still match. Guards that pinned the restore by path now point at the domain files.
This commit is contained in:
1 parent
dcf49dd14e
commit
e7b31fe8e0
27 files changed
+3778
-3008
No files matched your search
@@ -322,7 +322,7 @@ describe("every backed-up model travels both ways, or is named as debt", () => {
|
||||
it("does not count a nested relation read as a restore write", () => {
|
||||
expect(
|
||||
touches(
|
||||
["src/lib/export/restore-backup.ts"],
|
||||
["src/lib/export/measurements-backup.ts"],
|
||||
"User",
|
||||
WRITE_OPS,
|
||||
WRITE_RELATION_OPS,
|
||||
@@ -569,7 +569,7 @@ describe("tables outside the schema have a backup verdict too", () => {
|
||||
"utf8",
|
||||
);
|
||||
const restore = readFileSync(
|
||||
join(SRC, "lib/export/restore-backup.ts"),
|
||||
join(SRC, "lib/export/medications-restore.ts"),
|
||||
"utf8",
|
||||
);
|
||||
expect(writer).toMatch(/getMedicationCategories\(/);
|
||||
|
||||
@@ -12,7 +12,7 @@ import { readFileSync } from "node:fs";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
const READERS = [
|
||||
"src/lib/export/restore-backup.ts",
|
||||
"src/lib/export/restore-preflight.ts",
|
||||
"src/app/api/admin/backups/[id]/summary/route.ts",
|
||||
"src/app/api/admin/backups/[id]/download/route.ts",
|
||||
"src/app/api/admin/backups/upload/route.ts",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$comment": "Production files over 800 lines and their length. Maintained by src/__tests__/source-size-ratchet.test.ts.",
|
||||
"count": 129,
|
||||
"total": 156231,
|
||||
"count": 128,
|
||||
"total": 153023,
|
||||
"entries": {
|
||||
"app/api/dashboard/summary/route.ts": 1032,
|
||||
"app/api/documents/inbound/route.ts": 811,
|
||||
@@ -73,7 +73,6 @@
|
||||
"lib/export/full-backup-payload.ts": 1520,
|
||||
"lib/export/profile-backup.ts": 1019,
|
||||
"lib/export/records-backup.ts": 834,
|
||||
"lib/export/restore-backup.ts": 3208,
|
||||
"lib/fitbit/client.ts": 1529,
|
||||
"lib/fitbit/sync-core.ts": 968,
|
||||
"lib/gamification/achievements-result.ts": 1094,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$comment": "Production functions over 200 lines, keyed \"file :: name\", and their length. Maintained by src/__tests__/source-size-ratchet.test.ts.",
|
||||
"count": 415,
|
||||
"total": 154643,
|
||||
"count": 413,
|
||||
"total": 149647,
|
||||
"entries": {
|
||||
"app/achievements/page.tsx :: AchievementsPage": 206,
|
||||
"app/api/admin/backups/upload/route.ts :: apiHandler(arg)": 314,
|
||||
@@ -324,8 +324,6 @@
|
||||
"lib/export/profile-backup.ts :: buildProfileBackupSection": 270,
|
||||
"lib/export/profile-backup.ts :: restoreProfileData": 291,
|
||||
"lib/export/records-backup.ts :: buildRecordsBackupSection": 308,
|
||||
"lib/export/restore-backup.ts :: restoreBackup": 2833,
|
||||
"lib/export/restore-backup.ts :: restoreBackup > prisma.$transaction(arg)": 2163,
|
||||
"lib/export/vaccinations-backup.ts :: restoreVaccinationsData": 216,
|
||||
"lib/export/visits-backup.ts :: restoreVisitsData": 261,
|
||||
"lib/fhir/build-bundle.ts :: buildFhirDocumentBundle": 363,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$comment": "Comment lines that open with a release version, per file under src/. Maintained by src/__tests__/version-stamp-ratchet.test.ts.",
|
||||
"count": 2962,
|
||||
"total": 10588,
|
||||
"count": 2961,
|
||||
"total": 10571,
|
||||
"entries": {
|
||||
"__tests__/account-payload-consumer-guard.test.ts": 2,
|
||||
"__tests__/acting-account-boundary-guard.test.ts": 7,
|
||||
@@ -2050,7 +2050,6 @@
|
||||
"lib/export/profile-backup.ts": 10,
|
||||
"lib/export/records-backup.ts": 4,
|
||||
"lib/export/reminders-backup.ts": 4,
|
||||
"lib/export/restore-backup.ts": 17,
|
||||
"lib/export/visits-backup.ts": 5,
|
||||
"lib/feature-flags/__tests__/index.test.ts": 2,
|
||||
"lib/fhir/build-bundle.ts": 10,
|
||||
|
||||
@@ -123,7 +123,7 @@ const WRITERS: Record<string, Disposition> = {
|
||||
},
|
||||
|
||||
// ── Restore ───────────────────────────────────────────────────────────
|
||||
"lib/export/restore-backup.ts": {
|
||||
"lib/export/measurements-backup.ts": {
|
||||
kind: "restore",
|
||||
why: "replays the record's own export; dropping rows would break the restore contract",
|
||||
},
|
||||
|
||||
@@ -81,7 +81,7 @@ const WRITE_SITES: Record<string, string> = {
|
||||
"the import worker refolds the import's span and re-warms every imported type",
|
||||
"lib/import/health-connect/import.ts":
|
||||
"the Health Connect import worker refolds the import's span and re-warms every imported type",
|
||||
"lib/export/restore-backup.ts":
|
||||
"lib/export/measurements-backup.ts":
|
||||
"a restore replaces the whole record: it refolds the whole window and drops every per-user cache",
|
||||
// Value-preserving reshapes: the same readings folded into daily or hourly
|
||||
// rows. The rollups are refolded; the figures an assessment reads do not
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* v1.43 — pair guard binding the `MedicationIngredient` model to both ends of
|
||||
* the backup: the writer's `ingredients: m.ingredients.map(...)` block in
|
||||
* `full-backup-payload.ts` and the nested create in `restore-backup.ts`.
|
||||
* `full-backup-payload.ts` and the nested create in `medications-restore.ts`.
|
||||
*
|
||||
* The failure it catches is the one the measurement guard beside it was
|
||||
* written for: a column added to the composition in a later release, the
|
||||
@@ -87,7 +87,7 @@ describe("medication ingredient backup completeness", () => {
|
||||
|
||||
it("the restore writes every column back", () => {
|
||||
const keys = blockKeys(
|
||||
read("src", "lib", "export", "restore-backup.ts"),
|
||||
read("src", "lib", "export", "medications-restore.ts"),
|
||||
"create: m.ingredients.map((i) => ({",
|
||||
);
|
||||
expect(carried.filter((c) => !keys.has(c))).toEqual([]);
|
||||
|
||||
@@ -95,7 +95,7 @@ const MAY_READ_EVERY_ROW: Record<string, string> = {
|
||||
// Record-keeping: a backup, a restore and an export carry the medication
|
||||
// as stored, schedule and switch included.
|
||||
"lib/export/full-backup-payload.ts": "backup carries the stored rows",
|
||||
"lib/export/restore-backup.ts": "restore writes the stored rows back",
|
||||
"lib/export/medications-restore.ts": "restore writes the stored rows back",
|
||||
// v1.44 — the CSV import writes new medications and reads only their names
|
||||
// and doses to skip duplicates; it derives nothing due.
|
||||
"lib/import/medications-csv.ts": "imports new rows, derives nothing due",
|
||||
|
||||
@@ -195,7 +195,7 @@ describe("T2 — the set of files writing Workout rows is frozen", () => {
|
||||
"app/api/workouts/batch/route.ts": "client-supplied enum",
|
||||
// Backup restore replays rows this app previously wrote, provenance and
|
||||
// all.
|
||||
"lib/export/restore-backup.ts": "restore replay",
|
||||
"lib/export/workouts-backup.ts": "restore replay",
|
||||
};
|
||||
|
||||
it("only the registered ingests and the declared non-mappers create Workout rows", () => {
|
||||
|
||||
Reference in new issue
Block a user