Missing i18n translations: event.title.approval_decided + event.title.member_role_changed render as raw keys #101

Open
opened 2026-05-25 13:22:32 +00:00 by mAi · 1 comment
Collaborator

m's report (2026-05-25 15:23)

In an event-type filter list (looks like the /events or custom-view filter), two entries render as raw i18n keys instead of translated labels:

Event
  All
  Project created
  Project archived
  Project re-parented
  Project type changed
  Status changed
  Deadline created
  Deadline completed
  Deadline reopened
  Appointment created
  Appointment updated
  Appointment deleted
  event.title.approval_decided          ← raw key
  event.title.member_role_changed       ← raw key

There are some codes apparently - instead of names.

All the others use a proper translated label. Two keys missed the i18n catalog.

What to do

  1. Add the two missing keys to frontend/src/client/i18n.ts and frontend/src/i18n-keys.ts:
    • event.title.approval_decided → DE: "Genehmigung entschieden" / EN: "Approval decided"
    • event.title.member_role_changed → DE: "Teamrolle geändert" / EN: "Team role changed"
  2. Audit the rest of the event title catalog (every kind in paliad.project_events.event_type and KnownProjectEventKinds) and confirm each has both DE + EN labels.
  3. If a similar miss exists elsewhere (e.g. checklists, notes, audit feed), patch in the same commit if cheap; otherwise note in the completion report.

Files most likely touched

  • frontend/src/client/i18n.ts
  • frontend/src/i18n-keys.ts
  • Possibly the audit-feed render code if the fallback is buggy (i.e. it should show the key as a fallback only — should never happen with the catalog populated)

Hard rules

  • DE primary, EN secondary (per project CLAUDE.md).
  • Use proper Umlaute (ä, ö, ü, ß) — never ae/oe/ue.
  • cd frontend && bun run build clean (i18n codegen runs; should catch missing keys).
  • Branch: mai/<worker>/i18n-event-titles.

Out of scope

  • Re-renaming existing event-title labels.
  • Restructuring the i18n key hierarchy.

Reporting

mai report completed with branch + SHAs + the audited list of all event kinds + their DE/EN labels.

## m's report (2026-05-25 15:23) In an event-type filter list (looks like the /events or custom-view filter), two entries render as raw i18n keys instead of translated labels: ``` Event All Project created Project archived Project re-parented Project type changed Status changed Deadline created Deadline completed Deadline reopened Appointment created Appointment updated Appointment deleted event.title.approval_decided ← raw key event.title.member_role_changed ← raw key ``` > There are some codes apparently - instead of names. All the others use a proper translated label. Two keys missed the i18n catalog. ## What to do 1. Add the two missing keys to `frontend/src/client/i18n.ts` and `frontend/src/i18n-keys.ts`: - `event.title.approval_decided` → DE: "Genehmigung entschieden" / EN: "Approval decided" - `event.title.member_role_changed` → DE: "Teamrolle geändert" / EN: "Team role changed" 2. Audit the rest of the event title catalog (every kind in `paliad.project_events.event_type` and `KnownProjectEventKinds`) and confirm each has both DE + EN labels. 3. If a similar miss exists elsewhere (e.g. checklists, notes, audit feed), patch in the same commit if cheap; otherwise note in the completion report. ## Files most likely touched - `frontend/src/client/i18n.ts` - `frontend/src/i18n-keys.ts` - Possibly the audit-feed render code if the fallback is buggy (i.e. it should show the key as a fallback only — should never happen with the catalog populated) ## Hard rules - DE primary, EN secondary (per project CLAUDE.md). - Use proper Umlaute (ä, ö, ü, ß) — never ae/oe/ue. - `cd frontend && bun run build` clean (i18n codegen runs; should catch missing keys). - Branch: `mai/<worker>/i18n-event-titles`. ## Out of scope - Re-renaming existing event-title labels. - Restructuring the i18n key hierarchy. ## Reporting `mai report completed` with branch + SHAs + the audited list of all event kinds + their DE/EN labels.
mAi self-assigned this 2026-05-25 13:22:32 +00:00
Author
Collaborator

Fix shipped

Branch: mai/artemis/gitster-add-missing-i18n
Commit: f72e8a7mAi: #101 - add missing event.title.approval_decided + member_role_changed i18n

Root cause

frontend/src/client/filter-bar/axes.ts:300-314 hard-codes a PROJECT_EVENT_KINDS list (the FilterBar chip cluster), then renders each chip's label via:

const label = tDyn(`event.title.${kind}`);

tDyn (i18n.ts:6091-6093) falls back to the raw key when the catalog is missing the entry — exactly what was on screen. The catalog covered every other kind in PROJECT_EVENT_KINDS but had no entries for approval_decided or member_role_changed.

Changes

frontend/src/client/i18n.ts — two new entries per locale, placed right after appointment_project_changed so the umbrella/admin kinds sit next to the lifecycle kinds and before the per-entity *_approval_* lifecycle block:

key DE EN
event.title.approval_decided Genehmigung entschieden Approval decided
event.title.member_role_changed Teamrolle geändert Team role changed

frontend/src/i18n-keys.ts — regenerated by frontend/build.ts's generateI18nKeys (auto-generated from the source of truth above).

bun run build clean — i18n codegen reports 2864 keys, data-i18n scan clean, dist/ built.

Audit — every KnownProjectEventKind has DE + EN now

Canonical list lives in internal/services/filter_spec.go:200:

kind DE label EN label
project_created Projekt angelegt Project created
project_archived Projekt archiviert Project archived
project_reparented Projekt umstrukturiert Project re-parented
project_type_changed Projekt-Typ geändert Project type changed
status_changed Status geändert Status changed
deadline_created Frist angelegt Deadline created
deadline_completed Frist erledigt Deadline completed
deadline_reopened Frist wiedereröffnet Deadline reopened
deadline_updated Frist geändert Deadline updated
deadline_deleted Frist gelöscht Deadline deleted
deadlines_imported Fristen importiert Deadlines imported
appointment_created Termin angelegt Appointment created
appointment_updated Termin geändert Appointment updated
appointment_deleted Termin gelöscht Appointment deleted
approval_decided Genehmigung entschieden Approval decided
member_role_changed Teamrolle geändert Team role changed
note_created Notiz hinzugefügt Note added
our_side_changed Vertretene Seite geändert Represented side changed

18 / 18 covered. = newly added.

Notes for follow-up

  1. Drift risk between PROJECT_EVENT_KINDS (axes.ts) and KnownProjectEventKinds (filter_spec.go) remains. Today the frontend list is a hand-maintained subset — it omits deadline_updated, deadline_deleted, deadlines_imported, note_created, and our_side_changed. That divergence is intentional in the current state (the chip cluster is a curated UX, not a faithful mirror), but the file comment at axes.ts:295 says "Mirrors KnownProjectEventKinds", which is no longer true. Worth either (a) realigning the list, or (b) updating the comment. Out of scope for this issue — flagging for awareness, not patching.
  2. Fallback behaviour is intentional. tDyn returning the key itself was what made this bug visible; that's the right contract (better than rendering an empty chip). Leaving it.
  3. No other surfaces affected. The *_approval_* per-entity audit kinds (event.title.deadline_approval_requested, etc.) are already covered; they're separate event_types and not the umbrella approval_decided chip label.

Reporting

No other rendering callsites (Verlauf row title via translateEvent, ShapeList via t("event.title." + …)) were calling into the missing kinds because no paliad.project_events row carries event_type='approval_decided' (it's a filter-only umbrella). The actually-emitted member_role_changed rows from internal/services/partner_unit_service.go:369 will now also render with a translated title wherever the event-rendering path passes them through event.title.*.

## Fix shipped **Branch:** `mai/artemis/gitster-add-missing-i18n` **Commit:** [`f72e8a7`](https://mgit.msbls.de/m/paliad/commit/f72e8a7b852be7e6808c6fd254c930e141d0f29e) — `mAi: #101 - add missing event.title.approval_decided + member_role_changed i18n` ### Root cause `frontend/src/client/filter-bar/axes.ts:300-314` hard-codes a `PROJECT_EVENT_KINDS` list (the FilterBar chip cluster), then renders each chip's label via: ```ts const label = tDyn(`event.title.${kind}`); ``` `tDyn` (i18n.ts:6091-6093) falls back to **the raw key** when the catalog is missing the entry — exactly what was on screen. The catalog covered every other kind in `PROJECT_EVENT_KINDS` but had no entries for `approval_decided` or `member_role_changed`. ### Changes `frontend/src/client/i18n.ts` — two new entries per locale, placed right after `appointment_project_changed` so the umbrella/admin kinds sit next to the lifecycle kinds and before the per-entity `*_approval_*` lifecycle block: | key | DE | EN | |---|---|---| | `event.title.approval_decided` | Genehmigung entschieden | Approval decided | | `event.title.member_role_changed` | Teamrolle geändert | Team role changed | `frontend/src/i18n-keys.ts` — regenerated by `frontend/build.ts`'s `generateI18nKeys` (auto-generated from the source of truth above). `bun run build` clean — i18n codegen reports 2864 keys, data-i18n scan clean, dist/ built. ### Audit — every KnownProjectEventKind has DE + EN now Canonical list lives in `internal/services/filter_spec.go:200`: | kind | DE label | EN label | |---|---|---| | `project_created` | Projekt angelegt | Project created | | `project_archived` | Projekt archiviert | Project archived | | `project_reparented` | Projekt umstrukturiert | Project re-parented | | `project_type_changed` | Projekt-Typ geändert | Project type changed | | `status_changed` | Status geändert | Status changed | | `deadline_created` | Frist angelegt | Deadline created | | `deadline_completed` | Frist erledigt | Deadline completed | | `deadline_reopened` | Frist wiedereröffnet | Deadline reopened | | `deadline_updated` | Frist geändert | Deadline updated | | `deadline_deleted` | Frist gelöscht | Deadline deleted | | `deadlines_imported` | Fristen importiert | Deadlines imported | | `appointment_created` | Termin angelegt | Appointment created | | `appointment_updated` | Termin geändert | Appointment updated | | `appointment_deleted` | Termin gelöscht | Appointment deleted | | `approval_decided` ✨ | **Genehmigung entschieden** | **Approval decided** | | `member_role_changed` ✨ | **Teamrolle geändert** | **Team role changed** | | `note_created` | Notiz hinzugefügt | Note added | | `our_side_changed` | Vertretene Seite geändert | Represented side changed | 18 / 18 covered. ✨ = newly added. ### Notes for follow-up 1. **Drift risk between `PROJECT_EVENT_KINDS` (axes.ts) and `KnownProjectEventKinds` (filter_spec.go) remains.** Today the frontend list is a hand-maintained subset — it omits `deadline_updated`, `deadline_deleted`, `deadlines_imported`, `note_created`, and `our_side_changed`. That divergence is intentional in the current state (the chip cluster is a curated UX, not a faithful mirror), but the file comment at `axes.ts:295` says *"Mirrors KnownProjectEventKinds"*, which is no longer true. Worth either (a) realigning the list, or (b) updating the comment. Out of scope for this issue — flagging for awareness, not patching. 2. **Fallback behaviour is intentional.** `tDyn` returning the key itself was what made this bug visible; that's the right contract (better than rendering an empty chip). Leaving it. 3. **No other surfaces affected.** The `*_approval_*` per-entity audit kinds (`event.title.deadline_approval_requested`, etc.) are already covered; they're separate event_types and not the umbrella `approval_decided` chip label. ### Reporting No other rendering callsites (Verlauf row title via `translateEvent`, ShapeList via `t("event.title." + …)`) were calling into the missing kinds because no `paliad.project_events` row carries `event_type='approval_decided'` (it's a filter-only umbrella). The actually-emitted `member_role_changed` rows from `internal/services/partner_unit_service.go:369` will now also render with a translated title wherever the event-rendering path passes them through `event.title.*`.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: m/paliad#101
No description provided.