mirror of
https://github.com/dartdavros/chatballs.git
synced 2026-10-05 09:14:58 +03:00
🌐 feat(i18n): язык интерфейса — русский и английский
Интерфейс был русским в коде: строки лежали прямо в JSX и в ответах API, даты форматировались прибитым «ru-RU», склонение по числу писалось руками в каждом файле. Теперь текста в коде нет — он живёт в словарях, а язык выбирается человеком. Цепочка одна на обе стороны: профиль сотрудника → организация → установка → браузер. Пустое значение на каждом уровне значит «как выше», а не «русский»: тот, кто язык не трогал, поедет за организацией, когда владелец её переключит, а выбравший явно — останется на своём. Владелец задаёт язык организации («Настройки» → «Организация», рядом с часовым поясом) и язык установки («Платформа») — на нём открываются вход, сброс пароля и мастер первого запуска. Сотрудник переопределяет его в профиле. Русский каталог задаёт набор ключей, английский обязан его повторить: во фронтенде это ловит tsc — пропущенный перевод становится ошибкой сборки, — на бэкенде тест каталога, который заодно сверяет имена параметров в фразах. Формы множественного числа берутся из CLDR через Intl.PluralRules, даты и размеры — через Intl, а не через свои списки месяцев. Отдельно пришлось разобраться с тем, что уже записано в базу. Системные события диалога писались готовой русской фразой, и перевести историю задним числом нельзя — теперь пишется код события, а фразу собирает сервер на языке читателя. То же с уведомлениями: они адресованы операторам, а не одному человеку, и в смешанной команде готовая фраза неверна для половины. Тон системной строки в треде и признак анонимного посетителя больше не угадываются регуляркой по русским словам: под английским бэкендом это просто перестало бы работать. Письма уходят на языке получателя, а не отправителя: приглашение отправляет владелец, а читает другой человек. gettext не взят намеренно: .po/.mo потребовали бы msgfmt в сборке образа ради того же результата, что дают обычные словари, одинаковые на обеих сторонах. Язык запроса при этом активируется штатным механизмом Django, поэтому сообщения DRF переводятся тоже. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
f91b3da27a
commit
6c3dec7339
282 files changed
+8185
-2561
No files matched your search
@@ -44,6 +44,14 @@ Engineering rules / обязательные практики:
|
||||
- Не инлайнить сложный UI повторно. Выносить компонент, если структура повторяется или секция имеет отдельную ответственность.
|
||||
- Если реализация по задаче конфликтует с этими правилами, остановиться и явно сообщить blocker вместо поставки плохой структуры.
|
||||
|
||||
Язык интерфейса:
|
||||
- Текста, который видит человек, в коде не бывает. Строка живёт в словаре и подставляется через `t(...)`: во фронтенде это `src/i18n` приложения (`packages/ui` — свой словарь), на бэкенде `chatballs/i18n`. Русский каталог — источник ключей, английский обязан его повторить: пропущенный перевод во фронтенде ловит `tsc`, на бэкенде — тест каталога.
|
||||
- Ключ пишется от смысла, а не от фразы: `settings.storage_bucket_name`, а не пересказ текста. Строку переформулируют чаще, чем переименовывают.
|
||||
- Число не склоняют вручную: формы задаёт словарь, форму выбирает `tn(...)`. Дату, размер файла и разряды числа форматирует `fmt` — прибитые `"ru-RU"` и свои списки месяцев запрещены.
|
||||
- Что записано в базу, переводится по коду, а не текстом: системные события диалога, уведомления и подписи журнала аудита хранят код, а фразу собирает бэкенд на языке читателя. Писать в историю готовую русскую фразу нельзя — её потом не перевести.
|
||||
- Язык запроса выбирается цепочкой: профиль сотрудника → организация → установка → браузер. Письмо получает язык адресата, а не отправителя.
|
||||
- На бэкенде `t(...)` не вызывается на уровне модуля: язык там свой на каждый запрос, а константа посчиталась бы один раз при импорте.
|
||||
|
||||
Definition of Done:
|
||||
- Запускать только тесты, относящиеся к изменениям текущей итерации. Полный прогон всех тестов выполнять только по явному указанию владельца.
|
||||
- Измененные файлы должны быть проверены на NO GOD violations.
|
||||
|
||||
Reference in new issue
Block a user