- IDEA.md: product vision from the user's perspective (input for design)
- Architecture, ADRs, data model, REST API overview
- Auth and roles, library storage (NFS, path regexes, scanner, search),
playback, recommendation system ("My Wave"), track upload queue
- Web, Android (offline, self-update), i18n, design system
- Testing strategy, Gitea Actions CI/CD, deployment, conventions, roadmap
- Clickable web/Android design prototypes and wave button variants
- .claude/launch.json to serve the prototypes locally
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
37 lines
3.1 KiB
Markdown
37 lines
3.1 KiB
Markdown
# Локализация
|
||
|
||
## Принципы
|
||
|
||
- Поддерживаемые языки на старте: **ru**, **en**. Язык по умолчанию — язык системы / браузера, если поддерживается, иначе `en`.
|
||
- Выбор языка: на экране входа (сохраняется локально) и в профиле (сохраняется в `users.locale` — синхронизируется между устройствами).
|
||
- **Сервер не возвращает пользовательских текстов**: только машинные коды ошибок и ключи (`activity.running`).
|
||
Исключение — метаданные музыки (названия треков / исполнителей) и changelog релиза; они не переводятся.
|
||
- Добавление языка = добавить папку словаря + строку в список `SUPPORTED_LOCALES`, без изменения кода.
|
||
|
||
## Структура `packages/i18n`
|
||
|
||
```
|
||
packages/i18n/
|
||
├── locales/
|
||
│ ├── ru/ common.json auth.json player.json wave.json collection.json admin.json errors.json
|
||
│ └── en/ ...
|
||
├── src/
|
||
│ ├── index.ts # инициализация i18next, SUPPORTED_LOCALES, детекция
|
||
│ └── types.d.ts # типизация ключей (resources → TS), опечатка в ключе = ошибка компиляции
|
||
└── scripts/check.ts # проверка: все ключи есть во всех языках, нет лишних, плейсхолдеры совпадают
|
||
```
|
||
|
||
- Неймспейсы грузятся лениво (веб — по страницам; админка отдельно).
|
||
- Плюрализация — ICU / i18next plural (`ru` — one / few / many / other): «1 трек», «3 трека», «5 треков».
|
||
- Даты, длительности, числа — `Intl.*` с текущей локалью (`Intl.RelativeTimeFormat` для «вчера», группировка истории по дням).
|
||
- Ошибки API: `errors.json` содержит переводы по `code` с подстановкой `params`
|
||
(`"validation.password_too_short": "Пароль должен быть не короче {{min}} символов"`).
|
||
Неизвестный код → общий текст «Что-то пошло не так» + код в деталях.
|
||
|
||
## Процесс
|
||
|
||
- CI запускает `pnpm i18n:check` — отсутствующий ключ в любом языке ломает сборку.
|
||
- Новые строки сначала добавляются в `en` и `ru` одновременно в том же PR.
|
||
- В будущем — подключение платформы переводов (Weblate, self-hosted) к папке `locales/`, формат JSON совместим.
|
||
- Тесты UI запускаются минимум на двух локалях (длинные русские строки ловят проблемы вёрстки).
|