# Internationalization (i18n) Guide

This consolidated guide explains how i18n works across the repository (Backend API + Cook Web), how to add or modify translations, and how validation is enforced in CI and pre-commit.

## Overview
- Shared, canonical translations live in `src/i18n/<locale>/**/*.json`.
- Every JSON file may use two helpers:
  - `__namespace__`: explicit namespace (recommended)
  - `__flat__`: flat key/value map under that namespace
- Locale metadata and declared namespaces are in `src/i18n/locales.json`.
- Cook Web consumes shared JSON via a lightweight API bridge and i18next; Backend loads the same JSON at startup.

## Directory Structure
- `src/i18n/en-US/**`: English
- `src/i18n/zh-CN/**`: Chinese
- `src/i18n/fr-FR/**`: French
- `src/i18n/locales.json`: Default locale, supported locales, and exported namespaces

## Namespaces & Key Style
- server.<domain>[.<subdomain>].<key>
  - Backend business and error messages. Example: `server.order.courseNotPaid`.
- module.<feature>[.<subfeature>].<key>
  - Frontend module UIs and flows. Example: `module.chat.copySuccess`.
- component.<name>[.<part>].<key>
  - Reusable UI components. Example: `component.header.title`.
- common.core|errors|language
  - Cross-cutting strings. Example: `common.core.submit`.

Key rules
- Dot-separated. Lowercase namespace segments. lowerCamelCase keys.
- Clear, action-oriented names. English-only for keys.
- Avoid positional placeholders; prefer named placeholders with ICU.

## ICU MessageFormat (placeholders)
- Use ICU everywhere to align API and frontend formatting.
  - Variables: `Hello, {name}`
  - Plurals: `{count, plural, one {# item} other {# items}}`
  - Dates/times: `{ts, date, medium}` / `{ts, time, short}`
- Placeholders must match across locales for the same key. Validation enforces this.

## Add or Modify Keys
1) Choose file/namespace
   - Backend: `server.<domain>` (e.g., `server.user`, `server.order`, `server.shifu`)
   - Frontend: `module.*` or `component.*`
2) Edit every supported locale
   - Update `src/i18n/en-US/...`, `src/i18n/zh-CN/...`, and `src/i18n/fr-FR/...`.
3) New namespace?
   - Create it in both locales and ensure it is included in `locales.json` (or run the generator below).

## Validation & CI
Run in repo root:

```bash
python scripts/check_translations.py
python scripts/check_translation_usage.py --fail-on-unused
python scripts/generate_languages.py && git diff -- src/i18n/locales.json
```

Enforced by pre-commit and CI:
- Parity across locales (files and keys)
- ICU placeholders consistency across locales
- No missing or unused keys within declared namespaces
- locales.json matches current files
- Backend guard against hardcoded CJK in Python

## Cook Web Tooling
- i18next with ICU enabled in `src/cook-web/src/i18n.ts`
- Unified fetch backend: `src/cook-web/src/lib/unified-i18n-backend.ts`
- Frontend user-facing locales are exported from `src/i18n/locales.json`
- Optional key typing for developer ergonomics:

```bash
node scripts/generate_i18n_keys.js
# writes src/cook-web/src/types/i18n-keys.d.ts
```

## Backend Usage
- Use `_('server.domain.key')` for server messages; avoid hardcoded strings in code.
- Avoid legacy `module.backend.*` keys; use `server.*` exclusively.

## Scripts Summary
- Validate parity: `python scripts/check_translations.py`
- Validate usage: `python scripts/check_translation_usage.py --fail-on-unused`
- Generate locales metadata: `python scripts/generate_languages.py`
- Create namespace skeleton: `python scripts/create_translation_namespace.py <namespace> [--keys ...]`
- (Cook Web) Generate TS union of keys: `node scripts/generate_i18n_keys.js`

## Migration Notes (Phase 0 decisions, condensed)
- Canonical JSON under `src/i18n/` for all runtimes.
- ICU everywhere; frontend via i18next-icu; backend via Babel-compatible formatting.
- `locales.json` is the single source of truth for locale list + namespaces.
- CI + pre-commit enforce parity, usage, and metadata freshness.
