Skip to content

feat(translations): resolve imaging type labels via translated_string at execution#446

Open
hrazasalman wants to merge 1 commit into
mainfrom
feat/imaging-type-db-translations-main
Open

feat(translations): resolve imaging type labels via translated_string at execution#446
hrazasalman wants to merge 1 commit into
mainfrom
feat/imaging-type-db-translations-main

Conversation

@hrazasalman

Copy link
Copy Markdown
Collaborator

No description provided.

@github-actions

This comment was marked as outdated.

@hrazasalman hrazasalman force-pushed the feat/imaging-type-db-translations-main branch from 08d8793 to 9f5356b Compare May 13, 2026 07:38
@github-actions

github-actions Bot commented May 13, 2026

Copy link
Copy Markdown
Contributor

Claude finished @hrazasalman's task in 3m 4s —— View job


PR Review: feat(translations) — Imaging type DB translations

Verdict: ⚠️ a few items worth a look, but the approach is sound. 0 blockers / 3 suggestions / 3 nits.

Todo

  • Read repo guidance (CLAUDE.md / AGENT.md / REVIEW.md)
  • Examine PR diff against origin/main
  • Review macros/translations changes
  • Review new translated_strings base model
  • Review imaging-request reports and dataset YML
  • Review generator script changes
  • Run repo validation checks (validate_report_configs.py, check_translations.py, sqlfluff) — not runnable in this sandbox (no permission / sqlfluff not installed). Please run locally before merge.

🟡 Suggestion 1 — imaging_type loses its friendly fallback

macros/models/imaging_requests.sql:65-80 (removed) used a hand-coded CASE (xRay → X-Ray, vascularStudy → Vascular Study, …). After this PR, ir.imaging_type exposes the raw code and the reports rely entirely on coalesce(t_imaging_type.text, imaging_type).

If a deployment's translated_strings table is missing a row for imaging.property.type.<code> (e.g. a code added to a release before the CSV-seeded translations land), the report column will now render the raw code (xRay, ctScan, vascularStudy) instead of the previous friendly label. That is a behavioural regression for any environment whose translated_strings is not authoritative.

Suggested options:

  • Confirm that every imaging_type code currently produced by Tamanu has a default-language row in translated_strings on every supported deployment, or
  • Keep the CASE as a secondary fallback: coalesce(t_imaging_type.text, <hardcoded case>, imaging_type).

Fix this →


🟡 Suggestion 2 — note_type semantics changed silently (code → display name)

models/bases/notes.sql:7 flipped rd.code as note_typerd.name as note_type. Internally the PR keeps things consistent (filters everywhere now use note_type_id, e.g. note_type_id != 'notetype-system'), but note_type is part of the published base model surface. Any downstream tamanu-dbt-* package or external consumer that currently treats note_type as a code-like enum ('system', 'areaToBeImaged', …) will break — values are now display names.

Worth either:

  • explicitly noting this in the PR description / release notes for deployment repos, or
  • considering whether note_type should stay as the code and downstream code use a separate note_type_name column.

Also models/bases/notes.yml:27-28 describes the new column as {{ doc('reference_data__name') }} for the note type. — mixing a doc-block reference with trailing prose. AGENT.md says descriptions should reuse doc blocks; consider adding a dedicated notes__note_type block in models/sources/notes.md.


🟡 Suggestion 3 — get_translation_lookup() with no prefix returns the entire table

macros/translations.sql:70-99. When prefix_key is none (the default), key_list is empty so no where is emitted, and the CTE materialises every row in translated_strings. That's a footgun: any caller that forgets to pass a prefix gets a full-table scan as a CTE.

Consider either:

  • making prefix_key mandatory (omit the default), or
  • raising a compiler error when no prefix is provided.

The companion change in get_translation_prefix (now exceptions.raise_compiler_error on unknown keys) is a great improvement — applying the same defensiveness here would be consistent.


🔵 Nit 1 — n.note_type in encounter_summary no longer translated

macros/models/encounter_summary.sql:381 previously wrapped n.note_type in translate_column_value('NOTE_TYPE_LABELS', ...). Now it emits n.note_type directly (i.e. reference_data.name in the source DB language). Since the PR introduces a runtime-translation mechanism, it feels inconsistent that imaging types are translated via translated_strings at query time while note types fall back to reference_data.name only. Probably out of scope for this PR, but worth a follow-up ticket.

🔵 Nit 2 — Group-by widened by a functionally-dependent column

models/reports/sql/standard/imaging-requests-summary.sql:42-43 (and the sensitive variant) add t_imaging_type.text to both group by and order by. Because the join is 1:1 on string_id = '…' || ir.imaging_type and ir.imaging_type is already grouped, t_imaging_type.text is functionally determined by ir.imaging_type. Adding it is required for Postgres' grouping rules, but order by doesn't need both — the trailing t_imaging_type.text in order by is redundant.

🔵 Nit 3 — language not escaped in the lookup CTE

macros/translations.sql:90 interpolates '{{ language }}' directly into SQL. The prefix is escaped (p.replace("'", "''")) but the language value isn't. In practice language comes from a dbt var so this isn't exploitable, but for symmetry / future-proofing a language.replace("'", "''") would be consistent.


✅ Good things

  • get_translation_prefix now hard-errors on unknown keys — much nicer than the previous silent empty string.
  • Extracting generate_translation_macro into scripts/utils/translation_utils.py and switching to repr() for emitting Jinja literals is a clean fix for the old hand-rolled escaping.
  • New translated_strings base model and YAML reuse existing doc blocks (models/sources/translated_strings.md) correctly.
  • Pattern of building a small _translations CTE per report keeps the runtime translation logic local and easy to audit.

Suggested regression checks before merge

python scripts/validate_report_configs.py
python scripts/check_translations.py
sqlfluff lint .
dbt build --select imaging_requests+ encounter_summary+ user_audit+ --profiles-dir config

Spot-check a deployment whose translated_strings table is not fully populated with imaging.property.type.* rows, to confirm the fallback behaviour is acceptable.


• Branch: feat/imaging-type-db-translations-main

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.

1 participant