mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-14 06:40:50 +00:00
The element schemas move out of validations/backup.ts into one <domain>-backup-schema.ts per domain, beside its export and restore, with the shared primitives in backup-schema-kit.ts. validations/backup.ts now composes the slices into backupPayloadSchema in the same key order, with the same defaults and the checks that span sections, so the parsed payload, every validation message and the OpenAPI contract are unchanged. The lazy-schema guard now covers the slices too: a slice is reached only through the payload schema or another slice, never from a domain's export or restore. The external-id guard carries the payload's exemption to its slices, and mutation testing scores the slices with the payload schema.
45 lines
1.7 KiB
TypeScript
45 lines
1.7 KiB
TypeScript
/**
|
|
* The ecg slice of the backup payload schema.
|
|
*
|
|
* Part of the ecg backup domain, beside its export and restore.
|
|
* Loaded only through `src/lib/validations/backup.ts`, which composes every
|
|
* slice into `backupPayloadSchema` on first use (the schema is ~12 MB of
|
|
* heap; see `backup-schema-lazy-guard.test.ts`).
|
|
*/
|
|
import { z } from "zod/v4";
|
|
import {
|
|
MeasurementSource,
|
|
RhythmClassification,
|
|
} from "@/generated/prisma/enums";
|
|
import { base64BytesSchema, isoDateTime } from "@/lib/export/backup-schema-kit";
|
|
|
|
/**
|
|
* One ECG strip.
|
|
*
|
|
* `waveformEncrypted` and `waveform` are the two ends of the same contract, so
|
|
* both are optional here and exactly one arrives: a disaster-recovery file
|
|
* carries the ciphertext, a portable file carries the micro-volt samples.
|
|
* Requiring either would refuse half the valid files. `samplingFrequency` and
|
|
* `sampleCount` stay required in both, because without them the samples are a
|
|
* list of numbers with no time axis.
|
|
*/
|
|
export const ecgRecordingBackupSchema = z
|
|
.object({
|
|
id: z.string().min(1).optional(),
|
|
source: z.enum(MeasurementSource),
|
|
externalRecordingId: z.string().min(1),
|
|
recordedAt: isoDateTime,
|
|
waveformEncrypted: base64BytesSchema.optional(),
|
|
waveform: z.array(z.number()).optional(),
|
|
samplingFrequency: z.number().int(),
|
|
sampleCount: z.number().int(),
|
|
durationSeconds: z.number().nullable().optional(),
|
|
lead: z.string().nullable().optional(),
|
|
averageHeartRate: z.number().int().nullable().optional(),
|
|
rhythmClassification: z.enum(RhythmClassification).nullable().optional(),
|
|
measurementId: z.string().min(1).nullable().optional(),
|
|
createdAt: isoDateTime,
|
|
updatedAt: isoDateTime,
|
|
})
|
|
.passthrough();
|