440 lines
45 KiB
Markdown
440 lines
45 KiB
Markdown
# Промт: сессия ФРОНТ TextMachine — MVP веб-интерфейса
|
||
|
||
## Область ЭТОЙ сессии — этапы S0 и S1, дальше не идти
|
||
|
||
Фронт режется на шесть сессий. Ты — первая. **Твоя работа кончается на витрине токенов, до единого
|
||
экрана приложения.** Это не осторожность: без проверяемой петли обратной связи и сошедшихся токенов
|
||
все следующие этапы слепы, а смешивание инструментальной работы с интерфейсной сжигает контекст.
|
||
|
||
| Этап | Что | Сессия |
|
||
|---|---|---|
|
||
| **S0** | Планирование: как писать фронт. Пины версий, карта файлов, правила, протокол проверки | **твоя** |
|
||
| **S1** | Инструменты, скриншот-цикл, `tokens.css`, витрина | **твоя** |
|
||
| S2 | Оболочка (три панели, вкладки, статус-полоса) + слой `src/ui/` | отдельная |
|
||
| S3 | Слой данных, MSW, фикстуры всех состояний | хвост S2 или отдельная |
|
||
| S4 | Библиотека, загрузка, разбор, прогресс перевода | отдельная |
|
||
| S5 | Банк памяти и подпись (самый тяжёлый) | отдельная |
|
||
| S6 | Читалка двух колонок и замечания | отдельная |
|
||
| S7 | Метаданные, экспорт, настройки, сквозной прогон | отдельная |
|
||
|
||
**S0 лендится отдельным коммитом до первой строки кода** — иначе план останется словами.
|
||
|
||
## Обязательное чтение перед работой
|
||
|
||
1. `frontend/docs/STACK_DECISIONS.md` — **пины версий и ловушки**. Все версии сверены 02.08.2026
|
||
многоагентным исследованием с адверсариальной проверкой. Не выбирай библиотеки сам,
|
||
не «обновляй» пины по памяти: твои знания об экосистеме устарели, а вся документация
|
||
в сети описывает ПРОШЛЫЕ версии этих инструментов.
|
||
2. `docs/product-requirements.md` — реестр продуктовых требований владельца.
|
||
3. `docs/glossary.md` — расшифровка проектных сокращений.
|
||
4. `frontend/references/*.png` — три скриншота, **открой и посмотри** (ты умеешь читать изображения).
|
||
|
||
## Кто ты и твоя зона
|
||
|
||
Ты фронтенд-сессия. **Зона записи — только `frontend/`.** `backend/`, `platform/`, `docs/`, `eval/` — read-only; расхождения и вопросы — пингом владельцу, не правкой чужой зоны.
|
||
|
||
### ⚠ Коммит-права и git-протокол (решение владельца 02.08, D39.88 — читать ДО первого коммита)
|
||
|
||
**Право коммита у тебя ЕСТЬ — но ровно на свою зону: «свою часть коммить, чужую не трогать НИКОГДА».**
|
||
|
||
1. **Коммить только пути внутри `frontend/`.** Ничего за её пределами — ни `docs/`, ни `backend/`, ни `platform/`, ни корневых файлов, ни `.gitignore`. Нужна правка вне зоны — пинг владельцу, её сделает оркестратор.
|
||
2. **Форма коммита — ТОЛЬКО с явным списком путей:** `git commit -- frontend/<файл> frontend/<файл>`. Это не стилистика, а механика: **голый `git commit` уносит ВЕСЬ индекс**, включая файлы, застейдженные параллельной сессией, — и чужая работа уезжает под твоим сообщением. Так уже произошло ДВАЖДЫ 02.08 (`e9a6bb2`, `b98afb5` унесли доки оркестратора). Pathspec-форма чужой индекс не трогает.
|
||
3. **НИКОГДА `git add -A`, `git add .`, `git commit -a`.** Только явные пути.
|
||
4. **Перед каждым коммитом:** `git status` (опознать чужое) → `git diff --cached --name-only`. Увидел в индексе чужой путь — **не «прибирай» его**, просто коммить pathspec-формой, и он останется на месте.
|
||
5. **Не оставляй свои файлы застейдженными** между шагами: пока они в индексе, их может унести чужой коммит. Стейдж и коммит — одной командой.
|
||
6. **НИКАКИХ** `reset --hard`, `amend`/`rebase` несвежих коммитов, `checkout` поверх грязного дерева, перезаписи истории. Параллельные сессии — норма, их незакоммиченные файлы не трогать.
|
||
7. **Чужое всё-таки уехало в твой коммит?** Историю НЕ переписывать — сообщить владельцу; содержимое цело, теряется только атрибуция.
|
||
8. Никогда не коммитить: `START_PROMT.MD` (файл владельца), `.claude/settings.local.json`.
|
||
|
||
Общие правила проекта — в `CLAUDE.md` в корне (там же эта норма в каноническом виде). Коммиты: английский, одно предложение ≤30 слов, без Co-Authored-By.
|
||
|
||
## Что за продукт
|
||
|
||
Веб-сервис перевода книг (веб-новеллы, ранобэ) с одного языка на другой через ИИ. Пользователь загружает книгу, запускает перевод, подписывает словарь терминов, читает результат, выгружает готовое.
|
||
|
||
**Бэкенда пока нет** — точнее, движок перевода есть, но HTTP-API к нему ещё не построено. Ты работаешь на моках (см. §6). Это не помеха: контракт данных зафиксирован ниже, замена моков на реальные запросы будет точечной.
|
||
|
||
> ⚠ **Поправка канона (фронт-сессия S1, 02.08).** Формулировка выше читается как «однажды у движка появится HTTP-API». Это не так, и ошибка дорогая: **API будет у платформы, не у движка**, а движок фронту не виден вообще. Прежде чем писать слой данных, прочитай `FRONTEND_PLAN.md` §0.1–0.2 (карта канона и два провода) и первоисточник `docs/research/23-engine-platform-seam.md`. Там же цена ошибки: моки, снятые не с того уровня контракта, разойдутся с API — ровно то, ради предотвращения чего заведена строка 95 единого бэклога.
|
||
|
||
---
|
||
|
||
## 1. Референсы — копировать, а не вдохновляться
|
||
|
||
В `frontend/references/` лежат три скриншота. **Открой их своим инструментом чтения файлов — ты умеешь смотреть изображения.** Это обязательный первый шаг, до единой строки кода.
|
||
|
||
- `fleet.png` — **главная основа макета**. Копируем оболочку целиком: как устроены панели, отступы, скругления, плотность, палитра.
|
||
- `antigravity_main.png` — пустое состояние (ничего не выбрано).
|
||
- `antigravity_chat.png` — рабочее состояние с тремя колонками и правой панелью-документом.
|
||
|
||
Владелец сформулировал прямо: **«взять макет Fleet как он есть по блокам и стилю и полностью скопировать, переделав под наши нужды»**. Это не тот случай, где нужна своя эстетика. Нужна чужая, воспроизведённая точно.
|
||
|
||
### 1.1. Измеренные значения — брать эти, не выводить свои
|
||
|
||
Ниже — не оценка на глаз, а **замер пикселей** `fleet.png` (Python/PIL: гистограмма поверхностей, поиск насыщенных пикселей, срез по горизонтали, детект края скругления). Скриншот снят при масштабе **2x** — установлено по кнопкам окна macOS: шаг 40 физических пикселей против штатных 20 CSS. Все размеры ниже уже переведены в CSS-пиксели.
|
||
|
||
**Поверхности Fleet:**
|
||
|
||
| Роль | Значение | Где замерено |
|
||
|---|---|---|
|
||
| Фон оболочки: промежутки, верхняя полоса, статус-полоса | `#090909` | 10.5% площади |
|
||
| Заливка панели (все три панели одинаковы) | `#17191a` | 80.5% площади |
|
||
| Приподнятая поверхность / наведение | `#27292b` | |
|
||
| Выбранная строка, активная вкладка | `#353739` | |
|
||
| Подсветка текущей строки (синеватая) | `#152945` | |
|
||
| Выделение | `#164e8d` | |
|
||
| Основной текст | `#dfe1e3` | |
|
||
| **Акцент (фокус ввода)** | **`#746deb`** | тон 243°, насыщенность 0.76 |
|
||
| Красный индикатора | `#b82e45` | тон 350° |
|
||
|
||
**Геометрия Fleet:**
|
||
|
||
- **Промежуток между панелями — ровно 8px**, одинаковый везде: слева, между всеми панелями, справа (замер среза: четыре промежутка по 16 физических пикселей, без единого исключения).
|
||
- **Радиус скругления панели — 6px** (край выходит на прямую за ~11 физических пикселей).
|
||
- Панели не имеют ни рамок, ни теней: отделение только промежутком и разницей заливки `#090909` → `#17191a`.
|
||
|
||
**Antigravity — для пустого состояния и настроек** (чистый нейтральный серый, без холодного оттенка, в отличие от Fleet):
|
||
|
||
| Роль | Значение |
|
||
|---|---|
|
||
| Фон | `#101010` |
|
||
| Боковая панель | `#161616` |
|
||
| Приподнятая карточка (поле ввода) | `#1c1c1c` |
|
||
| Заливка кнопки основного действия | `#252525` |
|
||
| Разделитель / граница | `#323232` |
|
||
| Текст | `#cecece` |
|
||
|
||
**Что НЕ замерено и требует проверки скриншот-циклом:** размеры шрифтов, высота строк, внутренние отступы панелей. Их снимай сам сравнением своей витрины с `fleet.png`.
|
||
|
||
### Что именно снято с `fleet.png` (следуй этому буквально)
|
||
|
||
**Оболочка.** Очень тёмный, почти чёрный фон окна. Панели лежат на нём **отдельными скруглёнными «карточками»** (радиус ~8–10px) с чуть более светлой заливкой, разделённые узкими промежутками фона ~6–8px. Теней нет вообще — разделение только промежутком и разницей заливки. Это главная визуальная подпись Fleet, и владельцу нравится именно она.
|
||
|
||
**Верхняя полоса.** Слева кнопки сворачивания панелей (левая / нижняя / правая), по центру — название текущего контекста, справа — ряд иконок-действий. Тонкие линейные монохромные иконки.
|
||
|
||
**Левая панель.** Сверху **ряд вкладок внутри самой панели** (`Files · Search · Git · History · +`) — не отдельный сайдбар с иконками, а вкладки в шапке панели. Ниже дерево: корень, узлы с шевронами, иконки типов, у выбранной строки — светлая скруглённая подложка (~6px), а не рамка.
|
||
|
||
**Центр.** Полоса вкладок: иконка + имя + крестик; активная вкладка светлее и скруглена. Ниже содержимое с колонкой номеров строк приглушённого цвета, у текущей строки — едва заметная подсветка всей полосы. Мелкие подписи-подсказки над блоками очень тусклым серым. В правом верхнем углу — компактный индикатор проблем.
|
||
|
||
**Нижняя панель центра** — отдельная скруглённая карточка со своей вкладкой.
|
||
|
||
**Правая панель.** Вкладка с заголовком и `+`. В пустом состоянии — центрированный блок: иконка, заголовок, описание, ряды «клавиша + подпись». Внизу поле ввода с **акцентной рамкой** — единственное цветное пятно в панели.
|
||
|
||
**Нижняя статус-полоса** лежит на фоне оболочки, вне карточек: слева хлебные крошки, справа компактные метаданные состояния.
|
||
|
||
**Цвет.** Практически монохром: серый текст на тёмном. Цвет встречается редко и всегда что-то означает. Акцент — один, холодный.
|
||
|
||
**Типографика.** Компактный чистый гротеск ~13px в интерфейсе, моноширинный в содержимом. Плотные строки.
|
||
|
||
### Что снято с `antigravity_main.png` — пустое состояние
|
||
|
||
Главная область почти пустая, и по её **центру стоит один составной блок** — скруглённая карточка ввода с подсказкой внутри и рядом мелких управляющих элементов по нижнему краю. Никаких иллюстраций, никаких «начните работу» с картинками. Просто действие по центру пустоты.
|
||
|
||
В левой панели: **выделенная кнопка основного действия во всю ширину сверху**, ниже пункты навигации с иконками, ниже секция-заголовок мелким приглушённым шрифтом с иконками действий справа, ниже дерево. **`Настройки` прибиты к самому низу панели.**
|
||
|
||
### Что снято с `antigravity_chat.png` — рабочее состояние
|
||
|
||
Три колонки. В правой панели — **ряд вкладок сверху** (несколько именованных разделов) и содержимое как форматированный документ: заголовки, абзацы, **блоки-выноски с цветной левой границей** (синяя — заметка, зелёная — подсказка) и мелкие «чипы» с моноширинным текстом внутри абзацев.
|
||
|
||
**Эти выноски — наша модель для подсветки неточностей перевода** (см. §4, пункт про ненавязчивость). Цветная полоска слева и тусклая подпись — вместо заливки текста.
|
||
|
||
---
|
||
|
||
## 2. Раскладка нашего приложения
|
||
|
||
Оболочка Fleet, наполнение наше.
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────────┐
|
||
│ верхняя полоса: сворачивание панелей · название книги · действия │
|
||
├──────────────┬────────────────────────────────┬─────────────────┤
|
||
│ ЛЕВАЯ │ ЦЕНТР │ ПРАВАЯ │
|
||
│ │ │ │
|
||
│ вкладки: │ вкладки открытых глав │ вкладки: │
|
||
│ Книги · │ │ О книге · │
|
||
│ Банк · │ содержимое: │ Замечания │
|
||
│ Поиск │ — две колонки оригинал/перевод │ │
|
||
│ │ — или таблица банка памяти │ метаданные, │
|
||
│ дерево: │ — или пустое состояние │ выноски с │
|
||
│ книга │ │ неточностями │
|
||
│ ├ глава 1 │ │ │
|
||
│ ├ глава 2 │ │ │
|
||
│ └ + глава │ │ │
|
||
│ │ │ │
|
||
│ ⚙ Настройки │ │ │
|
||
├──────────────┴────────────────────────────────┴─────────────────┤
|
||
│ статус-полоса: путь · состояние · прогресс │
|
||
└─────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
- **Левая панель** — вкладки в шапке (`Книги` / `Банк памяти` / `Поиск`), дерево книг и глав, `Настройки` внизу. Клик по книге открывает её состояние, клик по главе открывает главу в центре.
|
||
- **Центр** — вкладки открытых глав, как файлы в Fleet.
|
||
- **Правая панель** — вкладки `О книге` (метаданные) и `Замечания` (места, требующие внимания).
|
||
- Все три панели сворачиваются кнопками в верхней полосе.
|
||
|
||
---
|
||
|
||
## 3. Сценарий и экраны
|
||
|
||
### 3.1. Пусто — ни одной книги
|
||
|
||
Центр пустой, по центру — блок добавления книги в духе `antigravity_main.png`: скруглённая карточка, зона переноса файла с подсказкой, под ней компактный ряд полей (язык оригинала, язык перевода, жанр) и кнопка. Без иллюстраций.
|
||
|
||
### 3.2. Загрузка книги
|
||
|
||
После выбора файла: **видимое подтверждение, что файл загружен целиком и успешно** — размер, объём, определённый язык. Не молчаливый переход.
|
||
|
||
### 3.3. Разбор на главы
|
||
|
||
Дальше книга разбирается на главы. Показать прогресс разбора; по завершении главы появляются деревом в левой панели. Это отдельный видимый шаг, а не часть перевода.
|
||
|
||
### 3.4. Перевод — первый проход
|
||
|
||
Кнопка запуска перевода. Пока идёт:
|
||
|
||
- **у каждой главы в дереве — свой индикатор выполнения** (крутящийся/прогресс), главы обрабатываются не по порядку и это нормально;
|
||
- общий прогресс по книге в статус-полосе;
|
||
- ⚠ **не рассказывать, что происходит внутри.** Никаких «сейчас работает редактор», «идёт добыча глоссария», никаких названий моделей. Пользователь видит «идёт перевод» и прогресс. Всё.
|
||
|
||
### 3.5. Банк памяти — подпись
|
||
|
||
По завершении первого прохода становится доступен **банк памяти**: таблица терминов книги (имена персонажей, места, термины) с предложенным переводом. Пользователь правит и подписывает.
|
||
|
||
Таблица должна быть быстрой в работе: терминов бывают сотни, идут подряд, **клавиатура важнее мыши** (перемещение по строкам, утверждение, правка без мыши). Массовые действия. Отдельная кнопка завершения подписи.
|
||
|
||
### 3.6. Перевод — финальный проход
|
||
|
||
После подписи — кнопка запуска финального перевода. Те же индикаторы, что и в 3.4.
|
||
|
||
### 3.7. Чтение и сравнение
|
||
|
||
Открытая глава в центре: **две колонки — оригинал и перевод**, пролистываются вместе. Абзацы слева и справа по количеству часто НЕ совпадают — это нормально для художественного перевода, выравнивание идёт по крупным блокам, не построчно. Возможность листать главы вперёд-назад.
|
||
|
||
### 3.8. Замечания
|
||
|
||
Места, где перевод может быть неточен, помечаются **ненавязчиво**: тонкая цветная полоска у левого края блока и тусклая подпись — по образцу выносок из `antigravity_chat.png`. Никакой заливки текста, никаких ярких маркеров, никаких иконок-восклицаний. Список всех замечаний главы — в правой панели, вкладка `Замечания`.
|
||
|
||
Правило: **если экран выглядит тревожным — он неправильный.** Замечание — это приглашение посмотреть, а не сигнал аварии.
|
||
|
||
### 3.9. Метаданные книги
|
||
|
||
Правая панель, вкладка `О книге`: название, языки, жанр, число глав, объём, даты, состояние перевода. Спокойный список пар «поле — значение», не карточки со статистикой.
|
||
|
||
⚠ Денежных полей здесь нет — см. §4.8.
|
||
|
||
### 3.10. Добавление главы
|
||
|
||
В дереве, под главами книги — действие добавления новой главы. Загруженная глава встаёт в дерево и может быть переведена отдельно.
|
||
|
||
### 3.11. Экспорт
|
||
|
||
Кнопка выгрузки текущей книги. Выбор формата, подтверждение готовности.
|
||
|
||
### 3.12. Настройки
|
||
|
||
Отдельный раздел (открывается из низа левой панели). Внутри: профиль и доступ, конфигурация моделей, параметры перевода по умолчанию. **Всё техническое живёт здесь и только здесь** — в рабочем потоке его нет.
|
||
|
||
⚠ Подписки, тарифов, остатка и счетов в MVP НЕТ — см. §4.8.
|
||
|
||
---
|
||
|
||
## 4. Жёсткие ограничения
|
||
|
||
1. **Не раскрывать устройство бэкенда.** Ни названий моделей, ни стадий конвейера, ни внутренней терминологии в рабочих экранах. Пользователю видны: загрузка, разбор, перевод, банк, готово. Всё техническое — в настройках.
|
||
2. **Цвет означает состояние и больше ничего.** Интерфейс монохромный. Цветными бывают: полоска замечания, индикатор состояния главы, акцент фокуса. Никаких зелёных кнопок «сохранить» и красных «удалить».
|
||
3. **Ненавязчивость замечаний** — §3.8. Это отдельное требование владельца, не деталь.
|
||
4. **Плотность.** Работают подолгу; лучше видеть много, чем красиво и мало. Компактные строки, небольшие отступы, маленькие скругления — как во Fleet.
|
||
5. **Только десктоп**, тёмная тема, базовая ширина 1440, работать должно и на 1920. Мобильной версии нет.
|
||
6. **Русский интерфейс**, кириллица в реальных пропорциях.
|
||
7. **Никаких готовых UI-китов** (MUI, Ant, Chakra) — они не дадут воспроизвести Fleet. Только собственные компоненты на токенах; для поведения выпадающих меню, диалогов и подсказок — headless-примитивы без своих стилей.
|
||
|
||
### Решения владельца от 02.08 — приняты, не переоткрывать
|
||
|
||
8. **Денег в интерфейсе MVP нет вообще.** Ни сумм, ни потолков, ни оценки стоимости до запуска, ни
|
||
счётчика во время прогона, ни подписки, ни остатка. Оплаты в MVP не будет, показывать нечего.
|
||
Учёт расхода остаётся внутри движка как телеметрия владельца. Если видишь денежное поле в
|
||
каком-либо разделе этого промта — это остаток прошлой редакции, его быть не должно.
|
||
9. **Подсветка сомнительных мест — только на уровне блока и главы.** Подчёркивания внутри текста
|
||
не делаем: у проверок движка нет байтовых смещений, только счётчики. Вопрос закрыт, к нему не
|
||
возвращаться.
|
||
10. **Выравнивание колонок — грубое, по единицам экспорта**, ориентир «глава целиком». Механизм в
|
||
движке уже есть (`tmctl export --pairs`), достраивать ничего не надо. Читалка обязана нормально
|
||
выглядеть и когда вся глава оказалась одним блоком.
|
||
11. **Остановка на подписи банка — параметр запуска**, задаётся галочкой в форме перед каждым
|
||
прогоном, а не глобальной настройкой.
|
||
|
||
---
|
||
|
||
## 5. Технический стек
|
||
|
||
**Стек зафиксирован в `frontend/docs/STACK_DECISIONS.md` — бери пины оттуда, не выбирай сам.**
|
||
Коротко: React 19.2.8 · TypeScript 6.0.3 (не 7 — там нет программного API) · Vite 8.2.0 (внутри
|
||
Rolldown, не Rollup) · react-router 8.3.0 в библиотечном режиме · TanStack Query 5 + Zustand 5 ·
|
||
CSS Modules + `tokens.css` · **react-aria-components 1.20.0 как ЕДИНСТВЕННАЯ библиотека
|
||
примитивов** · react-resizable-panels 4.12.2 (API v4: `Group`/`Panel`/`Separator`).
|
||
|
||
Три вещи, которые чаще всего делают неправильно, — прочитай про них в STACK_DECISIONS:
|
||
раздел про гейт «одно место для цвета», раздел про читалку без синхронизации прокруток,
|
||
и §7 «Ловушки».
|
||
|
||
**Никакого редактора текста** в этом MVP: тексты только читают и сравнивают.
|
||
|
||
Структура:
|
||
|
||
```
|
||
frontend/
|
||
references/ скриншоты (уже лежат)
|
||
docs/ этот промт и последующие заметки
|
||
src/
|
||
tokens/ tokens.css — ЕДИНСТВЕННЫЙ источник цвета и размера
|
||
api/ слой данных: сейчас моки, потом HTTP. Один вход.
|
||
mock/ фикстуры
|
||
shell/ оболочка: панели, вкладки, статус-полоса
|
||
features/ books, chapters, bank, reader, settings
|
||
ui/ кнопки, поля, таблица, дерево, выноска
|
||
```
|
||
|
||
---
|
||
|
||
## 5.1. Поддерживаемость — требование владельца, не пожелание
|
||
|
||
Владелец сформулировал прямо: **«главное, чтоб это было очень легко поддерживаемо»**. Этот код будут править другие сессии, не ты. Правила ниже — проверяемые, не лозунги.
|
||
|
||
1. **У каждой вещи одно место.** Цвет и размер — только `tokens.css`. Данные — только `src/api/`. Если значение появилось во втором месте, это ошибка, а не удобство.
|
||
2. **Плоско и скучно.** Никаких абстракций «на будущее», фабрик, слоёв ради слоёв. Проектный норматив: механизм строится там, где несёт ценность, а не ради архитектурной красоты. Дублирование двух строк лучше преждевременного обобщения.
|
||
3. **Файл = один компонент** плюс его `.module.css` рядом. Больше ~150 строк — делить.
|
||
4. **Компоненты глупые.** Данные приходят пропсами. Запросы живут на уровне экрана, не в листьях дерева.
|
||
5. **Состояние ровно в двух местах:** TanStack Query — всё серверное, Zustand — состояние интерфейса. Копий серверных данных в локальном состоянии нет. Контекстов «на всякий случай» нет.
|
||
6. **Глобальных стилей два файла:** сброс и `tokens.css`. Всё остальное — CSS Modules, они скоупятся сами.
|
||
7. **Никаких обёрток над обёртками** и никаких UI-китов.
|
||
8. **Имена человеческие, без аббревиатур** — проектная норма.
|
||
9. **Комментарии короткие:** одна-две строки «почему», не «что». Простыни не нужны.
|
||
10. **Каждый экран открывается в изоляции** — свой маршрут и своя фикстура, чтобы его можно было снять скриншотом и проверить отдельно от остальных.
|
||
|
||
**Проверка на поддерживаемость, которую применяй к своему коду:** добавление нового состояния главы или нового вида замечания должно требовать правки **одного** файла. Если требует трёх — структура неверная, переделай до того, как двинешься дальше.
|
||
|
||
## 6. Данные: моков придерживаться, API не выдумывать
|
||
|
||
HTTP-слоя ещё нет. **Весь доступ к данным — через `src/api/`, внутри которого сейчас моки.** Компоненты не знают, что данные поддельные. Когда появится сервер, меняется один модуль.
|
||
|
||
Заведи фикстуры на одну книгу целиком: метаданные, 5–8 глав, у каждой главы оригинал и перевод по несколько абзацев, несколько помеченных мест, таблица банка на 20–30 терминов в разных состояниях, состояние прогона.
|
||
|
||
**Материал для фикстур бери реальный** — китайский текст с русским переводом, имена и термины. Выдуманный «Lorem ipsum» даст неверную плотность: кириллица длиннее латиницы, иероглифы короче всего, и колонки поедут. Пример реального фрагмента лежит в `backend/example/chapter1-zh.txt` (читать можно, править нельзя).
|
||
|
||
Состояния, которые обязаны быть в фикстурах и нарисованы: книга не начата · разбирается · переводится (первый проход) · ждёт подписи банка · переводится (финал) · готова · остановлена пользователем · отклонена (не удалось разобрать файл) · прервана ошибкой.
|
||
|
||
---
|
||
|
||
## 7. Как работать — это важнее, чем что писать
|
||
|
||
### 7.1. Смотри на то, что построил
|
||
|
||
**Заведи цикл со скриншотами первым делом, до экранов.** Скрипт `npm run shot` поднимает приложение, снимает PNG в `frontend/.shots/`, ты **открываешь этот PNG и смотришь на него** (ты умеешь читать изображения), сравниваешь с `references/fleet.png`, правишь.
|
||
|
||
Без этого цикла ты пишешь вслепую: код валиден, вид случаен. Это единственный способ выполнить требование «скопировать Fleet».
|
||
|
||
**Установка проверена на этой машине — делай ровно так, sudo не нужен ни на одном шаге.** Среда: WSL2, Ubuntu 24.04, Node 22, пароль root недоступен.
|
||
|
||
```bash
|
||
npm i -D playwright
|
||
npx playwright install chromium # БЕЗ --with-deps: он требует sudo и ставит лишнее
|
||
```
|
||
|
||
Chromium запустится не сразу: не хватает четырёх системных библиотек (`libnss3.so`, `libnssutil3.so`, `libnspr4.so`, `libasound.so.2`). Ставятся локально, без root:
|
||
|
||
```bash
|
||
mkdir -p .tooling && cd .tooling
|
||
apt-get download libnss3 libnspr4 libasound2t64
|
||
for d in *.deb; do dpkg -x "$d" root; done
|
||
rm -f *.deb && cd ..
|
||
```
|
||
|
||
Путь к ним — `.tooling/root/usr/lib/x86_64-linux-gnu`. Пропиши его прямо в команду, чтобы никто о нём больше не думал:
|
||
|
||
```json
|
||
"scripts": {
|
||
"shot": "LD_LIBRARY_PATH=$PWD/.tooling/root/usr/lib/x86_64-linux-gnu node scripts/shot.mjs"
|
||
}
|
||
```
|
||
|
||
В `.gitignore`: `.tooling/` и `.shots/` — бинарники и снимки в репозиторий не едут.
|
||
|
||
Проверка, что цикл живой (сделай её до всякого интерфейса): отрисуй страницу с панелью `#17191a` на фоне `#090909`, радиус 6, отступ 8 — сними, открой, убедись, что видишь именно это. Работает браузер headless, окна нет, графический сервер не нужен.
|
||
|
||
### 7.2. Порядок твоей сессии
|
||
|
||
**S0 — план (кода нет).** Прочитай всё из блока обязательного чтения. Напиши
|
||
`frontend/docs/FRONTEND_PLAN.md`: таблица пинов (пакет · версия · дата релиза · зачем именно нам,
|
||
сверенная по npm), карта `src/` с назначением каждой папки, правила поддерживаемости в проверяемой
|
||
форме, протокол скриншот-цикла и критерий сравнения с референсом. **Заленди отдельным коммитом.**
|
||
|
||
**S1 — инструменты и токены.**
|
||
|
||
1. Проверь `node -v` — нужно **≥ 22.22**. Установи Playwright по процедуре из §7.1 (без sudo).
|
||
2. Каркас: Vite + React + TS, ESLint + stylelint + prettier, единая команда `npm run check`.
|
||
3. Скриншот-цикл и проверка, что он живой (страница с панелью на фоне, снять, посмотреть).
|
||
4. `tokens.css` — значения из `STACK_DECISIONS`/§1.1 этого промта, с комментарием об источнике.
|
||
Задай `@layer` явно: порядок каскада между стилями React Aria, токенами и модулями — источник
|
||
тихих расхождений. Сразу стилизуй скроллбары: дефолтные на Windows толстые и светлые, они
|
||
ломают вид на трёх панелях.
|
||
5. **Витрина**: страница из панелей, вкладок, строки дерева и строки таблицы. Сними, положи рядом
|
||
с `fleet.png`, **посмотри обе**, сведи.
|
||
6. Контракт-тест токенов: рендерим корень, сверяем вычисленные значения CSS-переменных с
|
||
замеренными числами. Это заменяет визуальный гейт с эталонами.
|
||
|
||
**На витрине остановись.** Если токены не сошлись — это и есть результат сессии, честно описанный;
|
||
дальше не иди. Экраны пишут следующие сессии.
|
||
|
||
### 7.3. Ревью исполнением — обязательно
|
||
|
||
Проектная норма: любая сессия, пишущая код, обязана **проверять себя исполнением**, а не заявлением. Для тебя это значит:
|
||
|
||
- приложение реально запускается, экран реально открывается — проверено запуском, не предположением;
|
||
- скриншот снят и просмотрен, а не «должно выглядеть так»;
|
||
- расхождения с референсом названы вслух, даже если исправить не успел;
|
||
- если чего-то не сделал — сказано прямо, без «в основном готово».
|
||
|
||
Отчёт в конце: что построено, что видно на скриншотах, где отошёл от референса и почему, что осталось.
|
||
|
||
### 7.4. Чего не делать
|
||
|
||
- Не изобретать API и не ходить в `backend/` за данными — только моки.
|
||
- Не тащить UI-киты и не «улучшать» референс своим вкусом.
|
||
- Не рисовать мобильную версию, светлую тему, иллюстрации пустых состояний.
|
||
- Не раскрывать конвейер (§4.1) — это самое лёгкое требование забыть.
|
||
- Не хардкодить цвета и размеры мимо `tokens.css`.
|
||
|
||
---
|
||
|
||
## 8. Готово — это когда (для ТВОЕЙ сессии, S0+S1)
|
||
|
||
- `FRONTEND_PLAN.md` заленден отдельным коммитом до кода.
|
||
- `npm run check` зелёный и делает все четыре шага.
|
||
- `npm run shot` снимает PNG, ты его открывал и смотрел.
|
||
- `tokens.css` — единственный источник цвета и размера; гейт против хардкода включён и **проверен
|
||
на живом нарушении** (вставь `#fff` в компонент, убедись, что проверка падает, убери).
|
||
- Витрина снята и сведена с `fleet.png`; расхождения названы вслух.
|
||
- Контракт-тест токенов проходит.
|
||
|
||
⚠ **Критерий сравнения — не растровое совпадение.** JetBrains Fleet закрыт (скачивание прекращено
|
||
22.12.2025), референс снят на macOS при 2x, наша цель — Windows-Chromium с другим хинтингом
|
||
шрифтов. Пиксель-в-пиксель недостижим и не является целью. Сходиться обязаны: **замеренные цвета,
|
||
промежутки 8px, радиусы 6px, плотность строк и общее впечатление**. Кегли и интерлиньяж — подбором
|
||
на глаз до похожести, потому что померить их больше негде.
|
||
|
||
## 9. Что уже известно про движок — учесть в плане, не открывать заново
|
||
|
||
Разобрано по коду 02.08. Влияет на форму данных, поэтому знать надо уже на S0.
|
||
|
||
- **Индикатор прогресса нельзя строить на «готово N из M»**: unit становится `done` только когда
|
||
есть и черновые строки всех его членов, и строка редактуры. Во время черновой волны это ноль
|
||
почти всё время. Правильно — **пофазно**: `черновик N/M` ∥ `редактура N/M`.
|
||
- **Подпись термина — не UPDATE строки.** Банк пересобирается из файлов на каждом прогоне, прямая
|
||
запись в таблицу молча стирается следующим прогоном. Форма контракта подписи это учитывает.
|
||
- **Байтовых смещений у замечаний нет** — только счётчики. Поэтому подсветка сомнительных мест
|
||
идёт **на уровне блока и главы**, а не внутри текста. Владелец это принял 02.08 (§4.9),
|
||
вопрос закрыт.
|
||
- **Гранулярность пар грубее ожидаемой**: финальный текст существует на уровне edit-unit, замерено
|
||
~1.9 блока на главу — местами вся глава окажется одним блоком. Читалка обязана нормально
|
||
выглядеть и в этом случае.
|
||
|
||
Полный список того, что достраивается в движке — `STACK_DECISIONS.md` §8.
|