mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-14 06:40:50 +00:00
fix(profile): let the third gender value through every surface that handles it
The profile validator has accepted MALE, FEMALE and OTHER for a long time, but the published contract documented two, and a client written against that contract had no way to know the third existed. The profile PATCH is one write, so a rejected gender took every sibling field with it - a time-format change lost to a field the person never touched. Gender now clears on an empty string, the same contract every other profile field documents, and an unsupported value is refused with a message that names the field and its accepted values instead of the validator's own prose. Onboarding validated against a narrower enum than the profile schema and 422'd the whole submission; its form could not record the third value at all. The rest is the same defect in other clothes. The Strain model scored an unanswered or OTHER account on the male Banister coefficients; it now uses the midpoint of both published models, matching every other sex-split formula here. The dashboard snapshot emitted null for an account that answered OTHER, which is indistinguishable from no answer. Three casts asserted a two-value type over a three-value column. All of them now carry the stored value and narrow once, at the boundary of a reference table that genuinely has no third row, through one named helper in src/lib/profile/sex.ts. Refs #645
This commit is contained in:
1 parent
0ce510fa68
commit
f74efc44aa
28 files changed
+388
-39
No files matched your search
@@ -45,7 +45,23 @@ export const profileSchema = z.object({
|
||||
email: z.email("Invalid email address").nullable().optional(),
|
||||
heightCm: z.number().min(50).max(300).nullable().optional(),
|
||||
dateOfBirth: z.string().nullable().optional(), // ISO date string
|
||||
gender: z.enum(["MALE", "FEMALE", "OTHER"]).nullable().optional(),
|
||||
// Three stored values, and the same clearing contract every other
|
||||
// profile field honours: null OR an empty string clears it. A client
|
||||
// that renders "no answer" as "" was otherwise 422'd on a field the
|
||||
// person never touched, and because the whole profile PATCH is one
|
||||
// transaction that rejection took every sibling change with it. The
|
||||
// message names the field and the accepted values — a person should
|
||||
// never read the validator's own prose off a form.
|
||||
gender: z.preprocess(
|
||||
(v) => (v === "" ? null : v),
|
||||
z
|
||||
.enum(["MALE", "FEMALE", "OTHER"], {
|
||||
error:
|
||||
"Gender must be MALE, FEMALE or OTHER. Send null or an empty string to clear it.",
|
||||
})
|
||||
.nullable()
|
||||
.optional(),
|
||||
),
|
||||
// v1.7.0 — optional patient-identity fields for the health-record
|
||||
// export cover + FHIR Patient resource. All optional, never required.
|
||||
fullName: z.string().trim().max(120).nullable().optional(),
|
||||
|
||||
Reference in new issue
Block a user