mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-15 06:52:04 +00:00
fix(backup): carry how hard a symptom hit through export and restore
A cycle symptom can be recorded with a 1-4 intensity. The log-day sheet writes it, the day-log reads it back, and the backup never carried it: the file held the symptom keys and nothing else. Export a day recorded as "cramps, and they were a 4", restore it, and you get "cramps". The symptom is there, the number is gone, and nothing fails, which is why nobody noticed. The file now carries `symptomSeverities` alongside `symptomKeys` — one entry per symptom that was actually rated. `symptomKeys` still decides which symptoms a day had, so a release that only knows that field reads every symptom out of a new file unchanged, and the two lists can never disagree about presence. A link nobody rated is simply not listed: no entry means never rated, which is not the same as rated zero. A file written before this restores exactly as it did, with every intensity absent rather than invented. An intensity outside 1-4, from a hand-edited file or some later scale, costs that one number and leaves the symptom and the rest of the restore alone.
This commit is contained in:
1 parent
340d1db6d9
commit
92da02f824
4 files changed
+407
-12
No files matched your search
@@ -267,8 +267,26 @@ const cycleSpanSchema = z
|
||||
* ciphertext envelope verbatim — the backup never decrypts it, so the
|
||||
* owner's free-text note round-trips encrypted (and a wrong-surface leak is
|
||||
* impossible). `symptomKeys` carries the seeded catalogue keys so the
|
||||
* restore can re-link without exporting internal join ids.
|
||||
* restore can re-link without exporting internal join ids, and
|
||||
* `symptomSeverities` carries how hard each of them hit.
|
||||
*/
|
||||
/**
|
||||
* The intensity recorded against one of a day's symptoms.
|
||||
*
|
||||
* A sparse annotation over `symptomKeys`, not a replacement for it: the keys
|
||||
* still say which symptoms the day had, this says how hard the ones that were
|
||||
* rated hit. Only rated links appear, so a missing entry means the person never
|
||||
* put a number on it. `severity` is left as a plain integer here on purpose —
|
||||
* the 1-4 range is checked when the row is written, so a file carrying a value
|
||||
* outside it loses that one intensity instead of failing to restore at all.
|
||||
*/
|
||||
const cycleSymptomSeveritySchema = z
|
||||
.object({
|
||||
key: z.string().min(1),
|
||||
severity: z.number().int().nullable().optional(),
|
||||
})
|
||||
.passthrough();
|
||||
|
||||
const cycleDayLogSchema = z
|
||||
.object({
|
||||
id: z.string().min(1).optional(),
|
||||
@@ -298,6 +316,7 @@ const cycleDayLogSchema = z
|
||||
createdAt: isoDateTime.optional(),
|
||||
updatedAt: isoDateTime.optional(),
|
||||
symptomKeys: z.array(z.string()).default([]),
|
||||
symptomSeverities: z.array(cycleSymptomSeveritySchema).default([]),
|
||||
})
|
||||
.passthrough();
|
||||
|
||||
|
||||
Reference in new issue
Block a user