09 — User Behaviour (i18n Module)
- 1. Consumer behaviours
- 2. Manager behaviours (planned console)
- 3. Failure-moment matrix
- 4. Behavioural rules
Observed behaviors, pain points, and design responses for translation consumers and (planned) managers. Personas in 02; journeys in 03.
1. Consumer behaviours
| Behaviour | Evidence | Design response |
|---|---|---|
| Locale comes from the device, not the app | locale resolved from Accept-Language only (i18n.middleware.ts:13-18); no in-app switcher | Keep header-first resolution; in-app switcher (forward-looking); ?locale= query override exists (i18n.controller.ts:15) |
| Users ignore English fallback | missing hi key renders English silently (i18n.service.ts:40) | Acceptable at runtime; CI drift check (planned) prevents silent drift shipping (IMPLEMENTATION_PLAN.md:845) |
Users notice literal {days} when a param is missing | runtime keeps {name} literal (i18n.service.ts:43) | Param parity validation in editor (08 §2) + tests |
| Region tags confuse resolution | hi-IN handled by split('-')[0] (i18n.middleware.ts:16) | Keep region-stripping; document that en-GB → en |
| App caches catalog aggressively | full map per fetch (getMessages, i18n.service.ts:47-49) | Cache-key = locale; version header (planned) for deltas (forward-looking) |
2. Manager behaviours (planned console)
| Behaviour | Pain today | Console response |
|---|---|---|
| Hand-edits JSON and deploys | en.json/hi.json manual edits; typo = runtime bug | Key Editor with live placeholder check (06 §2) |
| Doesn't know which locales are behind | no coverage signal anywhere | CoverageRing + missing badges (05 §1, 07 §2) |
| Adds a key to en only, ships it | silent English fallback for other locales | Save-time warning + CI gate (planned) |
| Reorders params while translating | runtime shows literal {days} (i18n.service.ts:43) | param parity error blocks save (08 §2) |
| Wants per-tenant copy | non-goal today (global catalogs, 01 §6) | Documented; tenant-catalog variant (forward-looking) |
3. Failure-moment matrix
| Moment | User sees | Correctness | Fix |
|---|---|---|---|
| Unknown key | key literal (e.g. errors.internal2) | degraded but honest | add key; editor search helps |
| Unknown locale | English | correct fallback | — |
| Missing param | Leave requested for {days} day(s). | broken copy visible | parity check blocks |
| Empty value in hi | empty string | worst case — empty UI | block save; never-empty guarantee i18n.service.ts:40 |
| 401 on catalog fetch | offline UI | correct | retry with backoff; cache last good catalog |
4. Behavioural rules
- Never render a blank string. If catalog lookup fails, fall back to
en, then to key — never
''(matchesi18n.service.ts:40). - English is the source of truth for keys and params; every other locale is derived.
- Console edits are global (no tenant dimension) until per-tenant catalogs are introduced (forward-looking).
- No auto-correct on translation fields (Indic scripts, 07 §8).
- Locale ≠ language of content. Tenant-authored announcements
(
announcement.service.ts:47) are content, not UI strings — they are never translated by this module; only system copy (notifications.handler.ts:16-31keys (planned)) is.