docs: update plan and backlog

This commit is contained in:
2026-09-13 05:25:56 +05:00
parent 9a27388119
commit abfcbbfac2
2 changed files with 55 additions and 0 deletions
+47
View File
@@ -267,6 +267,53 @@
`scoreDoc()`/`normalizeForSearch()` из `matching.ts` (входит в объём, см.
решение D). Последний шаг, аккуратный отдельный коммит.
### Фаза 8: Линтер словарей (i18n key linter)
Замена ручной проверки ключей на автоматическую. Инфраструктура уже есть:
`eslint-plugins/` умеет читать соседние файлы (`isolation/no-mixed-imports`) и
гоняться фикстурами (`test:rules`).
- **8.1** Новое правило `i18n/dict-consistency` в `web/eslint-plugins/`.
Применяется к файлам-словарям (конвенция: экспортируют `Dict`, лежат в
`lib/i18n/`); новые локали подхватываются автоматически — правка правила не
нужна.
- **8.2** Проверки — **только `warn`, никогда `error`** (пропущенный перевод не
валит сборку):
- **Паритет дерева ключей**: каждый ключ (dot-path `a.b.c`) присутствует во
всех остальных локалях, не только против BASE. Нет —
`missing key "x.y" in en`.
- **Пустые значения**: `""` и строка из одних пробелов —
`empty value "x.y" in en`.
- **Паритет плейсхолдеров**: у одинакового ключа набор `{name}` одинаковый во
всех локалях — поймать потерянную при переводе переменную.
- **8.3** Цель — zero-warn. Сейчас `en.ts` неполный (в `tools` только
результаты-помощники, остальной английский — из реестра), поэтому после
включения будет много warn'ов: доводим `en.ts` до полноты `ru.ts` (секции +
`tools` полностью, source — registry-English, без дрейфа). До достижения цели
допускается allowlist-механизм в ядре правила для осознанных отклонений.
- **8.4** Тесты правила — фикстуры в `web/eslint-plugins/__fixtures__/`, док в
`web/eslint-plugins/README.md`; включение в `eslint.config.js` как `"warn"`.
### Фаза 9: Множественные числа (plural-формы)
- **9.1** Тип значения словаря расширяем: `string | PluralForms`, где
`PluralForms = { other: string } & Partial<{ one, few, many }>` по
CLDR-правилам локали (ru: обязательны `one/few/many`; `other` — всегда, как
фолбэк). Новая функция `tPlural(path, n)` в `lib/i18n/`: выбирает категорию
через `Intl.PluralRules(locale).select(n)` и подставляет её с интерполяцией
`{n}`.
- **9.2** Первые потребители: «часть/части/частей» (split-into-parts-png),
счётчики инструментов (`catalog.toolsCount`), «N параметров», «N файлов».
- **9.3** Паритет в линтере (Фаза 8): если ключ — plural-объект в одной локали,
он обязан быть plural-объектом во всех остальных (тип-паритет; string в одной
из локалей — warn). Набор форм между локалями не сравнивается дословно — он
проверяется по правилам конкретной локали (`other` обязателен; en: one/other,
ru: one/few/many).
- **9.4** Открытый вопрос на этапе реализации: неоднозначность «объект-секция»
(`Record<string, string>`) vs plural-объект в дереве словаря. Варианты:
отдельная секция `plurals` в словаре, конвенция имён ключей, вывод типа из
контекста. Фаза начинается с проработки этого вопроса, не с кода.
## 5. Решения
- **A. Layout groups**: заголовки групп храним i18n-ключами прямо в схеме