Раздел: System
Идентификатор:changelog· Экран:ui/changelog/(6 файлов, ~600 строк)
Снимок: 2026-10-11
1. Зачем и что это
Источник данных — генерируемый из CHANGELOG.md файл app/src/main/assets/changelog.json. То есть в приложение попадает ровно то, что написано в репозитории: отдельной «правки релизов под телефон» не существует.
2. Как попасть
Хаб инструментов → секция System → карточка «Что нового» (hub_changelog_title, подпись «Что изменилось в каждом релизе», тайл — «История»).
| Откуда ещё | Путь |
|---|---|
| Мост | app_navigate с screen: "changelog" |
Маршрут: Screen.kt → MainRouter (ChangelogScreen).
3. Экран: элементы и действия
| Элемент | Что делает |
|---|---|
| Шапка | Промпт и мета: «N releases · A app · B backend» |
| Фильтр по области | All / App / Backend |
| Поиск | По версии и тексту пунктов |
| Список релизов | Карточки по версиям, новые сверху |
| Разделы релиза | [+] Added, [~] Changed, [x] Fixed, [-] Removed, [>] Debug, [↑] Performance, [i] Diagnostics |
| Отметка установленной версии | Релиз, совпадающий с установленным, помечается |
| Локальные даты | Месяцы переводятся на язык интерфейса |
4. Возможности подробно
Генерация JSON
Задача Gradle generateChangelogJson (app/build.gradle.kts:200) парсит CHANGELOG.md построчно:
| Элемент | Регулярка |
|---|---|
| Релиз | ^## \[version\] — дата |
| Раздел | ^### Тип |
| Пункт | ^- текст |
Продолжения пунктов (строки с отступом) склеиваются с предыдущим пунктом — без этого длинные описания молча терялись и в приложении пункт обрывался.
Задача подключена к preBuild, поэтому changelog.json перегенерируется при каждой сборке; файл помечен как output и обновляется только при изменении CHANGELOG.md.
Формат на выходе: [{"version": "...", "date": "...", "sections": [{"type": "Added", "items": ["…"]}]}].
Модель данных
ChangelogEntry(version, date, sections) и ChangelogSection(type, items). Разбор приложением идёт с ignoreUnknownKeys = true, так что лишние поля в JSON не ломают чтение.
Кэш
ChangelogRepository держит разобранный список в поле cached и читает assets один раз за процесс. Ошибка чтения или разбора даёт пустой список, а не падение.
Области релизов
changelogScopeOf определяет область по версии: если она начинается с backend (без учёта регистра) — это релиз backend, иначе — приложения. Заголовок показывает разбивку: «12 releases · 8 app · 4 backend».
Маркеры разделов
Тип в CHANGELOG.md | Маркер |
|---|---|
| Added | [+] |
| Changed | [~] |
| Fixed | [x] |
| Removed | [-] |
| Debug | [>] |
| Performance | [↑] |
| Diagnostics | [i] |
Даты
changelogDisplayDate переводит названия месяцев: берутся два массива ресурсов (исходный и локализованный) и делается замена подстрок. Сделано чистой функцией с параметрами по умолчанию, чтобы тестировать без Android-контекста.
Установленная версия
changelogIsInstalled сравнивает базовую часть версии (до дефиса, без префикса v, в нижнем регистре) с установленной versionName. Отметка ставится только для релизов приложения — у backend нет «установленной версии» в смысле APK.
5. Данные: БД, файлы, настройки
| Что | Где лежит | Как меняется | Кто читает |
|---|---|---|---|
| Исходник | CHANGELOG.md в корне репозитория | Вручную, в коммите | Gradle-задача |
| Данные для приложения | app/src/main/assets/changelog.json | Генерируется при сборке | ChangelogRepository |
| Месяцы | R.array.changelog_months_source / …_localized | Ресурсы | Форматирование дат |
6. Backend: REST/роуты
Неприменимо: changelog полностью статичен и читается из assets приложения.
7. Мост и MCP
| Что | Как | Примечание |
|---|---|---|
| Открыть экран | app_navigate с screen: "changelog" | BridgeScreenCatalog |
| Прочитать changelog | file_read (профиль /mcp) на CHANGELOG.md | Агенту нужен исходник, а не JSON |
8. Настройки, конфиг, квоты и лимиты
| Параметр | Значение | Где задаётся |
|---|---|---|
| Формат заголовка | ## [version] — дата | Регулярка в Gradle-задаче |
| Формат раздела | ### Тип | То же |
| Формат пункта | - текст | То же |
| Типов разделов | 7 | changelogSectionMarker |
9. Ловушки и ограничения
- Формат
CHANGELOG.mdжёсткий. Заголовок другого вида (## 0.8.131 — 01.11.2026без скобок) не распарсится, и релиз просто не появится. - Тип раздела должен быть одним словом (
### Added, не### Добавлено), иначе маркер будет[~]по умолчанию. - Файл большой (~390 КБ JSON). Он лежит в assets и читается один раз за процесс, но попадает в APK целиком.
- Кэш живёт только в процессе. После перезапуска приложения файл читается заново.
- Пометка «установлено» работает только для app-релизов и сравнивает базовую часть версии — сборка с суффиксом даты (
0.8.131-261011) считается той же версией, что и0.8.131. - Месяцы переводятся заменой подстрок, поэтому нестандартный формат даты останется как есть.
- Файл генерируется, поэтому ручные правки
changelog.jsonпропадут при следующей сборке.
10. Источники правды
app/src/main/java/com/y83/ws/ui/changelog/ChangelogScreen.kt— экран, фильтры, поиск.app/src/main/java/com/y83/ws/ui/changelog/ChangelogCards.kt— карточки релизов и разделов.app/src/main/java/com/y83/ws/ui/changelog/ChangelogFormat.kt— форматирование, маркеры, даты.app/src/main/java/com/y83/ws/ui/changelog/ChangelogRepository.kt— чтение assets и кэш.app/src/main/java/com/y83/ws/ui/changelog/ChangelogViewModel.kt— состояние.app/build.gradle.kts:200–264— задачаgenerateChangelogJsonи её подключение кpreBuild.CHANGELOG.md— источник истины по изменениям.