feat(mental-health): record which wording a check-in was answered in

An administration now stores `wording`: `validated` (the published
validated version of the reader's language, the original for English),
`unvalidated_translation` (HealthLog's own translation) or `original_en`
(the English original, chosen by a reader of another language). The
client sends only `englishOriginal`; the server resolves the rest from
the wording registry, so a client cannot claim a validated wording the
registry does not hold. `locale` keeps the reader's language, which
still selects the crisis resources.

Additive migration 0475: a nullable column with no backfill, since which
text earlier rows showed depended on releases since replaced. Every read
returns the field, the OpenAPI contract carries it and `englishOriginal`,
and the disaster-recovery backup carries and restores it (the parity
goldens gain the column; their pinned timestamps move by one step
because the fill writes one more column).

The PHQ-9 item-9 crisis signpost is answered from the answers alone and
is proven in every wording through the real route.
This commit is contained in:
Marc-André Bombeck committed 2026-10-23 08:14:15 +02:00
1 parent 3843705296
commit 02cc0631fa
14 files changed
+347 -66

No files matched your search

+41 -2
View File
@@ -34485,6 +34485,8 @@ components:
locale:
type: string
maxLength: 16
englishOriginal:
type: boolean
source:
default: WEB
type: string
@@ -34501,8 +34503,9 @@ components:
description: "Record one completed screener administration: PHQ-9 (9 items, 0–3), GAD-7 (7 items, 0–3), WHO-5 (5 items,
0–5) or SCI (8 items, 0–4). The array length and per-item ceiling must match the instrument. The item answers
are encrypted at rest and never returned. The server computes the total (WHO-5 reports raw-sum × 4 as 0–100) +
severity band + item-9 safety flag. Opt-in, beside mood tracking — this is a screening surface, not a
diagnosis."
severity band + item-9 safety flag. `locale` is the reader's app language; set `englishOriginal` when the reader
answered in the English original instead of their language's text, and the server records the resulting
`wording`. Opt-in, beside mood tracking — this is a screening surface, not a diagnosis."
CreateAllergyRequest:
type: object
properties:
@@ -44792,6 +44795,14 @@ components:
locale:
type: string
minLength: 1
wording:
anyOf:
- type: string
enum:
- validated
- unvalidated_translation
- original_en
- type: "null"
version:
type: string
responsesEncrypted:
@@ -78040,6 +78051,19 @@ components:
- SCI
locale:
type: string
wording:
anyOf:
- type: string
enum:
- validated
- unvalidated_translation
- original_en
- type: "null"
description: "Which text the answers were given in. `validated`: the published validated version for `locale` (the
original for English). `unvalidated_translation`: a translation written for HealthLog where no validated
version exists; clients show that the result is orientation only. `original_en`: the English original,
chosen by a reader of another language (`englishOriginal` on create). Null on administrations recorded
before v1.46."
version:
type: string
totalScore:
@@ -78060,6 +78084,7 @@ components:
- id
- instrument
- locale
- wording
- version
- totalScore
- severityBand
@@ -78265,6 +78290,19 @@ components:
- SCI
locale:
type: string
wording:
anyOf:
- type: string
enum:
- validated
- unvalidated_translation
- original_en
- type: "null"
description: "Which text the answers were given in. `validated`: the published validated version for `locale` (the
original for English). `unvalidated_translation`: a translation written for HealthLog where no validated
version exists; clients show that the result is orientation only. `original_en`: the English original,
chosen by a reader of another language (`englishOriginal` on create). Null on administrations recorded
before v1.46."
version:
type: string
totalScore:
@@ -78301,6 +78339,7 @@ components:
- id
- instrument
- locale
- wording
- version
- totalScore
- severityBand