From 42b3aa09a7c79ad2dc3d1f5b2912bd2dc0c30728 Mon Sep 17 00:00:00 2001 From: Codex Date: Mon, 2 Nov 2026 23:40:45 +0300 Subject: [PATCH 1/9] Consolidate product and deployment roadmap docs --- .gitignore | 5 + DESIGN.md | 34 +- README.md | 13 +- backend/README.md | 4 +- docs/README.md | 10 +- docs/product/frontend-pixel-perfect-plan.md | 355 -------------------- docs/product/implementation-roadmap.md | 340 +++++++++++++++++++ docs/product/interface-correction-plan.md | 334 ------------------ 8 files changed, 380 insertions(+), 715 deletions(-) delete mode 100644 docs/product/frontend-pixel-perfect-plan.md create mode 100644 docs/product/implementation-roadmap.md delete mode 100755 docs/product/interface-correction-plan.md diff --git a/.gitignore b/.gitignore index 8a49b9c..f2b7c1b 100755 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ # Local credentials and secrets credentials.json +codex.json # Python/runtime artifacts (for the upcoming bot implementation) __pycache__/ @@ -17,3 +18,7 @@ data/ # Local runtime logs logs/ + +# Local benchmark and scratch output (historical tracked evidence remains tracked) +/reports/ +/tmp/ diff --git a/DESIGN.md b/DESIGN.md index 49d4edc..b008e01 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -66,10 +66,11 @@ spacing: ## Overview -**Статус: утверждено пользователем 10 октября 2026 года.** Это целевая +**Статус: утверждено пользователем 10 октября 2026 года.** Это нормативная дизайн-система портала и внутренней лаборатории проверки поисковой выдачи. -Она ещё не внедрена в работающий интерфейс. Утверждение дизайна не означает -готовность публичного сервиса или разрешение на deployment. +Часть ресурсов и правил уже присутствует в исходном коде, но полное визуальное +соответствие и доступность не подтверждаются одним наличием кода. Утверждение +дизайна не означает готовность публичного сервиса или разрешение на deployment. **Creative North Star: "Түндүк — спокойное пространство для работы с правом".** @@ -80,20 +81,14 @@ spacing: Это единственная нормативная спецификация дизайна проекта. Требования исходного brief перенесены сюда; отдельный brief и ранние варианты удалены. -Визуальный ориентир — утверждённый пользователем -[концептуальный экран](docs/design/tunduk-desktop-concept.png). -Точные токены и правила этой спецификации важнее случайных деталей -генеративного изображения. Название продукта — **Акылдаш**; «УКУК» из -ранних концепций не используется. +Название продукта — **Акылдаш**; «УКУК» из ранних концепций не используется. -Изображение определяет целевую композицию, пропорции панелей и расположение -элементов поискового экрана. Эта спецификация определяет семантические токены, -шрифты, доступность и правила поведения. Расхождения между ними фиксируются -до реализации; утверждённые токены не заменяются цветами, взятыми пипеткой -из растрового изображения. Изменения постоянных правил вносятся сюда явно. -Этапы работ, исходные измерения и критерии визуальной приёмки находятся в -[едином плане корректировки UI/UX](docs/product/interface-correction-plan.md). -План не является второй дизайн-системой и не означает завершение реализации. +Целевые редактируемые состояния, композиция, измерения и критерии приёмки +собраны в [плане реализации и приёмки](docs/product/implementation-roadmap.md). +Макеты задают визуальное направление, но не источник юридических данных и не +доказательство работающих функций. Утверждённые токены не заменяются цветами, +взятыми пипеткой из растрового изображения. Изменения постоянных правил +вносятся сюда явно. **Key Characteristics:** @@ -141,8 +136,11 @@ spacing: **Заголовки документа и разделов:** Noto Serif, веса 600 и 700. **Интерфейс и основной текст:** Noto Sans, веса 400, 500 и 600. Шрифты подключаются штатным способом, предпочтительно локальными WOFF2 -с `font-display: swap`. До поставки проверить лицензии и символы -`Ө ө Ү ү Ң ң`. Файлы шрифтов пока не добавлены. +с `font-display: swap`. В исходном коде на сверенном `main` есть локальные +Noto Sans/Serif WOFF2 и OFL-лицензии в `backend/search/static/fonts/`; +`review.html` объявляет `font-display: swap`. Это подтверждает наличие ресурсов +и CSS, но не их загрузку на production и не полный визуальный аудит символов +`Ө ө Ү ү Ң ң`. См. [план реализации и приёмки](docs/product/implementation-roadmap.md). | Элемент | Размер | Межстрочный интервал | |---|---|---| diff --git a/README.md b/README.md index b5ec8c2..d5a9a75 100644 --- a/README.md +++ b/README.md @@ -9,18 +9,21 @@ Telegram-бот — только часть рабочего окружения ## Текущее состояние -Сейчас реализованы Telegram-бот-секретарь версии `0.2.2`, backend версии -`0.13.2` и frontend `0.3.3` с поисковым экраном, внутренней лабораторией и +В исходном коде находятся Telegram-бот-секретарь версии `0.2.2`, Search API +версии `0.13.3` и frontend `0.3.3` с поисковым экраном, внутренней лабораторией и согласованным отображением доступных действий учетной записи. Авторизация хранится в SQLite; первый пользователь `admin` создаётся интерактивной CLI-командой. Поиск расширяет аббревиатуры организационно-правовых форм и поднимает действующий Налоговый кодекс для запросов о налоге на прибыль. +Версии описывают код, а не установленный production-релиз; актуальное +подтверждённое состояние среды см. в +[`docs/operations/CURRENT_STATE.md`](docs/operations/CURRENT_STATE.md). | Компонент | Версия | Состояние | |---|---:|---| -| Telegram-бот | `0.2.2` | на Synology работает `0.2.1`; обновление после слияния | -| Backend | `0.13.2` | авторизация, серверная capability управления пользователями, поиск и статические ресурсы | +| Telegram-бот | `0.2.2` | исходный код; последняя заметка о Synology указывает `0.2.1`, актуальность не перепроверена | +| Search API | `0.13.3` | авторизация, серверная capability управления пользователями, поиск и статические ресурсы | | Frontend | `0.3.3` | поиск по правовой базе, просмотр редакций, внутренняя лаборатория и контекстная навигация кабинета | | Сбор и обработка правовых данных | `0.8.0` | добавлены relevance set и оценка выдачи | | RAG и база знаний | — | ещё не созданы | @@ -64,4 +67,4 @@ python3 -m unittest discover -s tools/telegram-bot -v --- -Акылдаш · Telegram-бот v0.2.2 · Backend v0.13.2 · Frontend v0.3.3 +Акылдаш · Telegram-бот v0.2.2 · Backend v0.13.3 · Frontend v0.3.3 diff --git a/backend/README.md b/backend/README.md index d7e7e88..3e7ae87 100644 --- a/backend/README.md +++ b/backend/README.md @@ -1,6 +1,6 @@ # Backend Акылдаш -Версия: `0.13.0` +Версия загрузчика `minjust_cbd.py`: `0.9.3` Первая backend-область проекта — загрузка правовых документов из официального Open Data API ЦБД Минюста Кыргызской Республики. Код расположен в @@ -311,4 +311,4 @@ PYTHONPATH=backend python3 -m search.query "ЖЧК ачуу тартиби" --la --- -Акылдаш · Backend v0.13.0 · Frontend v0.2.3 +Акылдаш · Search API v0.13.3 · Frontend v0.3.3 · Telegram-бот v0.2.2 diff --git a/docs/README.md b/docs/README.md index ccf9151..32b152e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -6,10 +6,15 @@ типографика, компоненты и правила адаптивности портала и лаборатории. - [Обзор проекта](product/project-overview.md) — назначение, основные области и правила работы с данными. +- [Стратегическое сравнение с Токтом](product/platform-development-plan-toktom-2026-10-24.md) — + продуктовая гипотеза и конкурентный анализ; это не план исполнения задач. - [План frontend поисковой СПС](product/frontend-search-sps-plan.md) — границы MVP, зависимости и спринты. - [Готовность к проектированию frontend](product/frontend-design-readiness-plan.md) — обязательные работы и критерии перехода к frontend. +- [План реализации и приёмки](product/implementation-roadmap.md) — единая + очередность UI и deployment gates, со статусом доказательств; не дублирует + продуктовую стратегию или эксплуатационные процедуры. - [План интерфейса оценки поисковой выдачи](product/search-relevance-review-interface-plan.md) — внутренняя лаборатория сбора оценок юристов для настройки OpenSearch. - [Разметка relevance set](../backend/search/RELEVANCE_ANNOTATION.md) — подготовка @@ -30,6 +35,9 @@ состояние production и оставшиеся проверки. - [Инфраструктура и эксплуатация](operations/INFRASTRUCTURE.md) — схема, доступы, deployment, backup, rollback и recovery. +- [Операционные процедуры](operations/DEPLOYMENT.md) — связанные инструкции по + deployment, [backup](operations/BACKUP.md), [rollback](operations/ROLLBACK.md), + [recovery](operations/RECOVERY.md) и [пакет владельца](operations/DEPLOYMENT_OWNER_PACKET.md). - [План Telegram-пространства](operations/telegram-workspace-plan.md) — темы, роли и этапы развития командного окружения. @@ -45,4 +53,4 @@ --- -Акылдаш · Telegram-бот v0.2.2 · Backend v0.13.0 · Frontend v0.2.3 +Акылдаш · Telegram-бот v0.2.2 · Backend v0.13.3 · Frontend v0.3.3 diff --git a/docs/product/frontend-pixel-perfect-plan.md b/docs/product/frontend-pixel-perfect-plan.md deleted file mode 100644 index 9f4cdbd..0000000 --- a/docs/product/frontend-pixel-perfect-plan.md +++ /dev/null @@ -1,355 +0,0 @@ -# План точного воспроизведения поискового интерфейса - -Дата: 23 октября 2026 года. - -Статус: основная реализация и локальная приёмка выполнены в -`feature/frontend-pixel-perfect`; после первичного прогона скорректированы -навигация, плотность результатов, заголовок документа, fixture-контент, -клавиатурный trap для диалогов и компактные позиционируемые подсказки -лаборатории. Скриншоты, покропленные сравнения и расширенный -Playwright-сценарий находятся в репозитории; см. [отчёт](visual-review/README.md). -Локальные тесты и guards из CI прошли. Ожидают runner: проверки Compose/Caddy и -сборка production images. Независимый review запускает владелец. Скринридер и -реальный корпус всё ещё требуют проверки. - -## 1. Цель, границы и источники истины - -Привести существующую авторизованную поисковую страницу `/` к композиции -утверждённого изображения «Акылдаш · Түндүк», сохранив реальные API, -авторизацию, безопасность и отдельный сценарий лаборатории `/review`. - -Источники: - -- [DESIGN.md](../../DESIGN.md) — единственная нормативная дизайн-система: - токены, типографика, доступность, постоянные правила компонентов. -- [Исходный концепт](../design/tunduk-desktop-concept.png) — визуальный - эталон композиции. Вложение пользователя 1280×800 визуально соответствует - этому сохранённому изображению более высокого разрешения. -- [План frontend СПС](frontend-search-sps-plan.md) — продуктовый контекст. -- [Readiness plan](frontend-design-readiness-plan.md) — отдельные условия - готовности публичного продукта, которые этот план не отменяет. - -Изображение задаёт композицию и пропорции; `DESIGN.md` задаёт токены, -шрифты и ограничения. До реализации фиксировать расхождения, а не молча -изменять палитру, шрифты или доступность ради совпадения растровых пикселей. -Временные задачи и результаты измерений остаются здесь; новые постоянные -правила добавляются в `DESIGN.md` без копирования всей дизайн-системы. - -Не входят: публичный запуск, изменение прав доступа, ранжирования, корпуса, -индекса, production, регистрация, аналитика, сравнение редакций, переход -на новый frontend framework. Содержимое демонстрационного документа -не становится юридическими данными продукта. - -Figma не является обязательной зависимостью: сохранённого эталона достаточно. -При необходимости совместного редактирования можно подготовить отдельный -Figma-макет с Auto Layout и переменными, ссылающийся на эти же правила; -это не заменяет проверку фактической вёрстки в браузере. - -## 2. Исходное состояние до реализации - -Таблица ниже фиксирует базовую проверку до реализации, выполненную по коду и -изображениям без браузера; строки не описывают текущее состояние. Последующие -результаты Playwright сохранены в [отчёте визуальной приёмки](visual-review/README.md). -Они относятся к локальному UI со стабильными fixture-ответами и не подтверждают -состояние production или актуального OpenSearch. - -Основные файлы: - -- `backend/search/review.html` — разметка, встроенные CSS и JavaScript обоих - сценариев, footer и авторизация. -- `backend/search/api.py` — выдача страницы для `/` и `/review`, API поиска, - фильтров и редакций. -- `backend/test_search_api.py` — существующие проверки API. -- `.gitea/workflows/ci.yaml` — обязательные проверки и сборка образов. - -| Проблема | Подтверждение в реализации | Требуемый результат | -|---|---|---| -| Другая шапка | Общая `.review__header`, поиск отдельной формой ниже | Бренд, поиск и язык в одной верхней строке | -| Нет второй строки эталона | Нет общей полосы навигации и активных фильтров | Навигация и удаляемые фильтры под шапкой | -| Другие пропорции | `.search__layout`: `230px / .9fr / 1.2fr`, `min-height: 65vh` | Измеренная сетка и корректная высота рабочей области | -| Не тот вид фильтров | Все справочники выводятся radio-списками, даты вертикально | Компактные группы, select органа, даты рядом | -| Выбранный результат неполон | Есть только фоновое выделение | Фон, рамка, подпись «Открыт», точные отступы | -| Неполная панель документа | Есть заголовок, select редакции/языка, метаданные и текст | Полная иерархия и работающие действия эталона | -| Смешаны стили документа | Объявлен `.search__document-body`, статья использует `.review__document-body` | Одна корректная область стилей поискового документа | -| Шрифты не поставляются | Noto указаны в CSS, локальные файлы не найдены | Проверенная загрузка локальных шрифтов | -| Нет фирменных ресурсов | Знак сделан CSS-кружком; орнамент и favicon отсутствуют | SVG-знак, орнамент, favicon | -| Лабораторная панель на поиске | `.review__actions` вне скрываемого `
`; для `/` не скрывается | Оценивание только на `/review` | -| Счётчик вводит в заблуждение | Выводится `payload.results.length`; API не возвращает total | Явное число на странице либо отдельно реализованный total | -| Нет визуального контроля | Найденные тесты проверяют API, не геометрию страницы | Воспроизводимые браузерные снимки и сравнение | - -Это исходное описание состояния до реализации. Сейчас переключатель RU/KY, -отдельный язык поиска, реальные редакции и язык документа, оглавление, поиск -по тексту документа, разворачивание, печать и отдельный маршрут `/review` -реализованы. Подробности текущей локальной приёмки и её ограничения приведены -в [отчёте](visual-review/README.md); оставшиеся непроверенные состояния не -считаются принятыми только потому, что чекбоксы плана перечислены ниже. - -## 3. Этап 0 — воспроизводимый эталон - -- [x] Перед реализацией перечитать актуальные инструкции, `DESIGN.md`, - реализацию маршрутов и обязательные проверки; использовать установленный - Ponytail согласно правилам репозитория. -- [x] Сохранить чужие незакоммиченные изменения, создать тематическую - `feature/` ветку и не переносить посторонние изменения в PR. -- [x] Зафиксировать основной viewport 1280×800 CSS px, браузер и его версию, - ОС, масштаб 100%, device scale factor и остальные viewport в отчёте. -- [ ] Получить исходный снимок текущего интерфейса на тех же размерах. -- [x] Подготовить детерминированные тестовые данные: запрос «налог на прибыль», - три результата из изображения, выбран первый, открыта соответствующая - демонстрационная редакция, фильтр статуса и исходная прокрутка. -- [x] Изолировать fixture от реального режима и пометить демонстрационное - содержимое только в тестовом сценарии. Не добавлять подмену юридических данных - в production-путь. -- [x] Нормализовать сохранённое изображение до 1280×800 без изменения - пропорций и сохранить параметры подготовки эталона. -- [x] Записать конфликты изображения с нормативной типографикой и токенами; - согласованные ограничения приведены в отчёте. - -Критерий завершения: один и тот же тестовый сценарий воспроизводится -независимо от состояния OpenSearch и текущей реальной выдачи; реальный режим -продолжает использовать API. Авторизация не ослабляется ради снимков. - -## 4. Этап 1 — карта геометрии - -Эталон 1586×992 пропорционально вписан в 1280×800; фактические значения -сверены с Playwright при device scale factor 1. Допуск границ крупных зон — -около 1 CSS px. - -| Область | Нормализованный эталон | Реализация | -|---|---:|---:| -| Шапка и строка навигации | y ≈ 0–126 px | y = 0–127 px | -| Рабочая область | y ≈ 126–744 px | y = 127–744 px | -| Footer | y ≈ 744–800 px | y = 744–800 px | -| Фильтры | x ≈ 0–226 px | x = 0–226 px | -| Результаты | x ≈ 226–648 px | x = 226–648 px | -| Документ | x ≈ 648–1280 px | x = 648–1280 px | - -Внутренние контрольные координаты и ограничения см. в -[отчёте визуальной приёмки](visual-review/README.md); там же есть overlay и -разница по каждой крупной области. - -- [x] Измерить крупные границы, основную навигацию и ключевые элементы - документа по исходнику; фактические значения записаны в отчёте. -- [ ] Измерить все внутренние отступы, размеры полей и кнопок, межстрочные - интервалы и разделители по всем областям. -- [x] Зафиксировать адаптивные точки и проверить сетку на 1440/1024/390/320 px; - реальные длинные данные ещё не проверены. -- [ ] Разделить метрики повторяемых элементов и высоты, зависящие от текста. - Не выравнивать принудительно высоту всех результатов или разделов. -- [ ] Определить владельца прокрутки каждой области, поведение footer - при коротком содержимом и доступность длинного документа. - -Критерий завершения: геометрия описана измерениями и адаптивными правилами, -а не независимыми приблизительными настройками каждого блока. - -## 5. Этап 2 — разделение сценариев и базовых стилей - -- [x] Разделить композиции поиска и лаборатории, сохранить маршруты, - авторизацию, кабинет, управление пользователями, обучение и черновики. -- [x] Ограничить лабораторные элементы маршрутом `/review`, включая - панель проверяющего и сохранения; маршрут проверен браузерным тестом. -- [ ] Использовать общий слой семантических токенов и базовых элементов; - стили поискового экрана изолировать BEM-классами. -- [ ] Устранить дублирующие и неиспользуемые правила, исправить класс статьи. -- [ ] Убрать зависимость шапки и footer поиска от лабораторного layout. -- [ ] Если CSS/JS/ресурсы выносятся из HTML, добавить ограниченную выдачу - static-файлов с MIME, защитой от обхода путей и сохранением защитных - заголовков. Убедиться, что ресурсы входят в production-образ. - -Ожидаемые зоны изменений: `backend/search/review.html`, при необходимости -каталог static-ресурсов рядом с ним и `backend/search/api.py`. -Не вводить Next.js, React или новый сборщик только ради этой задачи. - -Критерий завершения: оба сценария работают независимо, общие CSS не меняют -их композицию случайным образом; существующие права доступа сохранены. - -## 6. Этап 3 — шрифты, знак, орнамент и favicon - -- [ ] Поставить локальные WOFF2 Noto Sans 400/500/600 и Noto Serif 600/700 - с лицензиями; исключить случайное синтетическое начертание. -- [x] Проверить загрузку, `font-display`, кириллицу и `Ө ө Ү ү Ң ң`. - Визуальные снимки выполнять после `document.fonts.ready`. -- [ ] Подготовить SVG-знак по визуальному направлению референса; - сверить размер, толщину линий и положение относительно названия. -- [ ] Подготовить отдельный симметричный золотистый SVG-орнамент, - `aria-hidden`, без перекрытия управления и текста. -- [x] Подготовить favicon SVG и растровый fallback 32×32; подключить - в ``, проверить выдачу и MIME. Масштабирование SVG проверено визуально. -- [ ] Подготовить единые SVG-иконки поиска, очистки, календаря, печати, - оглавления, разворачивания и стрелок; иконкам-кнопкам дать доступные имена. -- [ ] Перенести значения в токены, не размножать HEX по компонентам. - -Критерий завершения: шрифты реально загружены, знак и орнамент являются -ресурсами, favicon отображается; нет CSS-заглушек вместо фирменной графики. - -## 7. Этап 4 — сборка композиции - -Работать от крупных областей к деталям; сначала геометрия, затем типографика. - -- [ ] Шапка: знак, название, разделитель, подпись продукта, поле с подписью - и очисткой, «Найти», язык интерфейса. Служебные действия доступны компактно. -- [ ] Вторая строка: «Поиск», «Об источниках», удаляемые фильтры; - демонстрационная подпись только для fixture. «Об источниках» открывает - реальные сведения о происхождении данных, а не пустую заглушку. -- [ ] Три панели: непрерывные границы, правильные фоны и пропорции, - отсутствие лишнего свободного ряда статуса в стабильном состоянии. - Сообщения для скринридера сохраняются. -- [ ] Фильтры: заголовок, текстовый сброс, статус, вид, орган, даты рядом, - орнамент в свободной нижней части без перекрытия длинного содержимого. -- [ ] Результаты: заголовок и честный счётчик, компактная сортировка, - строки выдачи, выбранная строка с рамкой/фоном/«Открыт», метаданные, - безопасная подсветка выдержки, пагинация. -- [ ] Документ: breadcrumbs и разворачивание, отдельная роль заголовка, - компактные метаданные, язык, действия, поиск внутри, поле чтения. -- [ ] Footer: бренд слева, фактические версии frontend/backend справа; - не копировать устаревшую backend-версию и слово «макет» из изображения. - -Критерий завершения: порядок, вложенность и пропорции всех крупных зон -соответствуют эталону; нет лишних лабораторных блоков. - -## 8. Этап 5 — рабочее поведение и интеграция - -- [ ] Сохранить поиск, сортировку, пагинацию, загрузку редакций и языков. -- [x] Синхронизировать фильтры с URL и удалять отдельный фильтр без сброса - остальных; сохранение второго фильтра проверяется Playwright. -- [ ] Проверить восстановление и историю навигации через прямые ссылки и Back/Forward. -- [ ] Согласовать вид фильтров с контрактом: текущий API принимает одиночные - значения. Не имитировать множественный выбор checkbox без поддержки API. - Если нужен multiselect, отдельно описать и проверить расширение контракта. -- [ ] Разделить язык интерфейса, поиска и текста документа. Для RU/KY - перевести подписи, статусы и ошибки; смена UI не подменяет текст редакции. -- [ ] Не выдавать число на странице за общее: использовать явную подпись - либо отдельно реализовать достоверный total с проверкой его семантики. -- [ ] Построить оглавление по реальным заголовкам, с корректными якорями; - при отсутствии структуры показать понятное состояние. -- [ ] Реализовать поиск по текстовым узлам документа: ввод/очистка, - подсветка, активное совпадение, счётчик, предыдущий/следующий, - прокрутка и состояние нулевого результата. Не повреждать HTML, - ссылки и таблицы; не вставлять пользовательский запрос через `innerHTML`. -- [ ] Реализовать разворачивание/возврат с сохранением выбранной редакции, - прокрутки и корректного фокуса. -- [x] Добавить печать через print CSS: документ, его реквизиты и источник - без поисковых и служебных панелей; служебные элементы проверены в print media. -- [ ] Защитить смену запроса/документа/редакции от запоздавших ответов - через отмену запроса или проверку актуальности результата. -- [ ] Сохранить безопасный вывод очищенного документного HTML и ссылок, - обработку ошибок и ограничения авторизации. - -Критерий завершения: каждый видимый элемент эталона выполняет действие; -нет декоративных кнопок, фиктивных языков и выдуманных юридических статусов. - -## 9. Этап 6 — адаптивность, типографика и состояния - -- [ ] Настроить размеры, веса, line-height и отступы после фиксации сетки. - Сверить переносы названия документа, результатов и плотность абзацев. -- [x] Проверить 1280×800 и ширины 1440/1024/390 px; дополнительно 320 px. - Высоты и параметры окружения записаны в отчёте. -- [ ] Проверить реальные длинные редакции, длинные названия на RU/KY и подобрать - breakpoints на реальных данных корпуса. -- [x] На узких экранах открывать фильтры отдельной доступной панелью, - документ — отдельным представлением с возвратом к результатам; проверено на 390 px. -- [x] Сокращать/убирать орнамент на телефоне; сохранять текст без - горизонтальной прокрутки, широкие таблицы — в собственной области прокрутки. - Проверено синтетической широкой таблицей; реальные таблицы корпуса остаются открыты. -- [x] Проверить длинные названия, отсутствие редакций, широкую таблицу и - широкое изображение синтетическими данными. -- [ ] Проверить одноязычные реальные редакции, ссылки, много фильтров и - длинный контент из реального корпуса. -- [x] Проверить загрузку редакции, empty, search/edition error, retry, - disabled-состояние без редакции и focus-visible; query сохраняется при ошибке. -- [ ] Проверить hover и сценарии ошибок авторизации/администрирования. -- [x] Проверить Tab/Shift+Tab/Escape, возврат фокуса мобильной панели и - диалогов, а также `prefers-reduced-motion`. -- [ ] Проверить доступные имена всех элементов, live-сообщения, контраст, - масштабирование, скринридер и touch-области на поддерживаемых устройствах. - -Критерий завершения: точность desktop не приводит к переполнению, -недоступности действий или потере контекста на узком экране. - -## 10. Этап 7 — визуальная приёмка - -Выполнить один пакет первичных снимков всех контрольных размеров, -собрать дефекты по областям, исправить одним пакетом и выполнить один -подтверждающий проход. Новые циклы обосновывать конкретными оставшимися -дефектами или замечаниями независимого reviewer, не бесконечной полировкой. - -- [x] Дождаться шрифтов и стабильных fixture-данных, задать исходную - прокрутку; снимки делаются после `document.fonts.ready`. -- [x] Проверить, что снимки показывают загруженный поисковый сценарий, а не - login, ошибку или другой маршрут. -- [x] Для 1280×800 подготовить overlay 50%, difference image и отдельные - сравнения шапки, фильтров, результатов, документа и footer. -- [x] Сохранить снимки остальных размеров и отчёт с условиями, отклонениями, - исправлениями и известными ограничениями. -- [ ] Передать независимому reviewer запрос пользователя, эталон, - `DESIGN.md`, этот план, diff и снимки всех проверенных размеров. - -Критерии для детерминированного fixture при 1280×800: - -| Проверка | Условие приёмки | -|---|---| -| Границы крупных зон | Отклонение от зафиксированной карты до 2 CSS px | -| Отступы и размеры управления | Отклонение до 2 CSS px от измерений | -| Ключевые заголовки | Совпадают переносы при согласованных шрифтах; исключения объяснены | -| Композиция | Все зоны и элементы эталона присутствуют, порядок совпадает | -| Ресурсы | Загружены шрифты, знак, орнамент, favicon, единые иконки | -| Рабочий сценарий | Поиск, фильтры, редакции, действия и навигация работают | -| Адаптивность | Нет перекрытий, обрезанного управления и общей горизонтальной прокрутки | -| Изоляция | Нет лабораторного оценивания на поиске, `/review` без регрессий | - -Нулевая попиксельная разница не является критерием: сглаживание текста, -растровая природа концепта и нормативные токены дают объяснимые различия. -Один процент сходства всего экрана не заменяет проверки каждой области. -Достижение допусков подтверждается измерениями, а не общей оценкой «похоже». - -## 11. Этап 8 — проверки, версия и PR - -Этот этап относится к реализации в feature-ветке. Frontend повышен до `0.2.3`, -backend — до `0.13.0` для allowlist-выдачи локальных шрифтов. Контракт Search -API v1 не менялся. - -- [x] Выполнить доступные локально проверки из `AGENTS.md` и CI: backend, - Telegram bot, backup, deploy, host/root/verifier/audit/Compose/production - config/runner guards, shell syntax и Playwright. -- [ ] Получить успешный CI на назначенном runner: `docker compose config`, - проверка Caddyfile и сборка backend/OpenSearch production images. -- [x] Добавить проверки фактических изменений: static/favicon, браузерные - сценарии поиска/редакций/поиска внутри/навигации и регрессии лаборатории; - визуальное сравнение использует стабильный fixture. -- [x] Повысить версии для совместимого функционального изменения; - frontend/backend версии согласованы в footer. -- [x] Выполнить push и найти существующий PR ветки через `gitea-api`; - изменения остаются в одном PR #53. -- [ ] После каждого push независимый reviewer проверяет полный текущий PR, - прежние исправления и оставляет краткий PR-комментарий с явным выводом - о наличии или отсутствии блокирующих замечаний; reviewer не редактирует код. -- [ ] Исправить обоснованные замечания в той же ветке/PR, повторить проверки, - commit/push и независимый review. -- [ ] После успешных проверок и устранения блокирующих замечаний обновить - существующий changelog, записав значимые изменения для пользователя. -- [ ] Commit/push changelog в тот же PR, повторить обязательные проверки - и независимый review окончательного состояния. - -Готовность к merge: проверки проходят, финальный review не содержит -блокирующих замечаний, changelog и версии согласованы, визуальные доказательства -доступны reviewer. Не сливать автоматически и не развёртывать production. - -## 12. Порядок выполнения и итоговые материалы - -Зависимости: эталон → измерения → разделение сценариев → ресурсы → композиция -→ поведение → адаптивность и состояния → визуальная приёмка → финальный PR. -Не начинать микроподгонку кнопок до исправления общей геометрии. - -Ожидаемые материалы реализации: - -- обновлённая поисковая страница и сохранённый сценарий лаборатории; -- локальные шрифты с лицензиями, SVG-знак, орнамент, favicon и иконки; -- детерминированный тестовый сценарий и воспроизводимый способ снимков; -- карта измерений, снимки, overlay/diff и отчёт приёмки; -- результаты обязательных проверок и независимого review; -- версии, changelog и один PR без автоматического merge. - -Чекбоксы отмечать только после выполнения и проверки. Локальные проверки, -которые реально выполнены, зафиксированы в отчёте visual-review. -Этот документ не подтверждает готовность API, публичного продукта или -production. diff --git a/docs/product/implementation-roadmap.md b/docs/product/implementation-roadmap.md new file mode 100644 index 0000000..7ac9a74 --- /dev/null +++ b/docs/product/implementation-roadmap.md @@ -0,0 +1,340 @@ +# План реализации и приёмки Акылдаш + +Дата актуализации: **2 ноября 2026 года**. Основа сверки: `main` на +`7ece39f212b67e497a8dfb360d5d271ab088ef57`. Это единый план работ по продукту, +интерфейсу и переходу к production. Он не заменяет эксплуатационные runbooks +и не подтверждает состояние живого сервиса. + +## 1. Статус и границы достоверности + +Различаем три вида сведений: + +- **В коде** — наличие исходного кода на указанном commit; это не доказывает, + что функция развёрнута или доступна пользователям. +- **Историческое наблюдение** — результат конкретного аудита, дата и пределы + которого указаны рядом. Оно не является повторной проверкой текущего сайта. +- **Цель / gate** — требование, которое нужно выполнить и подтвердить до + следующего этапа. + +На сверенном commit источники кода показывают Backend `0.13.3` +(`backend/search/minjust_opensearch.py`), Frontend `0.3.3` +(`backend/search/review.html`) и Telegram-бот `0.2.2` +(`tools/telegram-bot/bot.py`). Это версии исходного кода, а не подтверждение +установленных production-версий. В этом PR согласованы версии в корневом и +общем документационном README; `backend/README.md` отдельно называет версию +загрузчика `minjust_cbd.py` (`0.9.3`). При новых изменениях сверять версию +компонента с соответствующим исполняемым кодом. + +В Search API и frontend реализованы поиск RU/KY, фильтры, карточка документа, +редакции, поиск в тексте, внутренняя лаборатория, вход и административные +действия. В коде также есть локальные Noto Sans/Serif с лицензиями, favicon и +встроенный SVG-знак бренда. Наличие файлов и ссылок в HTML не подтверждает, +что они загрузились в live-браузере. Результаты браузерной проверки приведены +только в [отчёте визуальной приёмки](visual-review/README.md). + +Production readiness не следует из наличия Compose, release workflow или +deploy-кода. Подтверждённое состояние и ограничения находятся в +[CURRENT_STATE.md](../operations/CURRENT_STATE.md); статус релиза — в +[DEPLOYMENT.md](../operations/DEPLOYMENT.md), ограничения backup/restore — в +[BACKUP.md](../operations/BACKUP.md), rollback — в +[ROLLBACK.md](../operations/ROLLBACK.md), аварийное восстановление — в +[RECOVERY.md](../operations/RECOVERY.md). Этот план не повторяет команды из +этих runbooks. + +## 2. Очерёдность работ + +### 2.1 Продукт и качество правовых данных + +1. Поддерживать воспроизводимое получение и нормализацию официальных + правовых материалов с сохранением источника, редакции и контрольных сумм. +2. Подтвердить полноту и актуальность RU/KY корпуса, правила для отсутствующих + текстов и одноязычных редакций; не выдумывать перевод или реквизиты. +3. Развивать замороженный relevance set и измерять качество на одной и той же + выборке до и после изменений ранжирования. +4. Развивать версионируемые API и справочники, сохраняя совместимость + существующих клиентов. +5. Публичный frontend, персональные функции и RAG остаются отдельными + продуктовыми решениями и readiness gates. Сверяться с [обзором проекта](project-overview.md), + [планом frontend](frontend-search-sps-plan.md) и +[готовностью публичного frontend](frontend-design-readiness-plan.md). Конкурентная +гипотеза и сегмент рынка отдельно описаны в +[стратегическом сравнении с Токтом](platform-development-plan-toktom-2026-10-24.md). + +### 2.2 Интерфейс: датированный реестр UI-01—UI-33 + +Реестр ниже сохраняет исходные наблюдения аудита **23 октября 2026 года** и +критерии приёмки; это не список текущих открытых дефектов. Актуальный план на +`main` указывает, что все UI-01—UI-33 реализованы в PR #54. Он также описывает +follow-up по поиску, кабинету и лаборатории, локальную браузерную проверку и +синтетические regression fixtures. Их результаты привязаны к указанным в +исходном документе commits и окружению, а не являются повторным live-аудитом в +этой документационной задаче. Сверяться с [отчётом visual-review](visual-review/README.md); +не открывать снова выполненные пункты без нового воспроизводимого свидетельства. + +| ID | Приоритет | Историческое наблюдение 23.10.2026 | Требование / критерий | +|---|---|---|---| +| UI-01 | P1 | При пустом запросе одновременно показывались подсказка и empty-состояние | Разделить initial/loading/results/empty/error; empty показывать после завершённого поиска | +| UI-02 | P1 | До выбора документа были доступны действия и пустые select | До загрузки документа показывать понятное приглашение; действия доступны после выбора | +| UI-03 | P1 | Фильтры имели горизонтальное переполнение (`clientWidth=194`, `scrollWidth=231` при 1064 px) | Исключить переполнение; длинные списки раскрывать по запросу | +| UI-04 | P1 | Действие «Сбросить» обрезалось заголовком | Заголовок и действие видны целиком на поддерживаемых размерах | +| UI-05 | P1 | Счётчики отрывались от подписей, переносы растягивали панель | Разделить колонки выбора/подписи/числа; переносить только длинные названия | +| UI-06 | P1 | Все 28 видов и 8 статусов были раскрыты, орган и даты находились ниже первого экрана | Показывать основные значения и сворачиваемые группы, сохраняя доступ ко всему каталогу | +| UI-07 | P1 | Ширины около 78 px не хватало для RU/KY названий языка | Подбирать размер по самой длинной локализованной подписи без обрезки | +| UI-08 | P1 | На 390 px навигация прокручивалась горизонтально, кабинет и фильтры уходили за край | Адаптивно показывать поиск, фильтры и кабинет без горизонтальной прокрутки основных действий | +| UI-09 | P2 | Кабинет был малозаметной иконкой во второй строке | Подписанная desktop-кнопка; на mobile — доступное имя и достаточная touch-область | +| UI-10 | P1 | Три колонки оставались тесными на 1024/1064 px | Перейти к двухпанельному режиму и скрытию фильтров, не сжимать колонки бесконечно | +| UI-11 | P2 | Название документа повторялось в breadcrumb, заголовке и тексте | Breadcrumb обозначает контекст; официальный текст не переписывать | +| UI-12 | P1 | Ссылка на источник и toolbar переполнялись на промежуточной ширине | Переносить действия группами без обрезки; сохранять подписи редакции и языка | +| UI-13 | P2 | Пустые абзацы и синие ссылки конфликтовали с оболочкой | Нормализовать отступы и ссылки без потери структуры официального текста | +| UI-14 | P1 | Таблицы в документе шире панели (`clientWidth=412`, `scrollWidth=834`) | Дать таблице отдельную обозначенную прокрутку; не прокручивать всю страницу по горизонтали | +| UI-15 | P1 | Встречались Temp-пути и HTTP-ссылки исходного редактора | Классифицировать ссылки безопасно, не удалять юридический текст; не считать локальные/IP-ссылки проверенными | +| UI-16 | P2 | Развёрнутый документ терял поиск, совпадение и toolbar | Сохранять редакцию, язык, позицию и навигацию; обеспечить очевидный возврат | +| UI-17 | P2 | Часть KY-интерфейса оставалась на русском | Инвентаризировать строки интерфейса; не заменять переводом язык документа | +| UI-18 | P1 | На `/review` отображались два footer, общий footer был выше сохранения | Один footer после основного содержимого и панели сохранения | +| UI-19 | P1 | Шапка, формы, панели и footer лаборатории имели разные направляющие | Единая оболочка и совпадающие границы контента | +| UI-20 | P1 | Высокая шапка лаборатории отодвигала работу на mobile | Компактный заголовок и помощь; поиск и рабочая область доступны сразу | +| UI-21 | P1 | Заголовок кабинета был пустым | Видимый заголовок и доступное имя диалога | +| UI-22 | P1 | Не было постоянного крестика; закрытие находилось внизу формы | Крестик 44×44, доступное имя, Escape и возврат фокуса; отмена редактирования остаётся | +| UI-23 | P1 | Навигация, выход, профиль и смена пароля были смешаны | Разделить «Профиль» и «Безопасность», отделить выход от формы | +| UI-24 | P1 | Окно пользователей открывалось поверх кабинета | Не оставлять конкурирующие модальные окна; сохранять контекст и корректный фокус | +| UI-25 | P1 | Список пользователей был длинным модальным окном с закрытием ниже экрана | Отдельный экран списка и короткие диалоги для создания/сброса | +| UI-26 | P2 | Создание, удаление, сброс и входные данные смешивались | Действия на строке, отдельное подтверждение удаления, не раскрывать лишние формы | +| UI-27 | P2 | Бренд, навигация, шрифты и ссылки различались между экранами | Общие header, logo, button, link, dialog и footer | +| UI-28 | P2 | Диалоги закрывались разными способами | Единая модель окна и доступного закрытия | +| UI-29 | P2 | Обучение появлялось с задержкой и перехватывало ввод | Запуск по запросу или ненавязчиво до начала ввода; не отбирать фокус | +| UI-30 | P2 | Шкала 0–3 переносилась, комментарии всегда занимали место | Полные подписи; допустима сетка 2×2; раскрываемый комментарий без потери текста | +| UI-31 | P2 | Пустой экран лаборатории выглядел готовым к отправке оценки | Явное состояние снимка, прогресс и статус черновика; не менять смысл пустой оценки | +| UI-32 | P2 | Footer live-сайта показывал «Концепция Түндүк» | Рабочий интерфейс показывает продукт и реальные версии; концепция подписывается только в макете/демо | +| UI-33 | P1 | Документ растягивал лабораторию до y≈636935 px, сохранение уходило ниже | Ограничить высоту области чтения и прокручивать её отдельно; сохранение доступно независимо от длины текста | + +Дополнительные целевые критерии исходного аудита: + +- **Сетка и ресайз колонок:** desktop — три колонки с доступными разделителями; + ориентиры 1440 px: `280 / 408 / 736` плюс два захвата по 8 px, 1280 px: + `256 / 384 / 624` плюс захваты. Рекомендуемые пределы фильтров 256–360 px, + выдачи от 360 px, документа от 560 px. При недостатке ширины сначала скрыть + фильтры, затем показывать документ отдельно. +- Разделители должны иметь `role=separator`, доступное имя, min/max/current + значения, pointer drag и управление стрелками клавиатуры. Отдельные кнопки + скрытия/показа фильтров и сброса ширины обязательны; двойной клик не заменяет + доступный сброс. Сохранённая ширина ограничивается текущим viewport. +- **Панели и формы:** понятный заголовок и крестик 44×44; именованный modal + dialog, фокус внутри, Tab/Shift+Tab без выхода в фон, Escape там, где закрытие + допустимо, возврат фокуса инициатору. Не наслаивать кабинет и пользователей. + Права по-прежнему проверяет сервер; пароли не предзаполнять и не сохранять в + материалах аудита. Ошибки сохраняют допустимый ввод, loading исключает + повторную отправку. +- **Приёмка:** единая оболочка/header/footer; нет общей горизонтальной + прокрутки; initial не сообщает об empty до поиска; действия документа + активируются по состоянию; keyboard и touch работают; RU/KY подписи и язык + документа независимы; таблицы прокручиваются отдельно; тестируются contrast + WCAG AA, видимый focus, reduced motion, zoom/reflow и доступные имена. +- Viewport: **1440×900, 1280×800, 1024×768, 390×844**, дополнительно 320 CSS px + для reflow. Визуальное сравнение — детерминированное fixture; нулевой + pixel-diff не является критерием. Авторизация и destructive-сценарии + проверяются только в безопасном тестовом контуре. + +Исторически выполненные браузерные сценарии и ограничения аудита 23.10.2026: + +| Область | Выполнено в том аудите | Не проверено тогда | +|---|---|---| +| Начальная страница и поиск RU | Пустой запрос, фильтры, footer; поиск «налог на прибыль», открытие кодекса | Экспертная оценка юридической релевантности | +| Фильтры, сортировка, страницы | Статус, chip, снятие фильтра, дата/релевантность, страница 2 и сброс на страницу 1 | Все комбинации справочников | +| Пустая выдача и документ | Контрольный заведомо пустой запрос, реальные текст и редакции, язык, разворот | Искусственное создание серверного сбоя, реальная печать/PDF | +| Поиск в документе и локализация | Совпадения, переход к следующему, переключение RU/KY и чтение подписей | Поиск после смены редакции; полная проверка всех переводов | +| Источники и мобильные фильтры | Открытие/закрытие панели и раздела источников | Внешний сайт Минюста, полный touch на физическом устройстве | +| Кабинет и пользователи | Профиль, поля смены пароля, Escape/возврат фокуса; просмотр списка | Ввод пароля, создание/удаление пользователя, сброс пароля | +| `/review` | Пустое состояние, поиск, шкала, документ, обучение | Отправка оценки и подтверждение серверного сохранения | +| Авторизация | Наличие локальной реализации | Live login, истечение сессии и обязательная смена пароля | + +Этот перечень описывает только прежний браузерный сеанс. Не использовать его +как подтверждение текущих production-сценариев. + +#### Реализация, зафиксированная в текущем плане `main` + +Документ `interface-correction-plan.md` на базовом commit этого PR отмечает +UI-01—UI-33 реализованными в PR #54. Он связывает группы изменений с +регрессионными сценариями: + +| Пункты | Изменение, зафиксированное в плане `main` | Regression evidence, указанное там | +|---|---|---| +| UI-01—02 | Разделены initial/loading/results/empty/error; действия документа зависят от выбранной редакции | Empty, API error и редакция без текста | +| UI-03—08 | Компактные/сворачиваемые фильтры, счётчики, локализованные языковые select и адаптивная навигация | Reflow 320/390/640/1024/1280/1440; на 640 px проверены основные действия `/`, `/review`, `/users` | +| UI-09—10 | Подписанный кабинет и адаптивный layout вместо бесконечного сжатия трёх колонок | Геометрия и overflow на 640/1024/1280/1440 | +| UI-11—16 | Breadcrumb, toolbar, отдельный scroll таблиц, очистка небезопасных URL-атрибутов и разворот документа в панели | Синтетические private-IP/relative/HTTP ссылки; ошибки и гонки редакций A/B | +| UI-17 | Перевод интерфейсных подписей RU/KY с независимым языком документа | Переключение языка; полный ручной лингвистический review остаётся открытым | +| UI-18—20 | Один footer, общие направляющие и ограниченная по высоте лаборатория | Один footer и длинный синтетический документ с собственным scroll | +| UI-21—24 | Имя и разделы кабинета, безопасный переход к пользователям без наложенных диалогов | ARIA name, Escape, focus trap/return и отдельные маршруты | +| UI-25—28 | Отдельный экран пользователей, целевые окна для действий, общий способ закрытия | Только фиктивный `fixture-created`; реальные аккаунты/API не использовались | +| UI-29 | Обучение запускается пользователем | Локальный regression scenario | +| UI-30—31 | Оценка 2×2, раскрываемый комментарий, disable до результата и draft state | Фиктивное сохранение и сохранность оценок при ошибке/устаревшем ответе | +| UI-32—33 | Версии в footer и отдельная прокрутка длинного текста лаборатории | Footer versions и длинный fixture, сохранение остаётся доступно | + +Тот же план `main` фиксирует локальный browser run на **320×800, 390×844, +640×450, 1024×900, 1280×800 и 1440×900 CSS px**; на 1280 px измерена +сетка 256 / 384 / 640 px. Экран лаборатории с длинным текстом имел собственную +панель прокрутки, а сохранение/footer оставались доступны. Встроенная +проверка fixture не использовала production API или реальные учётные записи. +Это точная передача прежнего отчёта; её не следует трактовать как результат +нового прогона в этом PR. Полный screen-reader review, 200–400% zoom, +физический touch и полный ручной лингвистический review в исходном плане +оставлены непроверенными. + +Отдельный follow-up плана `main` описывает последующие изменения: статус +«Открыт» выставляется после успешной загрузки; оглавление распознаёт RU/KY +структурные заголовки и избегает дублирования упоминаний; размеры и положение +языкового выбора, фильтров и splitter скорректированы. В кабинете выровнены +пары профильных значений, сохранены семантические ссылки и доступность перехода +к пользователям. В лаборатории выровнены оболочка, форма, рабочая область, +сохранение и footer; mobile возвращается к естественному потоку документа. +Исходный план сообщает о локальной проверке 24 октября 2026 года; статус CI и +review относится к конкретному pushed SHA и должен подтверждаться отдельно. + +В актуальном плане `main` follow-up обозначен как реализованный; там указано, +что frontend был повышен до `0.3.0` из-за регулируемой ширины панелей. Текущий +source footer и версия кода — `0.3.3`. Историческую отметку «ожидаются CI и +review» из старого плана нельзя использовать как статус сегодняшнего PR: она +относилась к конкретному SHA на момент записи. + +#### Общие критерии окон и форм + +- Desktop-окно обычно 480–640 px и не шире viewport; на mobile — отступ 16 px + или полноэкранный режим для длинной формы. Заголовок и закрытие остаются + доступны при прокрутке. +- Диалог именуется через заголовок, держит фокус внутри и не делает фон + интерактивным. Escape закрывает обычные окна; исключения (например, + обязательная смена пароля) должны объясняться, а не маскироваться. +- Профиль и безопасность разделены. Удаление требует отдельного подтверждения; + создание/сброс не раскрывают дополнительные формы без запроса. +- Поля имеют постоянные подписи; пароль не предзаполняется и не записывается + в отчёт. Ошибки объясняют восстановление, допустимый ввод сохраняется, + повторная отправка во время loading исключена. +- «Отмена» вторична, выход не смешивается с сохранением; несохранённое + редактирование защищено от случайной потери. Обычный просмотр закрывается + без лишнего подтверждения. + +#### Последовательность при возобновлении UI-работ + +1. Зафиксировать актуальные SHA и версии; читать маршрут, API, `DESIGN.md`, + UI tests и CI. Не переносить состояние live-сайта без новой проверки. +2. Исправить общую оболочку и разделение поиска, лаборатории и служебных + экранов; затем initial/loading/empty/error и жизненный цикл документа. +3. Исправить фильтры, адаптивные минимумы и RU/KY; после этого — регулируемые + колонки и скрытие фильтров. +4. Привести формы/диалоги к общей модели с сохранением серверной авторизации, + прав, валидации, снимков оценок и черновиков. +5. Проверить текст, таблицы, ссылки, редакции, печать, адаптивность, + локализацию, доступность и состояния на реальном корпусе, где доступен. +6. Сделать детерминированный fixture-проход и независимый review; обновить + версию только при изменении кода, а changelog — после зелёных проверок и + разрешения blocking findings. + +| Приёмка | Условие | +|---|---| +| Оболочка | Один header/footer на маршруте, единые границы и порядок контента | +| Фильтры | Нет общей горизонтальной прокрутки; подписи/действия/счётчики видны полностью | +| Начальное состояние | До первого завершённого запроса empty-сообщение не показано | +| Документ | До выбора неактивные действия не вводят в заблуждение | +| Колонки | Pointer и клавиатура; min/max; скрытие/возврат; reset; адаптация сохранённой ширины к viewport | +| Телефон | Основные действия без горизонтального скролла; понятный возврат из фильтров/документа | +| Окна | Заголовок, крестик, Escape, trap/return focus; окна не конкурируют слоями | +| Лаборатория | Поиск → чтение → оценка → черновик → сохранение; текст не теряется, панель доступна при длинном документе | +| Локализация | RU/KY labels и символы; язык UI не подменяет язык документа | +| Типографика и таблицы | Noto действительно загружается; читаемый длинный текст; у широкой таблицы собственный скролл | +| Доступность | Контраст AA, focus, Tab/Shift+Tab/Enter/Escape, zoom/reflow, reduced motion и touch targets | +| Авторизация | Неверный пароль, expired session и обязательная смена проверены только в безопасном тестовом контуре | +| Снимки | 1440×900, 1280×800, 1024×768, 390×844 и 320 CSS px; стабильные fixture и объяснённые различия | + +### 2.3 Инфраструктура и переход к production + +Инфраструктурные источники содержали повторяющиеся этапы deployment и +устаревшие снимки VPS. В этом плане оставлены только gates; актуальные +подтверждённые данные и процедуры находятся в операционных документах. + +1. **Аудит:** сверить commit `main`, CI, Compose, зависимости, порты, volumes, + healthchecks, данные и перечень env-переменных без вывода секретов. Для VPS + пользоваться только read-only инвентаризацией, разрешённой + [правилами доступа](../operations/ACCESS.md). Не переносить IP, версии, + DNS-статус или ресурсы из старых планов как текущие факты. +2. **Данные и конфигурация:** установить источник и допустимость корпуса, + формат, состав, checksum/manifest, размер и воспроизводимую цепочку импорта. + Не подменять корпус пустым каталогом. Production env/секреты создаются вне + Git; в репозитории остаются только имена переменных и шаблоны без значений. +3. **Build/CI:** PR-проверки не получают production secrets и Docker socket. + Публикация образов должна фиксировать digest и provenance; release workflow + не равен deployment. Production CD не включать до прохождения owner gates, + безопасной сборки, backup и отдельного restore. +4. **Первое применение:** до запуска проверить реальные данные и + конфигурацию, требуемое свободное место, открытые порты, права, backup + readiness и совместимость схем. Выполнять через существующую ограниченную + процедуру; не добавлять общие sudo/Docker-привилегии. +5. **Проверка и recovery:** проверять health/API, RU/KY canaries, доступность + HTTPS, сохранность данных и rollback в пределах его документированных + ограничений. Data restore — отдельная процедура в staging, не автоматический + побочный эффект отката образа. +6. **Автоматизация:** только после одобренного отдельного bootstrap и + end-to-end проверки; serial deployment, digest verification, backup ACK, + health gates и отказ без destructive cleanup. Не включать триггер только + потому, что workflow завершился зелёным. + +Нынешний статус не переопределяется этим roadmap: на сверенной документации +production CD остаётся неактивным, а backup/restore и внешний bootstrap имеют +непроверенные owner prerequisites. Все точные блокировки сверять с +`CURRENT_STATE.md` и `DEPLOYMENT.md` перед планированием действий. + +## 3. Визуальные материалы и исходная база + +### Макеты Figma + +Целевые редактируемые экраны — гипотезы компоновки, а не работающий интерфейс, +источник юридических данных или доказательство доступности. + +| Экран | Макет | +|---|---| +| 01. Поиск с документом, 1440×900 | [Figma](https://www.figma.com/design/3PE98PJYOXo7a35u2X5VqB?node-id=3-2) | +| 02. Фильтры скрыты | [Figma](https://www.figma.com/design/3PE98PJYOXo7a35u2X5VqB?node-id=3-173) | +| 03. Начальный поиск | [Figma](https://www.figma.com/design/3PE98PJYOXo7a35u2X5VqB?node-id=3-288) | +| 04. Лаборатория и сохранение | [Figma](https://www.figma.com/design/3PE98PJYOXo7a35u2X5VqB?node-id=3-395) | +| 05. Кабинет: профиль и закрытие | [Figma](https://www.figma.com/design/3PE98PJYOXo7a35u2X5VqB?node-id=5-30) | +| 06. Кабинет: безопасность | [Figma](https://www.figma.com/design/3PE98PJYOXo7a35u2X5VqB?node-id=5-229) | +| 07. Источники | [Figma](https://www.figma.com/design/3PE98PJYOXo7a35u2X5VqB?node-id=5-428) | +| 08. Пользователи: отдельный экран | [Figma](https://www.figma.com/design/3PE98PJYOXo7a35u2X5VqB?node-id=5-605) | +| 09. Телефон: выдача | [Figma](https://www.figma.com/design/3PE98PJYOXo7a35u2X5VqB?node-id=5-670) | +| 10. Телефон: чтение | [Figma](https://www.figma.com/design/3PE98PJYOXo7a35u2X5VqB?node-id=5-670) | +| 11. Телефон: фильтры | [Figma](https://www.figma.com/design/3PE98PJYOXo7a35u2X5VqB?node-id=5-670) | +| 12. Эталон 1280×800 | [Figma](https://www.figma.com/design/3PE98PJYOXo7a35u2X5VqB?node-id=7-74) | +| 13. Планшет: две панели | [Figma](https://www.figma.com/design/3PE98PJYOXo7a35u2X5VqB?node-id=7-245) | +| 14. Кабинет на телефоне | [Figma](https://www.figma.com/design/3PE98PJYOXo7a35u2X5VqB?node-id=7-360) | +| 15. Вход, создание и подтверждение удаления | [Figma](https://www.figma.com/design/3PE98PJYOXo7a35u2X5VqB?node-id=8-118) | + +Локальные target exports: [поиск](../design/tunduk-search-target.png), +[лаборатория](../design/tunduk-review-target.png), +[кабинет](../design/tunduk-account-target.png). Это изображения цели; они не +заменяют браузерную проверку. + +### Исторические свидетельства + +Аудит UI выполнен **23 октября 2026 года** в авторизованной сессии на +`https://akyldash.kg/`, где footer показывал Frontend `0.2.3`, Backend +`0.13.0`. Сверка SHA сервиса с checkout не выполнялась. Проверены +1440×900, 1280×800, 1024×768, 390×844 CSS px и дополнительный browser viewport +1064×1244. Пароли не вводились; создание/удаление пользователей и отправка +оценки не выполнялись; полный физический touch, screen-reader и принтерный +прогоны не выполнялись. Существующие локальные browser evidence и screenshots +собраны в [отчёте visual-review](visual-review/README.md). Ветка `main` не +содержит отдельный архив live screenshots этого аудита. Любое использование +результатов требует повторной проверки актуальной версии и окружения. + +## 4. Постоянные правила дизайна и полномочия + +[DESIGN.md](../../DESIGN.md) остаётся нормативной дизайн-системой: цветовые +токены, типографика, бренд, композиционные принципы и доступность не +дублируются здесь. Этот roadmap задаёт работы, исторические критерии и gates; +он не утверждает новый дизайн и не разрешает production deployment. + +Все пункты плана отмечать выполненными только при наличии актуального +свидетельства. Изменения приложения проходят обычные тесты, версионирование, +CI и независимое review. Инфраструктурные изменения отражаются в +`CURRENT_STATE.md` только по фактическим проверкам. Никакие действия с +production, секретами, пользователями или правовым корпусом не следуют из +наличия этого документа. diff --git a/docs/product/interface-correction-plan.md b/docs/product/interface-correction-plan.md deleted file mode 100755 index 714fbf0..0000000 --- a/docs/product/interface-correction-plan.md +++ /dev/null @@ -1,334 +0,0 @@ -# Единый план корректировки интерфейса «Акылдаш» - -Дата аудита: **23 октября 2026 года**. -Базовые пункты UI-01—UI-33 исправлены и вошли в `main` через PR #54. -На 24 октября 2026 года отдельный follow-up по замечаниям владельца для поиска, -личного кабинета и лаборатории реализован; локальный браузерный набор пройден. -Ожидаются CI и ручное PR review для pushed SHA. - -Этот файл заменяет `frontend-pixel-perfect-plan.md` и является единственным -рабочим планом исправления UI/UX поиска, лаборатории и служебных окон. -Продуктовый roadmap и требования к юридической готовности остаются отдельными -документами: они не являются конкурирующими планами исправления интерфейса. - -## 1. Источники истины и границы - -- [DESIGN.md](../../DESIGN.md) — нормативная система «Түндүк». -- [Утверждённая композиция](../design/tunduk-desktop-concept.png) — визуальный - ориентир, а не образец юридических данных или текущих функций. -- [Целевые редактируемые макеты Figma](https://www.figma.com/design/3PE98PJYOXo7a35u2X5VqB) - — предлагаемая компоновка поиска, лаборатории, кабинета и адаптивных видов. -- Этот файл — дефекты, требования к поведению, порядок исправления и приёмка. - -Проверялся работающий `https://akyldash.kg/` в авторизованной сессии, -версии в интерфейсе: Frontend **0.2.3**, Backend **0.13.0**. -Локальный checkout содержит более ранние версии; код и live-сайт нельзя -считать одинаковыми без сверки SHA перед реализацией. Инфраструктурные -документы не заменяют результаты этой браузерной проверки. - -В этой задаче исправляются frontend и доступ к статическому экрану `/users`. -Backend-проверки ролей и операций управления пользователями не меняются. -Production, пользователи, пароли, сохранённые оценки, ранжирование и правовой -корпус не меняются. Реальные учётные записи не используются в регрессионном -fixture. - -## 2. Что проверено - -Проверка включала клики и чтение DOM, снимки и измерение переполнения. -Контрольные viewport: **1440×900, 1280×800, 1024×768, 390×844**; -дополнительно исходный viewport браузера 1064×1244. Изображения пользователя -с более широким desktop учитываются как дополнительные свидетельства, -но не выдаются за собственный браузерный прогон. - -| Поверхность / сценарий | Выполнено | Ограничение | -|---|---|---| -| Начальный `/` | Пустой запрос, доступные действия, фильтры, footer | Ошибочное empty-состояние подтверждено | -| Поиск RU | Запрос «налог на прибыль», загрузка выдачи, открытие кодекса | Не экспертная проверка юридической релевантности | -| Фильтры | Выбор статуса, появление chip, снятие фильтра | Все комбинации справочников не перебирались | -| Сортировка / страницы | Выбор даты / релевантности, переход на страницу 2, сброс на страницу 1 | Оценивалось состояние UI и URL | -| Пустая выдача | Запрос `zzzzqwerty987654321` | Серверный сбой не провоцировался | -| Документ | Реальный текст, список редакций, переключение редакции и языка, разворот | Печать на принтер / в PDF не запускалась | -| Поиск в документе | Ввод фразы, подсветка, кнопка следующего совпадения | Поиск после смены редакции требует отдельного теста | -| RU/KY интерфейс | Переключение и чтение подписей | Найдены непереведённые подписи; полнота всех строк не подтверждена | -| Мобильные фильтры | Открытие и закрытие панели | Полный touch-прогон на физическом устройстве не выполнен | -| «Об источниках» | Открытие, чтение, закрытие | Внешний сайт Минюста не является частью этого аудита | -| Личный кабинет | Открытие, профиль, поля смены пароля, Escape и возврат фокуса | Пароли не вводились и не менялись | -| Пользователи | Открытие из кабинета и из лаборатории, чтение структуры | Создание, удаление и сброс пароля не выполнялись | -| `/review` | Пустое состояние, поиск, шкала оценок, открытие документа, обучение | Оценки не отправлялись; серверное сохранение не подтверждено | -| Авторизация / истёкшая сессия | Установлено наличие в локальной реализации | Live login и принудительная смена пароля не проверялись: действующую сессию не завершали | - -Снимки: [каталог аудита](../design/audit-2026-10-23/). -Участки с реальными списками пользователей не переносятся в макеты Figma; -там используются явно условные примеры. Часть снимков лаборатории сделана -с длинной страницей; снимок не гарантирует корректность всех скрытых участков. - -## 3. Реестр недостатков - -**P1** — исправить до визуальной приёмки / выпуска; **P2** — существенное -улучшение понятности и последовательности. Предложения обозначены отдельно -от подтверждённых дефектов. Отсутствие функции само по себе не означает баг. - -| ID | Приоритет | Подтверждённый недостаток / свидетельство | Корректировка и условие приёмки | -|---|---|---|---| -| UI-01 | P1 | В начальном поиске одновременно «Введите запрос» и «Документы не найдены» | Разделить initial/loading/results/empty/error; empty только после завершённого поиска | -| UI-02 | P1 | До выбора документа доступны печать/разворот/содержание, видны пустые селекты | До выбора — только понятное приглашение открыть результат; инструменты появляются после загрузки | -| UI-03 | P1 | У фильтров горизонтальный и вертикальный скроллы; при 1064 px `clientWidth=194`, `scrollWidth=231` | Горизонтальное переполнение исключено; компактные группы, достаточная ширина, длинные списки раскрываются по запросу | -| UI-04 | P1 | «Сбросить» обрезается заголовком панели | Заголовок и действие полностью видны на всех поддерживаемых размерах | -| UI-05 | P1 | Счётчики отрываются от названий, частые переносы превращают фильтры в длинную колонку | Отдельные колонки выбора/подписи/числа; числа с разделителями; перенос только длинного названия по словам | -| UI-06 | P1 | Все 28 видов и 8 статусов развёрнуты; орган и даты далеко ниже первого экрана | Основные варианты + «Все виды»/«Все статусы», сворачиваемые группы; сохранять доступ ко всем значениям | -| UI-07 | P1 | Язык поиска имеет ширину около 78 px; «Русский»/«Кыргызский» обрезаются | Размер по самой длинной локализованной подписи и стрелке; проверка RU/KY без ellipsis | -| UI-08 | P1 | На 390 px строка навигации горизонтально прокручивается, кабинет и фильтры уходят за край | Адаптивная перестройка: видимые поиск, фильтры, кабинет; ни одна основная кнопка не требует горизонтального скролла | -| UI-09 | P2 | Кабинет — малозаметная иконка в правом конце второй строки; слева большой неинформативный промежуток | На desktop подписанная кнопка «Кабинет» в шапке; на mobile узнаваемая иконка с доступным именем и достаточной областью | -| UI-10 | P1 | На 1024/1064 три колонки остаются тесными; название кодекса занимает большую часть панели | Адаптивный двухпанельный режим, скрытие фильтров, ограничения ширин; не сжимать все три колонки бесконечно | -| UI-11 | P2 | Длинное название документа повторено в breadcrumb, заголовке и исходном тексте | Breadcrumb обозначает контекст; в заголовке короткое название при наличии отдельного поля, реквизиты ниже; официальный текст не переписывать | -| UI-12 | P1 | Source link и toolbar переполняются на промежуточных ширинах; при 1064 px toolbar `412/427` | Действия переносятся группами, без обрезки; размер по содержимому, подписи редакции и языка постоянные | -| UI-13 | P2 | В исходном тексте большие пустые абзацы и синие ссылки конфликтуют с оболочкой | Нормализовать отображение пустых блоков без потери структуры; безопасно унифицировать ссылки и отступы в scope документа | -| UI-14 | P1 | В тексте есть широкие таблицы: например, `clientWidth=412`, `scrollWidth=834` | Таблицы — самостоятельная обозначенная область прокрутки; документ и весь экран не получают горизонтальный скролл | -| UI-15 | P1 | В DOM документа обнаружены относительные ссылки на старые локальные Temp-пути и HTTP URL исходного редактора | Не показывать их как рабочие внутренние переходы; безопасно разрешать/классифицировать ссылки, не удаляя юридический текст; локальные/IP-ссылки не открывались | -| UI-16 | P2 | Разворот открывает ещё одно окно с текстом; поиск, выбранное совпадение и toolbar не представлены в нём | Целевой режим чтения сохраняет редакцию, язык, положение и средства навигации; возврат очевиден | -| UI-17 | P2 | Часть KY-интерфейса остаётся русской: например заголовки групп и служебные доступные подписи | Инвентаризировать все UI-строки; контент документа переводом интерфейса не подменять | -| UI-18 | P1 | На `/review` два видимых footer; общий footer находится до сохранения | Ровно один видимый footer после основного контента и панели сохранения | -| UI-19 | P1 | В лаборатории шапка, формы, панели и footer имеют разные границы и ширины | Общая оболочка и единые горизонтальные направляющие, совпадающие поля и ширины контейнеров | -| UI-20 | P1 | Шапка лаборатории слишком высокая; на mobile рабочие результаты вытеснены далеко вниз | Компактный заголовок и помощь рядом; поиск и начало работы доступны без большого вступительного блока | -| UI-21 | P1 | У кабинета фактически пустой `account-heading`, нет видимого заголовка | «Личный кабинет» в заголовке, корректное имя диалога для скринридера | -| UI-22 | P1 | В кабинете нет крестика; «Закрыть» только внизу формы смены пароля | Единый крестик 44×44 справа сверху, доступное имя, Escape, возврат фокуса; нижняя отмена при редактировании | -| UI-23 | P1 | Навигация, выход, профиль и смена пароля смешаны в одном неструктурированном окне | Отдельные разделы «Профиль» / «Безопасность»; служебные действия и выход отделены от формы | -| UI-24 | P1 | «Пользователи» из кабинета открывает `users-dialog`, когда `account-dialog` остаётся открытым поверх него | Не оставлять конкурирующие модальные окна: закрыть кабинет с сохранением контекста и открыть целевой экран/диалог; фокус соответствует видимому окну | -| UI-25 | P1 | Управление пользователями — длинный модальный список, закрытие ниже видимой области | Предпочтительно отдельный экран с таблицей; создать/сбросить — короткие отдельные диалоги с фиксированным заголовком и крестиком | -| UI-26 | P2 | Удаление, сброс пароля, создание и данные входа перемешаны без ясной иерархии | Действия на строке пользователя; удаление отдельно и с подтверждением; не раскрывать все формы сброса постоянно | -| UI-27 | P2 | Различаются оформление бренда/навигации/шрифтов, есть стандартные синие ссылки в лаборатории и кабинете | Единые header, logo, button, link, dialog и footer на всех поверхностях | -| UI-28 | P2 | Диалоги закрываются разными кнопками в разных местах | Одна модель окна и доступного закрытия, описанная ниже | -| UI-29 | P2 | Обучение автоматически появляется с задержкой и перехватывает фокус уже начатого ввода | Не перехватывать ввод; запуск по «Как это работает» либо ненавязчивому предложению до начала работы | -| UI-30 | P2 | Шкала 0–3 на длинной выдаче создаёт плотный набор переносов; комментарии всегда занимают место | Полные подписи без обрезки, допускается сетка 2×2; комментарий раскрывается, введённый текст не теряется | -| UI-31 | P2 | На пустом лабораторном экране «Сохранить оценку» выглядит готовой к отправке | Состояние зависит от наличия снимка; явное объяснение, прогресс и статус черновика; не менять смысл отсутствующей оценки | -| UI-32 | P2 | В footer работающего сайта остаётся «Концепция Түндүк» | В рабочем режиме название продукта и реальные версии; подпись концепции только в макете/демо | -| UI-33 | P1 | Открытие кодекса в лаборатории растягивает страницу: footer оказался на y≈636935 px, сохранение — внизу после него | Ограничить область чтения по высоте viewport и дать ей собственную вертикальную прокрутку; сохранение доступно независимо от длины документа, без сотен экранов прокрутки | - -Escape и возврат фокуса кабинета на `search-account-open` проверены и работают. -Это поведение сохранить. Механизм Tab/Shift+Tab всех окон, ошибки API, -контраст всех состояний, печатная вёрстка и поведение на 200–400% zoom -требуют отдельного приёмочного прогона; здесь они не объявлены проверенными. - -## 4. Целевая сетка, изменение ширины и фильтры - -Это согласованное направление корректировки, а не уже существующие функции. - -1. Шапка, навигация, main и footer принадлежат одной оболочке. Поисковый - и лабораторный контент не вставляются друг в друга и не дублируют footer. -2. На широком desktop три колонки с двумя доступными разделителями. - Базовый ориентир при 1440: **280 / 408 / 736 px + два захвата по 8 px**. - При 1280: **256 / 384 / 624 px + два захвата по 8 px**. Это размеры - целевых макетов, а не требование сжимать эти колонки ниже удобных минимумов. -3. Предлагаемые пределы: фильтры 256–360 px, выдача от 360 px, - документ от 560 px. Если окно не вмещает минимумы, фильтры уходят - в отдельную панель, затем документ становится отдельным представлением. - Пользовательское растягивание не может сломать соседнюю колонку. -4. Разделители: узнаваемый захват, `col-resize`, роль `separator`, - доступное имя, текущая/минимальная/максимальная ширина. Перетаскивание - и стрелки клавиатуры; отдельные «Скрыть фильтры» / «Показать фильтры» - и «Сбросить ширину». Двойной клик может дополнять, но не заменяет - видимый и клавиатурный способ сброса. Положение хранится локально; - при восстановлении ограничивается фактическим viewport. -5. На desktop у фильтров нет отдельной постоянно прокручиваемой узкой - колонки: краткие группы и раскрытие длинных справочников. Полный - каталог доступен через поиск/раскрытие; нельзя скрыть значения навсегда. - Одиночный выбор API не выдаётся за множественный checkbox. -6. Длинные названия органов открываются в панели выбора с полными строками; - основное поле не становится бессмысленной обрезанной подписью. -7. Даты имеют постоянные «От» / «До»; если два поля не помещаются, - ставятся друг под другом. Перенос текста внутри input недопустим. -8. На desktop самостоятельная вертикальная прокрутка выдачи и длинного - документа допустима. Их заголовки/toolbar доступны при чтении. - Фильтры и всё приложение не должны требовать горизонтальной прокрутки. - На телефоне — одна основная вертикальная прокрутка и отдельные панели. -9. Footer внизу короткой страницы через layout с `min-height: 100dvh` - и растущим main, а не `position: fixed` поверх содержимого. При длинном - контенте footer следует после него. Панель сохранения имеет собственное - место; sticky допускается только без перекрытия последней строки. - -## 5. Единые правила всех окон и форм - -- Видимый короткий заголовок и крестик в правом верхнем углу, область 44×44. - Закрытие не спрятано в конце длинного содержимого. -- Desktop: ширина по задаче, обычно 480–640 px, максимум относительно - viewport; mobile: отступ 16 px либо полноэкранная форма для длинного ввода. - Заголовок/закрытие остаются доступны при прокрутке содержимого. -- `dialog` / `aria-modal`, имя через заголовок; фокус при открытии внутри, - Tab/Shift+Tab не уходят в фон, Escape закрывает обычное окно, фокус - возвращается на инициатор. Фон не интерактивен. Исключения для - обязательной смены пароля объясняются пользователю, не маскируются. -- Не наслаивать кабинет и пользователей. Переход между задачами — замена - поверхности с понятным возвратом. Подтверждение удаления — короткое - целевое окно, а не второй длинный редактор за первым. -- «Профиль» — просмотр сведений; «Безопасность» — смена пароля. Доступ - к администрированию определяется сервером, редизайн не меняет права. -- В форме пароля постоянные подписи, подсказка требований, показать/скрыть - пароль с доступным именем; подтверждение нового пароля как защита от - опечатки. Никакие реальные пароли не предзаполняются и не записываются - в материалы аудита. Изменение пароля выполняет человек. -- Основное действие одно; «Отмена» вторична; «Выйти» отдельно от сохранения. - Enter отправляет только активную форму. Ошибки рядом с полем и в - доступном сообщении, введённые допустимые данные сохраняются. -- При несохранённом редактировании — понятная защита от случайной потери; - обычное закрытие окна просмотра не требует лишнего подтверждения. -- Loading исключает повторную отправку; при успехе сообщается результат; - при ошибке есть путь восстановления. Валидация не ограничивается цветом. -- Эти правила распространяются на кабинет, вход, обязательную смену пароля, - источники, создание/сброс/удаление пользователя, обучение и документный viewer. - -Основания для доступного поведения: -[WAI-ARIA Dialog](https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/), -[Window Splitter](https://www.w3.org/WAI/ARIA/apg/patterns/windowsplitter/) -(паттерн APG находится в разработке; использовать как ориентир), -[WCAG Reflow](https://www.w3.org/WAI/WCAG22/Understanding/reflow.html). -Крестик и структура кабинета — также прямое требование пользователя. - -## 6. Реализация и проверяемое покрытие - -Кодовая реализация сгруппирована по общей причине, а не по числу замечаний. -Ниже перечислены все UI-01—UI-33, привязанные к коду и регрессионному -сценарию. Playwright fixture использует только условные записи `admin`, -`fixture-user` и `fixture-created`; browser requests полностью перехватываются -тестом и не обращаются к приложению, Gitea или production API. Локальный browser -run завершился успешно. - -| Пункты | Изменение | Регрессионное покрытие | -|---|---|---| -| UI-01—02 | Разделены initial/loading/results/empty/error; панель документа показывает инструменты после выбора редакции | Пустой результат, API ошибка и редакция без текста | -| UI-03—08 | Скомпонованы фильтры и сворачиваемые группы, читаемые счётчики и языковые select; навигация адаптируется на промежуточной ширине | Reflow 320/390/640/1024/1280/1440 CSS px; на 640 px проверены кабинет, выход и создание пользователя на `/`, `/review`, `/users` | -| UI-09—10 | Кабинет подписан на desktop; экран переходит от трёх колонок к адаптивной компоновке | Геометрия действий и отсутствие page overflow на 640 px; layout измерен на 1024/1280/1440 px | -| UI-11—16 | Breadcrumb не дублирует заголовок; toolbar переносится; широкие таблицы имеют собственный scroll; URL-атрибуты очищаются; разворот остаётся в панели документа | Fixture удаляет `srcset`, `ping`, private-IP `href/src`, относительные и HTTP ссылки, сохраняя текст и официальную HTTPS-ссылку; лаборатория проверяет A → ошибка B → успешная B и устаревший ответ A | -| UI-17 | Переведены подписи поиска, фильтров, кабинета и `/users`; язык документа остаётся независимым | Переключение RU/KY и язык редакции; полный ручной лингвистический review остаётся открытым | -| UI-18—20 | Убрано дублирование footer, согласованы контейнеры, лаборатория ограничена по высоте документа | Fixture проверяет один видимый footer; панель 612 px при viewport 900 px и scrollHeight 41027 px | -| UI-21—24 | Кабинет имеет имя и разделы профиля/безопасности; переход к пользователям закрывает кабинет и открывает отдельный маршрут | ARIA имя, Escape, focus trap/return и отдельные маршруты | -| UI-25—28 | Управление пользователями — отдельный экран; создание и удаление — отдельные окна; сброс и история раскрываются по запросу; общие крестики | Fixture выполнил смену пароля, создание, сброс пароля и удаление только `fixture-created`; production учётные записи и API не использовались | -| UI-29 | Обучение запускается пользователем, без автоматического перехвата фокуса | Регрессионный сценарий обучения | -| UI-30—31 | Оценка 2×2, комментарий скрываемый; сохранение выключено до выбора результата, есть состояние черновика | Fixture проверяет черновик и фиктивное сохранение; рейтинг и комментарий сохраняются при переключении документа, включая ошибку B и устаревший ответ A | -| UI-32—33 | Footer содержит продукт и версии; документ лаборатории имеет собственную прокрутку до панели сохранения | Версии в обоих footer; длинный текст прокручивается внутри панели, сохранение и footer остаются ниже неё | - -Локальный Playwright run прошёл на **320×800, 390×844, 640×450, 1024×900, -1280×800 и 1440×900 CSS px**; горизонтального переполнения документа нет. -При 640 CSS px кабинет, выход и создание пользователя остаются видимыми и -помещаются в viewport на трёх маршрутах. Это проверка reflow, не проверка -browser zoom: в доступном headless Chromium Ctrl+Plus не меняет CSS viewport; -реальный zoom 200–400% остаётся непроверенным. -При 1280 px сетка измерена как 256 / 384 / 640 px. Для длинной лабораторной -редакции панель ограничена 544 px при viewport 800 px, scrollHeight 27278 px; -сохранение и footer остаются ниже неё в DOM и доступны независимо от текста. -Снимки, overlay и pixel-difference с целевым изображением сохранены в -[каталоге visual review](visual-review/). Растровый diff является обзорной -диагностикой, а не пороговой проверкой: макет и fixture-контент различаются. -Ручной лингвистический review всех скрытых KY-подписей, физический touch, -200–400% zoom и операции с реальными пользователями/паролями не выполнялись. - -Не мигрировать существующий Python frontend на React/Next.js ради этих -исправлений. Не менять ранжирование, корпус или права доступа в UI-задаче. - -## 9. Follow-up замечания владельца: поиск, кабинет и лаборатория - -Повторный просмотр трёх экранов выявил отдельные проблемы уже после PR #54. -Исправления остаются в этом плане, чтобы не создавать параллельный список: - -| Поверхность | Наблюдение | Реализация и проверка | -|---|---|---| -| Поиск: выдача и чтение | Метка «Открыт» ставилась до ответа, могла оставаться после ошибки и дублироваться; оглавление пропускало структурные заголовки из жирных `p > b > span`; выбор языка был обрезан и расположен в навигации; в фильтрах оставался декоративный SVG с пустым резервом; активный пункт «Поиск» визуально смещался | Метка очищается при смене результата/редакции и появляется только после успешной загрузки; оглавление распознаёт самостоятельные заголовки раздела/главы/статьи на RU/KY, назначает уникальные якоря и строит вложенные списки; язык поиска находится в фильтрах с полной шириной; SVG и его место удалены; ссылки навигации используют палитру Акылдаш. Проверка: ошибки и гонки загрузки, заголовки RU/KY и обычные упоминания, уникальные якоря, диапазон и доступность splitter | -| Личный кабинет | Навигация выглядела ссылкой браузера; закрытие занимало строку текстом; подписи и значения профиля стояли в столбик; заголовок был крупным; появлялось горизонтальное переполнение; действие управления пользователями было неочевидным | Ссылки кабинета оформлены как действия с сохранением семантики ``; крестик остаётся SVG-кнопкой 44×44 с доступной подписью; профиль выровнен в пары «поле — значение»; заголовок компактнее; длинные значения переносятся; администратор получает явную ссылку «Управление пользователями». Проверка: RU/KY, скрытие ссылки для не-администратора, фокус/закрытие диалога и ширина содержимого | -| Лаборатория | Дублировалась роль рядом с именем; ссылки навигации не имели вида кнопок; оболочка, форма, рабочая область, сохранение и footer имели разные границы; пустое сообщение резервировало высоту; панели выглядели разрозненными карточками; основной заголовок переносился; мобильный экран наследовал искусственную высоту | В шапке показывается только имя, роль остаётся в профиле; навигация сохраняет ссылки и получает единый вид кнопок; все участки выровнены по общему shell; пустой live status не добавляет зазор; результаты и документ образуют общую поверхность с внутренней прокруткой на desktop; заголовок использует доступную ширину и размеры по макету Figma; mobile возвращается к естественному потоку с прокруткой документа. Проверка: desktop/mobile, пустой status, сохранение после длинного документа и отсутствие page overflow | - -Frontend повышен до **0.3.0** из-за добавления доступного изменения ширины -панелей. Backend и его API не менялись. Fixture данные искусственные; preview -слушает только loopback, запрещает запросы за пределы своего origin и не -использует авторизационные cookies или production API. Браузерный прогон прошёл -на 24 октября 2026 года; пять скриншотов сохранены в `current-progress` рядом -с отчётом assignment. CI и независимое ревью проверяются для конкретного pushed -SHA. - -## 7. Приёмка: что значит «вылизанный интерфейс» - -| Проверка | Условие | -|---|---| -| Оболочка | Один видимый header и footer на каждом маршруте, единые границы блоков | -| Фильтры | Нет горизонтального скролла; полный текст действий, читаемые подписи и счётчики | -| Начальное состояние | Не сообщает об отсутствии результатов до первого поиска | -| Документ | Нет пустых селектов и активных бесполезных действий до выбора | -| Колонки | Drag и клавиатура работают; min/max соблюдаются; скрытие/возврат и сброс сохраняют контекст | -| Телефон | Основные действия видимы без горизонтального скролла, есть возврат из документа/фильтров | -| Окна | Заголовок, крестик, Escape, trap/return focus; нет невидимого окна поверх целевого | -| Лаборатория | Поиск → чтение → оценка → черновик → сохранение, панель до footer, данные не теряются | -| Локализация | RU/KY-подписи, Ө ө Ү ү Ң ң, язык UI не подменяет язык документа | -| Типографика | Реально загрузились Noto, основной текст 17–18 px / 1.6–1.7, длинные названия читаемы | -| Таблицы | Собственная обозначенная прокрутка, основной текст и controls без обрезки | -| Доступность | Контраст WCAG AA, видимый фокус, Tab/Shift+Tab/Enter/Escape, zoom/reflow, reduced motion | -| Авторизация | Проверены вход, неверный пароль, истечение сессии и обязательная смена в безопасном тестовом окружении | -| Снимки | 1440×900, 1280×800, 1024×768, 390×844; дополнительно 320 CSS px для reflow | - -Для визуального сравнения использовать изолированный детерминированный fixture -и одинаковые состояния, а не изменчивую выдачу. Fixture не включается в -production-путь и не обходит авторизацию. Сравнивать отдельно шапку, -фильтры, выдачу, документ, окна, сохранение и footer. Сглаживание текста -не требует нулевого pixel diff; совпадение растра не оправдывает обрезку, -неработающий control или нечитаемый реальный контент. - -Локальные проверки, указанные в PR, включая Playwright, прошли. Changelog -обновлён в этой ветке. Дальше остаются CI и ручное PR review по обычному -процессу репозитория; автоматический reviewer не запускается. Production не -меняется автоматически. - -## 8. Материалы и оставшаяся проверка - -Figma содержит целевые редактируемые состояния, а не исправленный live-сайт -и не доказательство работоспособности функций. Учётные записи в ней -обезличены, текст документа помечен как пример оформления. - -| Figma-экран | Ссылка | -|---|---| -| 01. Поиск с документом, 1440×900 | [Открыть](https://www.figma.com/design/3PE98PJYOXo7a35u2X5VqB?node-id=3-2) | -| 02. Фильтры скрыты | [Открыть](https://www.figma.com/design/3PE98PJYOXo7a35u2X5VqB?node-id=3-173) | -| 03. Начальный поиск | [Открыть](https://www.figma.com/design/3PE98PJYOXo7a35u2X5VqB?node-id=3-288) | -| 04. Лаборатория и доступное сохранение | [Открыть](https://www.figma.com/design/3PE98PJYOXo7a35u2X5VqB?node-id=3-395) | -| 05. Кабинет: профиль и закрытие | [Открыть](https://www.figma.com/design/3PE98PJYOXo7a35u2X5VqB?node-id=5-30) | -| 06. Кабинет: безопасность | [Открыть](https://www.figma.com/design/3PE98PJYOXo7a35u2X5VqB?node-id=5-229) | -| 07. Источники | [Открыть](https://www.figma.com/design/3PE98PJYOXo7a35u2X5VqB?node-id=5-428) | -| 08. Пользователи: отдельный экран | [Открыть](https://www.figma.com/design/3PE98PJYOXo7a35u2X5VqB?node-id=5-605) | -| 09–11. Телефон: выдача, чтение, фильтры | [Открыть](https://www.figma.com/design/3PE98PJYOXo7a35u2X5VqB?node-id=5-670) | -| 12. Эталон 1280×800 | [Открыть](https://www.figma.com/design/3PE98PJYOXo7a35u2X5VqB?node-id=7-74) | -| 13. Планшет: две панели | [Открыть](https://www.figma.com/design/3PE98PJYOXo7a35u2X5VqB?node-id=7-245) | -| 14. Кабинет на телефоне | [Открыть](https://www.figma.com/design/3PE98PJYOXo7a35u2X5VqB?node-id=7-360) | -| 15. Вход, создание и подтверждение удаления | [Открыть](https://www.figma.com/design/3PE98PJYOXo7a35u2X5VqB?node-id=8-118) | - -Макеты построены редактируемыми текстами, Auto Layout, SVG, локальными -переменными цветов/отступов и экземплярами общих кнопок; целый интерфейс -не вставлен одной картинкой. Прокрутка длинной выдачи/текста в Figma -обозначает намеренное продолжение содержимого. Drag-разделители, -закрытие и формы — спецификация будущего поведения, не работающий web-код. - -Локальные экспорты целевых экранов для просмотра без Figma: -[поиск](../design/tunduk-search-target.png), -[лаборатория](../design/tunduk-review-target.png), -[кабинет](../design/tunduk-account-target.png). - -Контрольные свидетельства live-сайта: -[поиск с кодексом](../design/audit-2026-10-23/search-document-1440.png), -[мобильный поиск](../design/audit-2026-10-23/search-mobile-390.png), -[фильтры телефона](../design/audit-2026-10-23/filters-mobile-390.png), -[кабинет](../design/audit-2026-10-23/account-desktop.png), -[кабинет телефона](../design/audit-2026-10-23/account-mobile-390.png), -[лабораторный документ](../design/audit-2026-10-23/review-document-1440.png). - -Browser evidence текущей ветки: -[desktop 1280×800](visual-review/desktop-1280x800.png), -[mobile 390 px](visual-review/mobile-390px.png), -[Figma overlay](visual-review/overlay-50.png) и -[pixel difference](visual-review/pixel-difference.png). Overlay показывает -различия компоновки между live-target frame и deterministic fixture; pixel -diff не используется как pass/fail. - -Регрессия UI10: сетка поиска остаётся двухпанельной на ширине 1101 и 1175 px; -третья панель включается при 1176 px, когда минимальные ширины трёх колонок -помещаются. Проверка также меняет ширину окна при скрытых фильтрах и проверяет -отсутствие горизонтального переполнения. Реальные browser zoom и экспертиза -юридической корректности по законодательству не подтверждены этими тестами. - -Не проверялись реальные destructive/auth-сценарии: вход с неверным паролем, -смена пароля, удаление/создание пользователей и отправка оценки в production. -Наличие макета не считается доказательством этих функций. -- 2.54.0 From 3fd5695bb222bd8bd6178374db2ba1aa5afa9fef Mon Sep 17 00:00:00 2001 From: Codex Date: Mon, 2 Nov 2026 23:41:46 +0300 Subject: [PATCH 2/9] Clarify roadmap source history --- docs/product/implementation-roadmap.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/product/implementation-roadmap.md b/docs/product/implementation-roadmap.md index 7ac9a74..24ef45c 100644 --- a/docs/product/implementation-roadmap.md +++ b/docs/product/implementation-roadmap.md @@ -152,8 +152,8 @@ follow-up по поиску, кабинету и лаборатории, лок #### Реализация, зафиксированная в текущем плане `main` -Документ `interface-correction-plan.md` на базовом commit этого PR отмечает -UI-01—UI-33 реализованными в PR #54. Он связывает группы изменений с +UI-план, находившийся на базовом commit этого PR, отмечает UI-01—UI-33 +реализованными в PR #54 и связывает группы изменений с регрессионными сценариями: | Пункты | Изменение, зафиксированное в плане `main` | Regression evidence, указанное там | -- 2.54.0 From 3eba203009dacc1c4a1f03c0c0c7a677a6cc0d35 Mon Sep 17 00:00:00 2001 From: Codex Date: Mon, 2 Nov 2026 23:43:11 +0300 Subject: [PATCH 3/9] Complete transferred UI and operational criteria --- docs/product/implementation-roadmap.md | 91 ++++++++++++++++++++------ 1 file changed, 71 insertions(+), 20 deletions(-) diff --git a/docs/product/implementation-roadmap.md b/docs/product/implementation-roadmap.md index 24ef45c..08cf289 100644 --- a/docs/product/implementation-roadmap.md +++ b/docs/product/implementation-roadmap.md @@ -71,6 +71,11 @@ follow-up по поиску, кабинету и лаборатории, лок этой документационной задаче. Сверяться с [отчётом visual-review](visual-review/README.md); не открывать снова выполненные пункты без нового воспроизводимого свидетельства. +В исходном реестре **P1** означает обязательное исправление до визуальной +приёмки/выпуска, **P2** — существенное улучшение понятности и +последовательности. Отсутствие функции само по себе не считается багом; +обозначенные целевые корректировки требуют подтверждения по коду и дизайну. + | ID | Приоритет | Историческое наблюдение 23.10.2026 | Требование / критерий | |---|---|---|---| | UI-01 | P1 | При пустом запросе одновременно показывались подсказка и empty-состояние | Разделить initial/loading/results/empty/error; empty показывать после завершённого поиска | @@ -118,12 +123,30 @@ follow-up по поиску, кабинету и лаборатории, лок значения, pointer drag и управление стрелками клавиатуры. Отдельные кнопки скрытия/показа фильтров и сброса ширины обязательны; двойной клик не заменяет доступный сброс. Сохранённая ширина ограничивается текущим viewport. +- Остальные правила сетки: фильтры не становятся постоянно прокручиваемой + узкой колонкой; полный каталог значений всегда достижим; API single-select не + изображается множественными checkbox. Длинное название органа читается в + панели выбора полностью. Поля дат имеют постоянные «От» / «До» и переходят + в столбец, когда не помещаются. На desktop выдача и документ могут иметь + отдельную вертикальную прокрутку с доступными заголовком/toolbar; на mobile + основной поток вертикальный с отдельными панелями. Footer использует + растущий main (`min-height: 100dvh`), не перекрывает контент и следует за ним; + панель сохранения имеет собственное место. - **Панели и формы:** понятный заголовок и крестик 44×44; именованный modal dialog, фокус внутри, Tab/Shift+Tab без выхода в фон, Escape там, где закрытие - допустимо, возврат фокуса инициатору. Не наслаивать кабинет и пользователей. - Права по-прежнему проверяет сервер; пароли не предзаполнять и не сохранять в - материалах аудита. Ошибки сохраняют допустимый ввод, loading исключает - повторную отправку. + допустимо, возврат фокуса инициатору; фон не интерактивен. Не наслаивать + кабинет и пользователей. Профиль и безопасность — отдельные разделы; права + по-прежнему проверяет сервер. В форме пароля постоянные подписи, требования, + доступное показать/скрыть и подтверждение нового пароля. Пароли не + предзаполнять и не сохранять в материалах аудита; ввод выполняет человек. +- Основное действие одно; отмена вторична, выход отдельно; Enter отправляет + только активную форму. Ошибка у поля и в доступном сообщении, допустимый ввод + сохраняется, loading исключает повторную отправку. Несохранённое редактирование + защищено от случайной потери, обычный просмотр закрывается без лишнего + подтверждения. После успеха сообщается результат, при ошибке есть путь + восстановления; состояние не кодируется одним цветом. +- Правила применяются к кабинету, входу, обязательной смене пароля, источникам, + созданию/сбросу/удалению пользователя, обучению и просмотру документа. - **Приёмка:** единая оболочка/header/footer; нет общей горизонтальной прокрутки; initial не сообщает об empty до поиска; действия документа активируются по состоянию; keyboard и touch работают; RU/KY подписи и язык @@ -180,21 +203,35 @@ UI-план, находившийся на базовом commit этого PR, физический touch и полный ручной лингвистический review в исходном плане оставлены непроверенными. -Отдельный follow-up плана `main` описывает последующие изменения: статус -«Открыт» выставляется после успешной загрузки; оглавление распознаёт RU/KY -структурные заголовки и избегает дублирования упоминаний; размеры и положение -языкового выбора, фильтров и splitter скорректированы. В кабинете выровнены -пары профильных значений, сохранены семантические ссылки и доступность перехода -к пользователям. В лаборатории выровнены оболочка, форма, рабочая область, -сохранение и footer; mobile возвращается к естественному потоку документа. -Исходный план сообщает о локальной проверке 24 октября 2026 года; статус CI и -review относится к конкретному pushed SHA и должен подтверждаться отдельно. +Отдельный follow-up в плане `main` описывает реализованные после PR #54 +корректировки и regression coverage: -В актуальном плане `main` follow-up обозначен как реализованный; там указано, -что frontend был повышен до `0.3.0` из-за регулируемой ширины панелей. Текущий -source footer и версия кода — `0.3.3`. Историческую отметку «ожидаются CI и -review» из старого плана нельзя использовать как статус сегодняшнего PR: она -относилась к конкретному SHA на момент записи. +- **Поиск:** «Открыт» сбрасывается при смене результата/редакции и ставится + только после успешной загрузки. Оглавление распознаёт самостоятельные + заголовки RU/KY из структурированных абзацев (`p > b > span`), задаёт + уникальные якоря и вложенность, не принимает обычные упоминания за заголовки. + Выбор языка поиска находится в фильтрах и не обрезается; декоративный SVG и + пустое резервное место удалены; активная навигация использует палитру. + Проверены ошибки и гонки загрузки, структура заголовков, splitter и + доступность диапазона его ширины. +- **Кабинет:** ссылки действий сохраняют `` семантику, крестик остаётся + подписанной SVG-кнопкой 44×44, значения профиля стоят в парах «поле—значение», + длинные значения переносятся, заголовок компактнее; администратору явно + доступно «Управление пользователями». Проверены RU/KY, отсутствие ссылки у + не-администратора, фокус/закрытие и ширина. +- **Лаборатория:** имя показывается без дублирующей роли; ссылки навигации имеют + вид кнопок; оболочка, форма, рабочая область, сохранение и footer выровнены. + Пустой live status не резервирует высоту, результаты и документ образуют + общую поверхность с внутренней прокруткой на desktop, заголовок использует + доступную ширину, а mobile возвращается к естественному потоку. Проверены + desktop/mobile, пустой status, сохранение после длинного документа и page + overflow. + +Исходный план сообщает о локальной проверке этих изменений 24 октября 2026 +года и повышении frontend до `0.3.0` из-за регулируемой ширины панелей. Текущий +source footer и версия кода — `0.3.3`. Его отметка «ожидаются CI и review» +относилась к конкретному pushed SHA и не задаёт статус этого или любого нового +PR. #### Общие критерии окон и форм @@ -229,6 +266,9 @@ review» из старого плана нельзя использовать к версию только при изменении кода, а changelog — после зелёных проверок и разрешения blocking findings. +Не переносить существующий Python frontend на React/Next.js ради визуальной +корректировки. UI-работа не меняет ранжирование, корпус или права доступа. + | Приёмка | Условие | |---|---| | Оболочка | Один header/footer на маршруте, единые границы и порядок контента | @@ -267,7 +307,10 @@ review» из старого плана нельзя использовать к 4. **Первое применение:** до запуска проверить реальные данные и конфигурацию, требуемое свободное место, открытые порты, права, backup readiness и совместимость схем. Выполнять через существующую ограниченную - процедуру; не добавлять общие sudo/Docker-привилегии. + процедуру; не добавлять общие sudo/Docker-привилегии. Базы данных и + внутренние сервисы не публиковать в интернет. DNS, reverse proxy и TLS + проверять до выпуска; для Cloudflare применять Full (strict). SSH/UFW и + сетевые ограничения меняются только после owner approval. 5. **Проверка и recovery:** проверять health/API, RU/KY canaries, доступность HTTPS, сохранность данных и rollback в пределах его документированных ограничений. Data restore — отдельная процедура в staging, не автоматический @@ -312,6 +355,12 @@ production CD остаётся неактивным, а backup/restore и вне [кабинет](../design/tunduk-account-target.png). Это изображения цели; они не заменяют браузерную проверку. +В Figma экраны собраны из редактируемого текста, Auto Layout, SVG, локальных +переменных цвета/отступов и общих экземпляров кнопок; это не один растр. +Прокрутка длинной выдачи/текста показывает продолжение содержимого. +Splitter, закрытие и формы описывают целевое поведение, но не являются +работающим web-кодом. + ### Исторические свидетельства Аудит UI выполнен **23 октября 2026 года** в авторизованной сессии на @@ -337,4 +386,6 @@ production CD остаётся неактивным, а backup/restore и вне CI и независимое review. Инфраструктурные изменения отражаются в `CURRENT_STATE.md` только по фактическим проверкам. Никакие действия с production, секретами, пользователями или правовым корпусом не следуют из -наличия этого документа. +наличия этого документа. Root-only bootstrap и предоставление секретов +выполняет/утверждает владелец в защищённой среде; DEV готовит проверяемый код +и точный план, reviewer независимо проверяет безопасность и failure paths. -- 2.54.0 From ba9564fca2442ad19bb2bbaf4bc226696f9bfc12 Mon Sep 17 00:00:00 2001 From: Codex Date: Mon, 2 Nov 2026 23:44:57 +0300 Subject: [PATCH 4/9] Narrow scratch ignores and clarify shared mockup --- .gitignore | 4 ++-- docs/product/implementation-roadmap.md | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index f2b7c1b..4f7aca6 100755 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,6 @@ data/ # Local runtime logs logs/ -# Local benchmark and scratch output (historical tracked evidence remains tracked) -/reports/ +# Transient local scratch output; keep reports/ reviewable by default +/reports/tmp/ /tmp/ diff --git a/docs/product/implementation-roadmap.md b/docs/product/implementation-roadmap.md index 08cf289..c3803e7 100644 --- a/docs/product/implementation-roadmap.md +++ b/docs/product/implementation-roadmap.md @@ -342,9 +342,7 @@ production CD остаётся неактивным, а backup/restore и вне | 06. Кабинет: безопасность | [Figma](https://www.figma.com/design/3PE98PJYOXo7a35u2X5VqB?node-id=5-229) | | 07. Источники | [Figma](https://www.figma.com/design/3PE98PJYOXo7a35u2X5VqB?node-id=5-428) | | 08. Пользователи: отдельный экран | [Figma](https://www.figma.com/design/3PE98PJYOXo7a35u2X5VqB?node-id=5-605) | -| 09. Телефон: выдача | [Figma](https://www.figma.com/design/3PE98PJYOXo7a35u2X5VqB?node-id=5-670) | -| 10. Телефон: чтение | [Figma](https://www.figma.com/design/3PE98PJYOXo7a35u2X5VqB?node-id=5-670) | -| 11. Телефон: фильтры | [Figma](https://www.figma.com/design/3PE98PJYOXo7a35u2X5VqB?node-id=5-670) | +| 09–11. Телефон: выдача, чтение и фильтры (общий Figma-узел) | [Figma](https://www.figma.com/design/3PE98PJYOXo7a35u2X5VqB?node-id=5-670) | | 12. Эталон 1280×800 | [Figma](https://www.figma.com/design/3PE98PJYOXo7a35u2X5VqB?node-id=7-74) | | 13. Планшет: две панели | [Figma](https://www.figma.com/design/3PE98PJYOXo7a35u2X5VqB?node-id=7-245) | | 14. Кабинет на телефоне | [Figma](https://www.figma.com/design/3PE98PJYOXo7a35u2X5VqB?node-id=7-360) | @@ -357,6 +355,7 @@ production CD остаётся неактивным, а backup/restore и вне В Figma экраны собраны из редактируемого текста, Auto Layout, SVG, локальных переменных цвета/отступов и общих экземпляров кнопок; это не один растр. +Состояния 09–11 ведут на один общий мобильный узел, как в исходном плане. Прокрутка длинной выдачи/текста показывает продолжение содержимого. Splitter, закрытие и формы описывают целевое поведение, но не являются работающим web-кодом. -- 2.54.0 From 4cf96e3fa9ef95873657284af954c9ab3b629683 Mon Sep 17 00:00:00 2001 From: Codex Date: Mon, 2 Nov 2026 23:58:47 +0300 Subject: [PATCH 5/9] Address documentation roadmap review findings --- .gitignore | 4 +- docs/product/implementation-roadmap.md | 70 ++++++++++++++++++++++++-- 2 files changed, 67 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index 4f7aca6..0682263 100755 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,6 @@ data/ # Local runtime logs logs/ -# Transient local scratch output; keep reports/ reviewable by default -/reports/tmp/ +# Local generated reports; deliberately publish reviewed/sanitized evidence with git add -f +/reports/ /tmp/ diff --git a/docs/product/implementation-roadmap.md b/docs/product/implementation-roadmap.md index c3803e7..468295f 100644 --- a/docs/product/implementation-roadmap.md +++ b/docs/product/implementation-roadmap.md @@ -71,6 +71,14 @@ follow-up по поиску, кабинету и лаборатории, лок этой документационной задаче. Сверяться с [отчётом visual-review](visual-review/README.md); не открывать снова выполненные пункты без нового воспроизводимого свидетельства. +Источники по состоянию на базовый commit этого PR сохранены постоянными +ссылками: [UI-план на `7ece39f`](https://git.vakanaut.ru/admin/akyldash/src/commit/7ece39f212b67e497a8dfb360d5d271ab088ef57/docs/product/interface-correction-plan.md) +и [план pixel-perfect на `7ece39f`](https://git.vakanaut.ru/admin/akyldash/src/commit/7ece39f212b67e497a8dfb360d5d271ab088ef57/docs/product/frontend-pixel-perfect-plan.md). +UI-01—UI-33 вошли в [PR #54](https://git.vakanaut.ru/admin/akyldash/pulls/54) +(merge commit [`01380d3c`](https://git.vakanaut.ru/admin/akyldash/commit/01380d3c09d71e32c965d974a39a4d82de0a15c5)); +последующий follow-up поиска, кабинета и лаборатории записан в +[commit `e5a8326a`](https://git.vakanaut.ru/admin/akyldash/commit/e5a8326a5e3def1bf5d5dc94794da82a2af801ab). + В исходном реестре **P1** означает обязательное исправление до визуальной приёмки/выпуска, **P2** — существенное улучшение понятности и последовательности. Отсутствие функции само по себе не считается багом; @@ -280,11 +288,30 @@ PR. | Окна | Заголовок, крестик, Escape, trap/return focus; окна не конкурируют слоями | | Лаборатория | Поиск → чтение → оценка → черновик → сохранение; текст не теряется, панель доступна при длинном документе | | Локализация | RU/KY labels и символы; язык UI не подменяет язык документа | +| Геометрия | При 1280×800 границы основных зон и отступы/размеры controls отличаются от измеренного fixture не более чем на 2 CSS px; согласованные исключения описаны | | Типографика и таблицы | Noto действительно загружается; читаемый длинный текст; у широкой таблицы собственный скролл | | Доступность | Контраст AA, focus, Tab/Shift+Tab/Enter/Escape, zoom/reflow, reduced motion и touch targets | | Авторизация | Неверный пароль, expired session и обязательная смена проверены только в безопасном тестовом контуре | | Снимки | 1440×900, 1280×800, 1024×768, 390×844 и 320 CSS px; стабильные fixture и объяснённые различия | +Допуск **до 2 CSS px** для границ крупных зон и отступов/размеров controls при +1280×800 перенесён из исторического pixel-perfect плана по стабильной ссылке +выше. Он применяется к одинаковым детерминированным fixture; расхождения +растра, вызванные сглаживанием текста или содержимым, сами по себе не дают +основания обрезать или уплотнять юридический текст. + +#### Нормативный орнамент и фактическое состояние + +`DESIGN.md` нормативно требует небольшой золотистый SVG-орнамент в свободной +нижней части desktop-панели фильтров, не перекрывающий длинные списки и не +резервирующий место за счёт управления. Follow-up из commit `e5a8326a` удалил +предыдущий декоративный SVG и его пустой резерв; в `backend/search/review.html` +на базовом `main` целевого орнамента нет. Это не выполненное требование, а +подтверждённое расхождение между `DESIGN.md` и реализацией. Дизайн остаётся +нормативным до отдельного решения владельца: UI-задача должна либо вернуть +орнамент в свободную область без влияния на управление, либо получить явное +одобрение на изменение `DESIGN.md` и подтвердить его визуальной приёмкой. + ### 2.3 Инфраструктура и переход к production Инфраструктурные источники содержали повторяющиеся этапы deployment и @@ -304,11 +331,16 @@ PR. Публикация образов должна фиксировать digest и provenance; release workflow не равен deployment. Production CD не включать до прохождения owner gates, безопасной сборки, backup и отдельного restore. -4. **Первое применение:** до запуска проверить реальные данные и - конфигурацию, требуемое свободное место, открытые порты, права, backup - readiness и совместимость схем. Выполнять через существующую ограниченную - процедуру; не добавлять общие sudo/Docker-привилегии. Базы данных и - внутренние сервисы не публиковать в интернет. DNS, reverse proxy и TLS +4. **Контролируемое изменение существующего production:** последняя датированная + проверка `https://akyldash.kg/review` вернула HTTP 200 25 октября 2026 года + ([CURRENT_STATE](../operations/CURRENT_STATE.md)); установленный на хосте + SHA остался неизвестен. План относится к безопасному + обновлению существующего сервиса, а не к первому развёртыванию. До изменения + проверять реальные данные и конфигурацию, доступное место, опубликованные + порты, права, совместимость схем и backup readiness. Выполнять через + существующую ограниченную процедуру; не добавлять общие sudo/Docker- + привилегии. Базы данных и внутренние сервисы не публиковать в интернет. + DNS, reverse proxy и TLS проверять до выпуска; для Cloudflare применять Full (strict). SSH/UFW и сетевые ограничения меняются только после owner approval. 5. **Проверка и recovery:** проверять health/API, RU/KY canaries, доступность @@ -320,6 +352,34 @@ PR. health gates и отказ без destructive cleanup. Не включать триггер только потому, что workflow завершился зелёным. +**Backup/maintenance gate:** настройки CI, проверка конфигурации и подготовка +release provenance должны быть отделены от production cutover. Production CD +в `CURRENT_STATE.md` остаётся неактивным. Перед каждым фактическим production +изменением, включая миграции, создать и проверить внешний pre-change backup. +Полный cold backup требует остановки Compose и может выполняться только в +заранее согласованное с владельцем окно. +Ни полный архив, ни его временная копия никогда не записываются на VPS. По +текущей утверждённой схеме архив передаётся напрямую на фиксированный +`D:\Dev\akyldash\.backups`; фактическая готовность D:, SSH и отдельное +восстановление всё ещё не подтверждены. На VPS остаётся только secret-free +идентификатор/manifest согласно `BACKUP.md`. Политика — одна retained, +проверенная внешняя копия. При замене прежняя копия сохраняется до тех пор, +пока новый candidate не опубликован и не проверен; на время этой проверки две +копии могут сосуществовать. После подтверждения новой копии retention может +изменить только владелец явным решением; автоматическая очистка запрещена. +При неудачной публикации или проверке прежняя подтверждённая копия остаётся. +Локальные VPS cold-backup команды из старых документов superseded и +использоваться не должны. + +#### Локальные generated reports + +`/reports/` и `/tmp/` игнорируются по умолчанию, чтобы generated bulk не +попадал в обычный `git status`. Уже отслеживаемые historical evidence остаются +отслеживаемыми. Если конкретный отчёт нужен в Git, сначала проверить его +содержимое, удалить секреты, персональные данные, production corpus и +временные файлы, затем добавить только предназначенный к публикации файл +явной командой `git add -f reports/`. Не добавлять каталоги целиком. + Нынешний статус не переопределяется этим roadmap: на сверенной документации production CD остаётся неактивным, а backup/restore и внешний bootstrap имеют непроверенные owner prerequisites. Все точные блокировки сверять с -- 2.54.0 From ee03dc6cc77b0a82a82aebbe7bf9912ce2fe1a4d Mon Sep 17 00:00:00 2001 From: Codex Date: Tue, 3 Nov 2026 00:11:52 +0300 Subject: [PATCH 6/9] Clarify data pipeline versions and corpus handoff gate --- README.md | 4 +++- backend/README.md | 5 +++++ docs/README.md | 4 +++- docs/product/implementation-roadmap.md | 11 +++++++++-- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index d5a9a75..ba77460 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,9 @@ SQLite; первый пользователь `admin` создаётся инт | Telegram-бот | `0.2.2` | исходный код; последняя заметка о Synology указывает `0.2.1`, актуальность не перепроверена | | Search API | `0.13.3` | авторизация, серверная capability управления пользователями, поиск и статические ресурсы | | Frontend | `0.3.3` | поиск по правовой базе, просмотр редакций, внутренняя лаборатория и контекстная навигация кабинета | -| Сбор и обработка правовых данных | `0.8.0` | добавлены relevance set и оценка выдачи | +| Загрузчик архива Минюста (`backend/ingestion/minjust_cbd.py`) | `0.9.3` (`APP_VERSION`) | версия CLI и User-Agent в исходном коде | +| Нормализатор корпуса (`backend/normalization/minjust_cbd.py`) | CLI `0.10.0` (`APP_VERSION`); формат/алгоритм `1.1.0` (`NORMALIZER_VERSION`) | версия инструмента и версия нормализатора в manifest — разные значения | +| Оценка релевантности | формат набора `relevance-set-v1` | отдельная версия компонента не задана; CLI использует Search API `0.13.3` | | RAG и база знаний | — | ещё не созданы | ## Структура репозитория diff --git a/backend/README.md b/backend/README.md index 3e7ae87..97d581f 100644 --- a/backend/README.md +++ b/backend/README.md @@ -6,6 +6,11 @@ Open Data API ЦБД Минюста Кыргызской Республики. Код расположен в `ingestion/minjust_cbd.py`: его можно запускать как CLI сейчас и импортировать из будущего планировщика backend без запуска отдельного процесса. +Для передачи корпуса в production обязательна отдельная процедура +[CORPUS_HANDOFF.md](../docs/operations/CORPUS_HANDOFF.md); она проверяет +source/staging, inventory и checksum, решение по code 6, публикацию и +готовность индекса. Этот runbook — release gate; команды передачи здесь не +дублируются. ## Пробная загрузка diff --git a/docs/README.md b/docs/README.md index 32b152e..0b1ada8 100644 --- a/docs/README.md +++ b/docs/README.md @@ -37,7 +37,9 @@ доступы, deployment, backup, rollback и recovery. - [Операционные процедуры](operations/DEPLOYMENT.md) — связанные инструкции по deployment, [backup](operations/BACKUP.md), [rollback](operations/ROLLBACK.md), - [recovery](operations/RECOVERY.md) и [пакет владельца](operations/DEPLOYMENT_OWNER_PACKET.md). + [recovery](operations/RECOVERY.md), обязательная процедура + [передачи корпуса](operations/CORPUS_HANDOFF.md) и + [пакет владельца](operations/DEPLOYMENT_OWNER_PACKET.md). - [План Telegram-пространства](operations/telegram-workspace-plan.md) — темы, роли и этапы развития командного окружения. diff --git a/docs/product/implementation-roadmap.md b/docs/product/implementation-roadmap.md index 468295f..62e5675 100644 --- a/docs/product/implementation-roadmap.md +++ b/docs/product/implementation-roadmap.md @@ -325,8 +325,15 @@ PR. DNS-статус или ресурсы из старых планов как текущие факты. 2. **Данные и конфигурация:** установить источник и допустимость корпуса, формат, состав, checksum/manifest, размер и воспроизводимую цепочку импорта. - Не подменять корпус пустым каталогом. Production env/секреты создаются вне - Git; в репозитории остаются только имена переменных и шаблоны без значений. + Обязательный gate любой передачи/публикации корпуса — процедура + [CORPUS_HANDOFF.md](../operations/CORPUS_HANDOFF.md): source → staging → + inventory/manifest и checksum comparison → безопасная публикация → проверка + индекса/alias. Она требует непустые source и staging, явное решение по + исключению code 6 и fail-closed при неполных/несовпадающих данных. Следовать + runbook без копирования его команд сюда; до прохождения gate корпус в + production не передавать и не индексировать. Не подменять корпус пустым + каталогом. Production env/секреты создаются вне Git; в репозитории остаются + только имена переменных и шаблоны без значений. 3. **Build/CI:** PR-проверки не получают production secrets и Docker socket. Публикация образов должна фиксировать digest и provenance; release workflow не равен deployment. Production CD не включать до прохождения owner gates, -- 2.54.0 From 849c7537ed134831a8da46999d5cbdde1772e4bb Mon Sep 17 00:00:00 2001 From: Codex Date: Tue, 3 Nov 2026 00:18:06 +0300 Subject: [PATCH 7/9] Document atomic corpus publication gate --- docs/operations/CORPUS_HANDOFF.md | 29 ++++++++++++++++++++++++-- docs/product/implementation-roadmap.md | 19 ++++++++++------- 2 files changed, 39 insertions(+), 9 deletions(-) diff --git a/docs/operations/CORPUS_HANDOFF.md b/docs/operations/CORPUS_HANDOFF.md index 12b5207..a6525ec 100644 --- a/docs/operations/CORPUS_HANDOFF.md +++ b/docs/operations/CORPUS_HANDOFF.md @@ -168,8 +168,33 @@ backed up, resolve the raw code `6` finding, and approve the exact normalized corpus to use. Transfer only `minjust-normalized/`; keep the raw source archive offline. Do not preserve the source's Windows/WSL file permission bits. Copy to a new staging location with owner-approved permissions, verify the copied -manifest and files there, and only then consider placing it under `DATA_ROOT`. -Never overwrite an existing corpus or OpenSearch volume. +manifest and files there, and only then consider publishing it under +`DATA_ROOT/minjust-normalized`. + +### Atomic publication gate for `DATA_ROOT` + +The verified staging tree must be published to +`DATA_ROOT/minjust-normalized` as one all-or-nothing operation, using an +owner-approved atomic mechanism or a separately documented equivalent. An +in-place copy into the live target is not an acceptable publication method. +Preserve the current published corpus until the candidate is fully verified and +ready for the atomic switch; never overwrite its contents in place. +The publication mechanism and its interrupted-operation recovery have not yet +been specified or tested; this is a release gate, not a claim that atomic corpus +publication is implemented. Until that gate is completed, do not publish or +replace a corpus in `DATA_ROOT`. + +If preparation is interrupted before publication, keep the current target +untouched. Resume only from the isolated staging tree after a full rehash and +source comparison; if that cannot be established, fail closed and prepare a +new staging candidate. If interruption makes the outcome of the final +publication ambiguous, do not retry or replace anything automatically. Verify +the target against the approved manifest and resolve the state with the owner +before any retry. Never overwrite an existing corpus or OpenSearch volume. + +The atomic filesystem publication of the approved corpus into `DATA_ROOT` and +the OpenSearch alias switch are separate gates. A successful corpus publish +does not authorize indexing or alias changes; do not conflate the two. The bulk importer now refuses alias publication until all Bulk item results are successful, the full staged index is refreshed, its fragment count exactly diff --git a/docs/product/implementation-roadmap.md b/docs/product/implementation-roadmap.md index 62e5675..94a823e 100644 --- a/docs/product/implementation-roadmap.md +++ b/docs/product/implementation-roadmap.md @@ -327,13 +327,18 @@ PR. формат, состав, checksum/manifest, размер и воспроизводимую цепочку импорта. Обязательный gate любой передачи/публикации корпуса — процедура [CORPUS_HANDOFF.md](../operations/CORPUS_HANDOFF.md): source → staging → - inventory/manifest и checksum comparison → безопасная публикация → проверка - индекса/alias. Она требует непустые source и staging, явное решение по - исключению code 6 и fail-closed при неполных/несовпадающих данных. Следовать - runbook без копирования его команд сюда; до прохождения gate корпус в - production не передавать и не индексировать. Не подменять корпус пустым - каталогом. Production env/секреты создаются вне Git; в репозитории остаются - только имена переменных и шаблоны без значений. + inventory/manifest и checksum comparison → атомарная публикация + проверенного staging-корпуса в `DATA_ROOT/minjust-normalized` → отдельная + проверка и импорт в индекс → OpenSearch alias switch. Runbook требует + непустые source и staging, явное решение по исключению code 6 и fail-closed + при неполных/несовпадающих данных. Атомарная файловая публикация и + возобновление/отказ после прерывания — обязательный, но ещё не реализованный + gate; до описания и проверки all-or-nothing механизма не заменять им + действующий корпус. Не смешивать его с атомарным переключением OpenSearch + alias. Следовать runbook без копирования его команд сюда; до прохождения + gates корпус в production не передавать и не индексировать. Не подменять + корпус пустым каталогом. Production env/секреты создаются вне Git; в + репозитории остаются только имена переменных и шаблоны без значений. 3. **Build/CI:** PR-проверки не получают production secrets и Docker socket. Публикация образов должна фиксировать digest и provenance; release workflow не равен deployment. Production CD не включать до прохождения owner gates, -- 2.54.0 From 7437aef346cd103a4f7f1d63cc5a48d319bf9ae0 Mon Sep 17 00:00:00 2001 From: Codex Date: Tue, 3 Nov 2026 00:22:21 +0300 Subject: [PATCH 8/9] Record documentation gates in changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d41e71f..42ee3a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ ## Не выпущено +- Документация: объединены продуктовый, UI- и deployment-планы; уточнены + внешняя backup-retention политика и обязательный owner-approved maintenance + window для cold backup. Передача корпуса требует атомарной публикации + проверенного staging в `DATA_ROOT`; безопасное возобновление либо fail-closed + при прерывании остаётся release gate. Механизм атомарной публикации ещё не + реализован. - Успешный CI на `push` в `main` запускает release workflow: при настроенных registry secrets он собирает образы rootless Kaniko, публикует digest references и сохраняет schema-v4 descriptor с SHA-256 в Gitea artifact; -- 2.54.0 From 9fc269283bba6e4298c7472304102b9d7e57ed60 Mon Sep 17 00:00:00 2001 From: codex Date: Tue, 3 Nov 2026 09:02:33 +0300 Subject: [PATCH 9/9] docs: align documentation footer versions --- docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index 0b1ada8..385bd98 100644 --- a/docs/README.md +++ b/docs/README.md @@ -55,4 +55,4 @@ --- -Акылдаш · Telegram-бот v0.2.2 · Backend v0.13.3 · Frontend v0.3.3 +Акылдаш · Telegram-бот v0.2.2 · Backend v0.13.4 · Frontend v0.3.4 -- 2.54.0