Прежняя git-история утрачена при переносе проекта на машину владельца (снапшот без .git). Хэши коммитов в docs/reports/* относятся к утраченной истории. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
70 lines
5.3 KiB
Markdown
70 lines
5.3 KiB
Markdown
# План фазы 2: этап 2 — доска Canvas (packages/board)
|
||
|
||
Обновлено: 2026-08-05 | Статус: код и тесты готовы, gates зелёный (74 теста:
|
||
43 core + 31 board). Осталось: визуальная проверка — на этапе 5.
|
||
|
||
## Пометки о ходе (2026-08-05)
|
||
|
||
- Объём выполнен целиком: geometry.ts, render.ts (тёмная тема по умолчанию),
|
||
input.ts, dom.ts, index.ts; корневой tsconfig.json — reference на
|
||
packages/board; зависимость @go-learn/core 0.1.0 в package.json пакета.
|
||
- Все тесты из раздела «Тесты» ниже написаны и зелёные (31 тест board).
|
||
- Отклонение: в packages/board/tsconfig.json нет references на ../core —
|
||
`tsc -b --noEmit` (гейт typecheck) с project references падает с чистого
|
||
состояния (TS6310, CLI --noEmit распространяется на referenced-проект,
|
||
TS 5.9.3). Импорт резолвится через workspace-симлинк; подробности —
|
||
комментарий в packages/board/tsconfig.json.
|
||
- Уточнение семантики territory (в первой редакции контракта стороны не
|
||
различались): структура TerritoryMap { black, white } с множествами ключей
|
||
"x,y" по цветам — зафиксировано в контракте (правка main loop при приёмке).
|
||
|
||
## Критические долги (реестр — в начале, III.5)
|
||
|
||
- Нет.
|
||
|
||
## Ключевые решения (не пере-решать)
|
||
|
||
- Доска — Canvas 2D, не DOM/SVG (плавность на 361 пересечении) — мастер-промпт.
|
||
- render(ctx, position, options) — чистая функция состояния, весь кадр из аргументов.
|
||
- Геометрия, редьюсер ввода и рендер — headless-тестируемые; DOM — тонкий адаптер
|
||
(setupCanvas, attachPointerInput), юнит-тестами не покрывается — см. матрицу
|
||
«чего НЕ покрывает ни один тест» ниже.
|
||
- Координаты — буквы без «I» (стандарт Го), числа снизу вверх.
|
||
- Дефолтная тема — тёмная (мастер-промпт: минималистичный дизайн, тёмная тема).
|
||
- Контракт — docs/INTERFACES.md, раздел «Контракт отрисовки доски» (зафиксирован
|
||
2026-08-05 до кода).
|
||
|
||
## Объём этапа 2
|
||
|
||
1. packages/board: geometry.ts (computeGeometry, pointToPixel, pixelToPoint,
|
||
hoshiPoints), render.ts (render + BoardTheme + дефолтная тёмная тема),
|
||
input.ts (reduceInput), dom.ts (setupCanvas, attachPointerInput), index.ts.
|
||
2. Отзывчивый размер и devicePixelRatio (setupCanvas).
|
||
3. Хоси, координаты и номера ходов (переключаемые), фантомный камень,
|
||
подсветка последнего хода, тач-ввод с подтверждением (первый тап — позиция,
|
||
второй тап или confirm — ход), слои разметки (LB/TR/SQ/CR, заливка
|
||
территории, приглушение мёртвых).
|
||
4. Корневой tsconfig: references += packages/board; packages/board зависит от
|
||
@go-learn/core (project reference).
|
||
|
||
## Тесты (гейт приёмки этапа)
|
||
|
||
- Геометрия: хоси для 9/13/19; roundtrip pixelToPoint∘pointToPixel; отклонение
|
||
точки дальше половины клетки; padding при showCoordinates on/off.
|
||
- Редьюсер ввода: тап → pending; второй тап по той же точке → commit; тап по
|
||
другой точке → перенос; confirm без pending → commit null; cancel → сброс;
|
||
тап мимо доски → без изменений.
|
||
- Рендер: мок-ctx с записью вызовов — число камней = числу занятых клеток
|
||
BoardState; фантом рисуется с phantomOpacity; метка последнего хода только
|
||
при lastMove; LB/TR/SQ/CR из markup; заливка только для territory-ключей;
|
||
мёртвые приглушены. Не проверяем каждый вызов — только инварианты.
|
||
- Wiring: orphan-check по публичным функциям packages/board (вызывающие —
|
||
тесты допустимы, дом-адаптер помечен как входная точка).
|
||
- Матрица «чего НЕ покрывает ни один тест»: реальный вид кадра, pointer-события
|
||
браузера, поведение на мобильном Safari — ручная проверка в этапе 5/7
|
||
(смоук-сценарий, слой GUI — litany II.8).
|
||
|
||
## Критерий выхода
|
||
|
||
Все тесты зелёные + `npm run gates` зелёный. Визуальная проверка — на этапе 5
|
||
(когда появится страница); до неё — demo-страница не нужна.
|