Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

12 — API Mapping (i18n Module)

Exact endpoints, contracts and RBAC. Envelope conventions per 00-shared/07_API_Conventions.md; versioning /api/v1 URI (src/main.ts:44-46).


1. Live endpoints

GET /api/v1/i18n/messages

FieldDetail
AuthJWT (JwtAuthGuard, i18n.controller.ts:8) — Bearer token required
RBAC permissionnone (guard only; no i18n.* perm exists in permissions.constants.ts — verified: all 97 perms, no i18n entries)
Querylocale?: string (optional; default = resolved locale)
Behaviorlocale provided → CATALOGS[locale]; else resolved locale; unknown/missing → English DEFAULT_CATALOG (i18n.service.ts:47-49)
Responseflat Record<string,string> (key → localized template), e.g. { "app.welcome": "Welcome to StudyLyon", "leave.requested": "Leave requested for {days} day(s)." }
Sourcesrc/modules/i18n/i18n.controller.ts:13-17I18nService.getMessages

Locale resolution (server-side, all routes)

Accept-Language: hi-IN, hi;q=0.9 → first tag → strip region → lowercase → whitelist check → ctx.locale (i18n.middleware.ts:13-18). Applied globally (src/app/app.module.ts:139). Read via TenantContextService.getLocale() (src/shared/tenant/tenant-context.service.ts:58-60).


2. Planned endpoints (admin console)

MethodPathPurposeRBAC (planned)Status
GET/api/v1/i18n/keyslist keys + per-locale status (paginated, filter/search)i18n.key.read(planned)
POST/api/v1/i18n/keyscreate key + en sourcei18n.key.create(planned)
GET/api/v1/i18n/keys/:keyone key, all locale values + params + versioni18n.key.read(planned)
PUT/api/v1/i18n/keys/:keyupdate values (params parity enforced)i18n.key.update(planned)
DELETE/api/v1/i18n/keys/:keydelete key in all localesi18n.key.delete(planned)
POST/api/v1/i18n/keys/bulkbulk create/update (import CSV)i18n.key.update(planned)
GET/api/v1/i18n/localeslist locales + coveragei18n.locale.read(planned)
POST/api/v1/i18n/localesadd/promote localei18n.locale.manage(planned)
GET/api/v1/i18n/driftmissing-keys + param-drift reporti18n.locale.read(planned)

Gap: none of the i18n.* permissions exist yet — they must be added to src/modules/rbac/permissions.constants.ts before any console endpoint ships (today: 97 perms, permissions.constants.ts:1-97).


3. Consumer API mapping (server-side translation)

ConsumerMechanismTodaySource
Notificationsevent → hardcoded EN title/bodyEN-only; drift risknotifications.handler.ts:16-31,41-49
Announcement publishAnnouncementPublished event payload titletenant-authored content — not translatedannouncement.service.ts:86-91
Leave requestkey leave.requested with {days} existsno consumer wired yeten.json:9
Error responseserrors.* keys existHTTP filter not yet wired to translate()en.json:3-8
Plannednotifications + errors consume I18nService.translate() with event/user localeIMPLEMENTATION_PLAN.md:171

Interpolation contract (consumers must pass): translate(key, { name: value }){name} replaced; missing params left literal (i18n.service.ts:42-44).

4. Integration surface for the Flutter app

App fetches GET /i18n/messages?locale=<current> → flat map → ARB merge (15_Flutter_Implementation_Guide.md §2). Keep locale list in sync with SUPPORTED_LOCALES (i18n.service.ts:11-21): en, hi, ta, te, kn, ml, gu, mr, bn.