Carry the custom-metric entry tombstone through backup and restore

The entries gained a soft-delete this release; both backup ends follow in
the same one. A portable export omits tombstoned readings so a restore
cannot resurrect them; a disaster-recovery payload carries the tombstone
and the restore writes it back, so the account returns exactly as it
stood — undo affordance included.
This commit is contained in:
Marc-André Bombeck committed 2026-08-14 09:58:11 +02:00
1 parent bcabd43ca7
commit 4941cd075b
2 files changed
+14 -1

No files matched your search

+11 -1
View File
@@ -118,6 +118,8 @@ export interface CustomMetricEntryBackupEntry {
measuredAt: string;
note: string | null;
createdAt?: string;
/** v1.37.20 (A3-11) — soft-delete tombstone; DR payloads only. */
deletedAt?: string | null;
}
/**
@@ -260,7 +262,13 @@ export async function buildProfileBackupSection(
where: disasterRecovery ? { userId } : { userId, deletedAt: null },
orderBy: { name: "asc" },
include: {
entries: { orderBy: { measuredAt: "asc" } },
// v1.37.20 (A3-11) — entries soft-delete now: a portable export
// omits tombstoned readings (a restore must not resurrect them); a
// DR payload carries them, tombstone included, like the parent.
entries: {
where: disasterRecovery ? {} : { deletedAt: null },
orderBy: { measuredAt: "asc" },
},
},
}),
prisma.healthProfileFactRevision.findMany({
@@ -438,6 +446,7 @@ export async function buildProfileBackupSection(
? {
id: entry.id,
createdAt: entry.createdAt.toISOString(),
deletedAt: entry.deletedAt?.toISOString() ?? null,
}
: {}),
value: entry.value,
@@ -840,6 +849,7 @@ export async function restoreProfileData(
unit: entry.unit,
measuredAt: new Date(entry.measuredAt),
note: entry.note,
deletedAt: entry.deletedAt ? new Date(entry.deletedAt) : null,
...(entry.createdAt
? { createdAt: new Date(entry.createdAt) }
: {}),
+3
View File
@@ -611,6 +611,9 @@ const customMetricEntryBackupSchema = z
measuredAt: isoDateTime,
note: z.string().nullable().default(null),
createdAt: isoDateTime.optional(),
/// v1.37.20 (A3-11) — the entry tombstone rides DR payloads so a restore
/// brings the account back exactly as it stood, undo affordance included.
deletedAt: isoDateTime.nullable().optional(),
})
.passthrough();