Skip to content

feat: Korean locale (#839, @aucun6352) — the seventh interface language - #849

Merged
MBombeck merged 5 commits into
mainfrom
feat/korean-locale
Aug 28, 2026
Merged

feat: Korean locale (#839, @aucun6352) — the seventh interface language#849
MBombeck merged 5 commits into
mainfrom
feat/korean-locale

Conversation

@MBombeck

Copy link
Copy Markdown
Owner

Brings HealthLog's interface language count to seven. Korean (ko) joins German, English, Spanish, French, Italian and Polish, contributed by @aucun6352 in #839.

The work is theirs. Their three commits are preserved with their authorship, so the credit stays where it belongs.

What lands

  • The full Korean message catalog, sitting alongside the other six locales.
  • An NFC recompose in the shared fold helper, so decomposed Hangul jamo match their composed form when the app searches or compares user text.
  • A LOINC key normaliser for Hangul lab names, so a Korean-entered analyte still resolves to its reference band.
  • The tilde ~ as a range separator, which is how Korean written numbers express a span.
  • The officially published Korean wording for PHQ-9, GAD-7 and WHO-5, so those instruments render in a validated translation rather than a home-made one.

What I added on top

Trunk moved on between the original PR and this merge, so two families of keys had drifted:

  • The chart range selector was renamed from "points" to "days" in v1.37.29. The Korean catalog still carried the old points* keys, so I recomposed them as days* with day-based Korean wording (7일, 최근 7일, and so on).
  • The admin AI provider-health card arrived in v1.37.31 with seventeen new keys the Korean catalog had never seen. I translated them faithfully.

Both were caught by the locale-integrity guard, which is exactly its job: every key in en.json must have a Korean value or CI goes red. That guard is also the answer to the maintenance question. A future English string with no Korean translation cannot ship silently. It fails the build until someone fills it in.

The aggregate client-bundle budget rises from 3500 to 3700 KB gz to make room for a seventh message catalog. The measured total is 3631 KB. The reasoning is recorded next to the value in bundle-budget.json.

Gate

typecheck, full unit suite (22301 passing), lint (no new warnings), format check, OpenAPI in sync, production build, and the bundle budget all green locally.

aucun6352 and others added 5 commits August 26, 2026 16:42
Register `ko` in the locale list, language names, and labels, and ship
messages/ko.json so the whole UI — dashboard, settings, share views,
clinician PDF, notifications, and AI prompts — renders in Korean.

Extend the locale-parity, English-leak, plural-completeness, and copy
guard tests to cover the new locale, and update README/CONTRIBUTING to
list Korean among the supported languages.
Registering `ko` in the `Locale` union left seven locale-keyed tables
without an entry, so the build could not type-check and the safety
screens, the citation-coverage grader and the reference-range parser
read nothing at all for a Korean reader.

Three failures were not missing keys but wrong assumptions:

- The shared fold decomposes with NFD and strips U+0300-U+036F. Latin
  accents become plain letters, but Hangul decomposes into jamo, which
  are not in that range and survived — so folded Korean text was a jamo
  sequence no precomposed table entry could ever match. It recomposes to
  NFC now; every Latin, Polish and German fold is byte-identical.
- `normaliseLabKey` kept `[a-z0-9]`, which reduced every Korean analyte
  name to the empty string, so the derived index held none of them and a
  Korean cholesterol result reached a FHIR export uncoded.
- The reference-range parser had the hyphen and the dashes but not the
  tilde a Korean lab actually prints (`3.5~5.0`).

The Korean safety banks carry no `\b` next to a Hangul token — `\b` is
an ASCII `\w` boundary and Hangul is not `\w`, so `/\b증량/` matches
nothing — and the clause order is the mirror of the Latin banks, since
Korean closes with the verb. The dose patterns require a target-marking
particle for the same reason the Latin banks require "to"/"by": without
it the permitted restatement "7.5mg을 복용 중이고, 체중은 내려가고
있어요" tripped the lowering pattern.

The Coach and Insights prompts route `ko` down the reviewed English body
plus a Korean reply directive; there is no `safety-contracts.ko.yaml`, so
the native builder has no Korean ground rules to compose from.
The Korean questionnaire wording was translated freshly from English, so
a score built from it was comparable to nothing in the literature. Each
instrument now carries the text its own publisher put out, or no Korean
at all.

PHQ-9 and GAD-7 come verbatim from the instrument owner's distribution —
Pfizer's `PHQ9_Korean for Korea.pdf` (2010-06-15) and `GAD7_Korean for
Korea.pdf` (2010-05-18), the latter being the file Ahn/Kim/Choi 2019
names as what it validated. The sheets grant reproduction, translation,
display and distribution without permission. Verbatim means verbatim:
the spacing in "7 일 이상 방해 받았다" and the sheet's "안절부절 못하거나"
against the GAD-7 sheet's "안절부절못해서" are reproduced as printed.

WHO-5 has no official Korean arm. Neither the WHO's 2024 distribution
(26 languages) nor the Psychiatric Research Unit folder it inherited
from (31 languages) has ever carried one, and ePROVIDE lists the same
31. Korean therefore carries the published forward/back-translation
from Kim HJ et al., J Korean Geriatr Psychiatry 2010;14(2):90-96, which
is CC BY-NC and so redistributable; the attribution line names it. Its
validation sample was community-dwelling elderly rather than general
adults, which the definition says out loud.

The Sleep Condition Indicator reverts to English. It is validated in
English only, its cut-off was derived from those words, and no openly
redistributable Korean exists — so `ko` now matches de/es/fr/it/pl:
items, section stems and response anchors byte-identical to en.json,
under the localized "validated in English" note.

`ALL_APP_LOCALES` grows to seven, which is what stops the check-in
wizard claiming English wording over Korean items on every Korean
check-in.

One gap is deliberate and not yet resolved. The official Korean PHQ-9
and GAD-7 sheets disagree on anchor 2 — "7 일 이상 방해 받았다" against
"2 주 중 절반 이상 방해 받았다" — but both instruments read one shared
`mentalHealth.options` set, which holds for the other six locales
because their two sheets agree word for word. Korean takes the PHQ-9
wording for both here. GAD-7's anchors are therefore validated in
substance but not verbatim; splitting them into a `gad7Options`
namespace is the fix, and is left for the maintainer to weigh against
the 24 duplicated keys it would add across the other locales.

The functional-impairment item and its four anchors come from the same
PHQ-9 sheet. They are not scored and not covered by the
`validatedItemLocales` contract.
Integrates @aucun6352's Korean locale (PR #839): the full catalog, the
NFC recompose in the shared fold, the Hangul lab-name normaliser, the
tilde range separator, and the officially published Korean PHQ-9, GAD-7
and WHO-5 wording. Resolves the CHANGELOG and OpenAPI conflicts against
the current trunk and regenerates the spec. Raises the aggregate bundle
budget to 3700 KB gz for the seventh message catalog, with the reasoning
recorded next to the value.

The contributor's three commits are preserved with their authorship.
@MBombeck
MBombeck merged commit 05732c6 into main Aug 28, 2026
23 checks passed
@MBombeck
MBombeck deleted the feat/korean-locale branch August 28, 2026 21:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants