User первые впечатления после go-live board.kzntsv.site:
- drawer падает TypeError (приватные репо + no browser token; bundle md
в build-time — единственно верное решение)
- slug не виден на карточке (только в data-attr)
- дата без времени, неясный формат
- owner-pill дублируется (single-owner whitelist → visual noise)
- нет нумерации задач (BV-12 / T-001 shorthand нужен)
- done-tail слишком длинный (нужен render-side cutoff/collapse)
Все 6 — code-impl в board-viewer (не deploy → не в .admin, per workshop §5).
TDD posture везде (project follow tdd-criteria).
Drawer bug = critical (clear-impl: bundle md в build-time, root-cause grounded).
Show-slug + full-datetime = clear-impl, простой TDD-цикл.
Owner-conditional = clear-impl (single vs multi owner branches), 2 fixtures.
Task-numbers + done-cutoff = design-first (4 open questions каждый),
brainstorm если recommendations не пройдут single-session.
+ review umbrella 🔵 blocked-by 6 slug'ами (workshop §4 mandatory).
Ops-handoff (rebuild image + Portainer pull) — отдельная taska в
.admin/[board-viewer-redeploy-ux-round1] (workshop §5).
44 lines
4.2 KiB
Markdown
44 lines
4.2 KiB
Markdown
# board-viewer-drawer-bundle-md
|
||
|
||
## Goal
|
||
|
||
Drawer падает с `TypeError: Failed to fetch` при клике на любую карточку. Root-cause: `rawUrl` указывает на `git.kzntsv.site/<owner>/<repo>/raw/branch/<branch>/<path>` — приватные репо требуют auth, в браузере токена нет (он только в build-контейнере для статической генерации, `auth.toml` ro-mounted). Browser fetch без `Authorization` → Gitea отдаёт 401 / 302→login HTML → fetch воспринимает как failure → TypeError.
|
||
|
||
Решение: **bundle per-task md-content в build-time**. Build-контейнер уже знает где per-task `.md` файлы (он их fetch'ит для парсинга), у него есть Gitea token. Расширить read-фазу: вместе с STATUS.md тянуть и per-task .md (если существует), складывать в `dist/tasks-md.json` или встраивать в `<script type="application/json" id="tasks-md">…</script>` в `index.html`. Drawer читает из этого локального data вместо fetch.
|
||
|
||
## TDD posture
|
||
|
||
**Mode = TDD** (project CLAUDE.md имеет `follow tdd-criteria`). Failing test первым:
|
||
|
||
- Unit: reader получает per-task md content параллельно с STATUS.md, кладёт в `TaskRecord.md_content?: string`
|
||
- Render: каждая карточка имеет `data-md-encoded` или используется shared JSON-bundle с `data-md-key={slug}`
|
||
- Drawer test (board.js): открывает draweр по data-key, читает из bundled JSON, рендерит через `marked.parse` — без fetch
|
||
- E2E smoke: открыть локально dist/index.html в browser-driver (или mocked DOM), кликнуть карту → drawer показывает md content, не «Failed to load»
|
||
|
||
## Key files
|
||
|
||
- `src/gitea.ts` — добавить метод `getRawContent(owner, repo, path)` через API (`/api/v1/repos/.../contents/`+base64-decode или `/api/v1/repos/.../raw/...` с токеном)
|
||
- `src/reader.ts` — расширить чтобы для каждого `TaskRecord` пулить per-task `.md` (если file exists)
|
||
- `src/render.ts:136` — добавить data-md-key вместо data-raw-url, либо встроить JSON-bundle в html
|
||
- `static/board.js:200-215` — `openDrawer` читает из localStorage / global var вместо fetch
|
||
- `tests/` — fixture для per-task md, новые тесты
|
||
|
||
## Acceptance criteria
|
||
|
||
- Все 49 текущих тестов всё ещё pass + новые тесты для md-bundle pipeline
|
||
- E2E smoke на real board.kzntsv.site (live): клик на любую карту → drawer заполняется per-task content без network-запросов на git.kzntsv.site
|
||
- DevTools Network: открыть карту → 0 запросов исходящих к git.kzntsv.site/raw
|
||
- Размер `index.html` или `tasks-md.json` reasonable (предположительно <500 KB на 80 records — markdown текстовый, gzip сильно сожмёт)
|
||
- Карты без per-task `.md` файла (status=ready без deep-context) — drawer показывает только title + status block, без «Failed to load»
|
||
|
||
## Decisions log
|
||
|
||
- 2026-05-22: создана из user UX-feedback round1 — drawer ломается с TypeError. Root-cause grounded: приватные репо + no browser token. Импл-направление = bundle, не proxy (proxy потребовал бы nginx с auth_request к board-viewer-build или Gitea token в nginx — переусложнение). Bundle deterministic + no runtime network.
|
||
|
||
## Notes
|
||
|
||
- Bundle approach впишется в существующий cron-loop pattern (build every 300s регенирует index.html + tasks-md). Никаких runtime-зависимостей от Gitea API.
|
||
- Файлы могут быть rotated/архивированы (см. сестринскую таску `board-viewer-ux-done-cutoff`).
|
||
|
||
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: .workshop / 2026-05-22 / trigger: user-ux-feedback-round1 -->
|