tasks: round1 UX feedback — 6 dev-tasks + review umbrella [board-viewer-ux-round1-review]
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).
This commit is contained in:
@@ -66,6 +66,77 @@ _Updated: 2026-05-22_
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## ⚪ [board-viewer-drawer-bundle-md] — fix `Failed to fetch` в drawer: bundle md-content в build-time
|
||||||
|
|
||||||
|
**Status:** ready (critical bug)
|
||||||
|
**Where I stopped:** (not started — diagnose grounded: приватные репо + `fetch(rawUrl, {credentials:'omit'})` без auth → Gitea 401/302→login → TypeError. Решение — bundle per-task .md в build-time в JSON/inline script, drawer читает локально.)
|
||||||
|
**Next action:** см. `board-viewer-drawer-bundle-md.md`. TDD mode. Сначала reader test: `TaskRecord.md_content?: string`. Затем render embeds JSON-bundle. Затем `static/board.js openDrawer` читает local instead of fetch. E2E smoke в browser-driver: 0 запросов на git.kzntsv.site/raw при клике.
|
||||||
|
**Branch:** master
|
||||||
|
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: .workshop / 2026-05-22 / trigger: user-ux-feedback-round1 -->
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚪ [board-viewer-ux-show-slug] — показать slug на карточке (сейчас только в data-attr)
|
||||||
|
|
||||||
|
**Status:** ready
|
||||||
|
**Where I stopped:** (not started)
|
||||||
|
**Next action:** TDD mode. Failing test в `tests/render.test.ts`: ожидать `<code class="card-slug">...</code>` в output. Impl в `src/render.ts` + CSS в `static/board.css`. Smoke: slug читается на каждой карточке.
|
||||||
|
**Branch:** master
|
||||||
|
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: .workshop / 2026-05-22 / trigger: user-ux-feedback-round1 -->
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚪ [board-viewer-ux-full-datetime] — дата + время в явном формате (не только дата)
|
||||||
|
|
||||||
|
**Status:** ready
|
||||||
|
**Where I stopped:** (not started — 3 design questions: TZ МСК/UTC, format readable/ISO, оставить ли relative «7h». Recommendations внутри `board-viewer-ux-full-datetime.md`.)
|
||||||
|
**Next action:** TDD mode. Resolve 3 design-вопроса (или принять recommendations: МСК с явным суффиксом, `YYYY-MM-DD HH:MM МСК`, relative сохранить тоненькой строкой). Затем failing test + impl в `src/render.ts`.
|
||||||
|
**Branch:** master
|
||||||
|
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: .workshop / 2026-05-22 / trigger: user-ux-feedback-round1 -->
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚪ [board-viewer-ux-owner-conditional] — скрывать owner-pill когда все таски одного owner'а
|
||||||
|
|
||||||
|
**Status:** ready
|
||||||
|
**Where I stopped:** (not started — текущий VDS whitelist single-owner `OpeItcLoc03/*` → pill дублируется visual noise. Рендерить условно: single-owner → шапка «Owner: X (N repos)», без pill; multi-owner → pill на карточках.)
|
||||||
|
**Next action:** TDD mode. Два теста (single/multi owner fixtures). Impl в `src/render.ts`. Связанный ops-audit в `.admin/[board-viewer-redeploy-ux-round1]`: verify `auth.toml board_viewer_repos` (по memory `books` = `victor/books`, не `OpeItcLoc03/books`).
|
||||||
|
**Branch:** master
|
||||||
|
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: .workshop / 2026-05-22 / trigger: user-ux-feedback-round1 -->
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚪ [board-viewer-ux-task-numbers] — shorthand numbering (BV-12) на карточке
|
||||||
|
|
||||||
|
**Status:** ready (design-first)
|
||||||
|
**Where I stopped:** (not started — 4 design-вопроса: scope per-repo/global, source-of-truth `<!-- num: ... -->` в STATUS.md vs auto-derive, format BV-12 vs T-001, ретроактивно или нет. Recommendations в `board-viewer-ux-task-numbers.md`.)
|
||||||
|
**Next action:** Resolve 4 design-вопроса (single user-session). Если рекомендации принимаются — TDD impl: parser извлекает `num` из block-comment, render показывает badge. Ретроспективно — отдельный proход «chore: number existing tasks». Если возникает дилемма — `.workshop/.brainstorm/board-viewer-task-numbers.md`.
|
||||||
|
**Branch:** master
|
||||||
|
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: .workshop / 2026-05-22 / trigger: user-ux-feedback-round1 -->
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚪ [board-viewer-ux-done-cutoff] — фильтр / cutoff длинного done-tail
|
||||||
|
|
||||||
|
**Status:** ready (design-first)
|
||||||
|
**Where I stopped:** (not started — 4 design-вопроса: что считать «archive-нужно» (все 🟢 или N дней+), source неизменен (recommend) vs физический archive, default hide vs show-all, тип cutoff (last-N / date / combined). Recommendations в `board-viewer-ux-done-cutoff.md`.)
|
||||||
|
**Next action:** Resolve design (single user-session или brainstorm). Recommendations: source-неизменен, render-side cutoff = «hide done by default + toggle + last-10 fallback при show». TDD impl: render с N done>cutoff показывает только N + «N more» expander. Если дилемма — `.workshop/.brainstorm/board-viewer-done-cutoff.md`.
|
||||||
|
**Branch:** master
|
||||||
|
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: .workshop / 2026-05-22 / trigger: user-ux-feedback-round1 -->
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔵 [board-viewer-ux-round1-review] — review umbrella для 6 UX-fixes round1
|
||||||
|
|
||||||
|
**Status:** blocked
|
||||||
|
**Blocker:** board-viewer-drawer-bundle-md, board-viewer-ux-show-slug, board-viewer-ux-full-datetime, board-viewer-ux-owner-conditional, board-viewer-ux-task-numbers, board-viewer-ux-done-cutoff
|
||||||
|
**Where I stopped:** (not started — открывать когда все 6 импл-таск 🟢)
|
||||||
|
**Next action:** Independent review subagent'ом (clean context, не имплементер) — TDD-immutability (тесты не переписаны под impl), output-correctness (smoke на live board.kzntsv.site после redeploy), regression check (49 существующих тестов остаются pass).
|
||||||
|
**Branch:** master
|
||||||
|
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: .workshop / 2026-05-22 / trigger: workshop-CLAUDE.md §4 mandatory review umbrella -->
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Status legend:
|
Status legend:
|
||||||
🔴 Active — only one at a time
|
🔴 Active — only one at a time
|
||||||
|
|||||||
43
.tasks/board-viewer-drawer-bundle-md.md
Normal file
43
.tasks/board-viewer-drawer-bundle-md.md
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
# 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 -->
|
||||||
40
.tasks/board-viewer-ux-done-cutoff.md
Normal file
40
.tasks/board-viewer-ux-done-cutoff.md
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# board-viewer-ux-done-cutoff
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
User: «чаще нужна архивная чистка — очень длинный хвост в done». Колонка 🟢 done растёт без ограничения; visual noise. Нужна фильтрация / cutoff / collapse.
|
||||||
|
|
||||||
|
## Design open questions — РЕШИТЬ ДО ИМПЛА
|
||||||
|
|
||||||
|
1. **Что архивная чистка должна делать на UI-стороне** (источник = STATUS.md остаётся неизменным, чистка — render-time)?
|
||||||
|
- Hide-by-default + toggle «show done» (текущий `toggleArchived` уже близко к этому, но done ≠ archived)
|
||||||
|
- Last-N cutoff: показать последние N done (например 10) per column, остальные за «N more…»
|
||||||
|
- Date-cutoff: показать done за последние 7 / 14 / 30 дней, остальные скрыты
|
||||||
|
- Combined: hide by default, expander «show older»
|
||||||
|
2. **Что считается «done для скрытия»?** Все 🟢 или только те у которых close-date старше N дней?
|
||||||
|
3. **Должен ли source (STATUS.md) фактически archive'ить старые** (физически переносить в отдельный `.tasks/_archive/<date>.md`)? Это уже не UI а layout-вопрос. Recommend: **нет**, source неизменен, всё на UI-стороне — иначе любая повторная сборка ломается при reorganization.
|
||||||
|
4. **Default:** hide-done by default или show-all? Если hide — user тыкает один раз чтобы увидеть, плюс — чистый default-вид. Recommend hide-by-default + видимый toggle в шапке.
|
||||||
|
|
||||||
|
## Pre-impl
|
||||||
|
|
||||||
|
- Brainstorm перед импл. Если решения 4-х вопросов выше bundle'ятся в один очевидный recommendation — стартовать impl сразу с design-комментарием в decisions log. Если возникает дилемма — `.workshop/.brainstorm/board-viewer-done-cutoff.md`.
|
||||||
|
|
||||||
|
## TDD posture
|
||||||
|
|
||||||
|
**Mode = TDD** (после resolve design). Failing test: render с N done > cutoff показывает только cutoff штук + «N more» link/button. Цикл RED→GREEN.
|
||||||
|
|
||||||
|
## Key files
|
||||||
|
|
||||||
|
- `src/render.ts` (column-rendering — добавить cutoff + expander)
|
||||||
|
- `static/board.js` (expander click handler)
|
||||||
|
- `static/board.css` (styling collapsed state)
|
||||||
|
- `tests/render.test.ts`
|
||||||
|
|
||||||
|
## Acceptance
|
||||||
|
|
||||||
|
- В колонке 🟢 done видны только последние N (число согласовано в design) — остальные скрыты под expander
|
||||||
|
- Toggle / expander работает (DevTools click test)
|
||||||
|
- Source STATUS.md не модифицируется (verify через `git status` after smoke)
|
||||||
|
- Тесты pass
|
||||||
|
|
||||||
|
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: .workshop / 2026-05-22 / trigger: user-ux-feedback-round1 -->
|
||||||
30
.tasks/board-viewer-ux-full-datetime.md
Normal file
30
.tasks/board-viewer-ux-full-datetime.md
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
# board-viewer-ux-full-datetime
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
Сейчас карточка показывает `YYYY-MM-DD` + tooltip с full ISO + относительное `7h` (per `board-viewer-card-meta-fix`). User: «хочется видеть дату и время, а не только дату в непонятном форматировании».
|
||||||
|
|
||||||
|
Заменить short ISO на `YYYY-MM-DD HH:MM` (timezone-suffix явный — `МСК` / `UTC`, чтобы не было ambiguity). Relative «7h» оставить (компактный signal recency) или убрать — зависит от ответа user'а в impl-сессии.
|
||||||
|
|
||||||
|
## Design open questions
|
||||||
|
|
||||||
|
- TZ: МСК (UTC+3) или UTC? User в МСК, но board может смотреться из других мест. Recommend МСК с явным суффиксом.
|
||||||
|
- Format: `2026-05-22 14:35 МСК` или ISO `2026-05-22T14:35+03:00`? Recommend первое — читаемее.
|
||||||
|
- Relative «7h» — сохранить или убрать? Recommend сохранить как тоненькую вторую строку под датой.
|
||||||
|
|
||||||
|
## TDD posture
|
||||||
|
|
||||||
|
**Mode = TDD**. Failing test для нового format'а в `render.test.ts` (или эквивалент в card-meta-fix tests). Impl в `src/render.ts`.
|
||||||
|
|
||||||
|
## Key files
|
||||||
|
|
||||||
|
- `src/render.ts` (formatLastCommitIso или эквивалент функция)
|
||||||
|
- `tests/render.test.ts`
|
||||||
|
|
||||||
|
## Acceptance
|
||||||
|
|
||||||
|
- Карточка показывает `2026-05-22 14:35 МСК` (или согласованный format) — не только дату
|
||||||
|
- Tooltip остаётся (full ISO с секундами для копи-паста)
|
||||||
|
- Тесты pass с новым форматом
|
||||||
|
|
||||||
|
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: .workshop / 2026-05-22 / trigger: user-ux-feedback-round1 -->
|
||||||
29
.tasks/board-viewer-ux-owner-conditional.md
Normal file
29
.tasks/board-viewer-ux-owner-conditional.md
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
# board-viewer-ux-owner-conditional
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
User: «`OpeItcLoc03` — почему везде один и тот же owner? Зачем он вообще?» Owner-pill добавлен `board-viewer-card-meta-fix` как differentiator для cross-owner whitelist'а, но в текущем VDS-конфиге все 5 репо в одном namespace (`OpeItcLoc03/*`) → pill дублируется на каждой карточке, visual noise.
|
||||||
|
|
||||||
|
Рендерить owner **условно**: если на текущем рендере все видимые карточки имеют один и тот же owner — pill скрыть, owner один раз показать в шапке доски (например «Owner: OpeItcLoc03 (5 repos)»). При ≥2 distinct owners — pill вернуть на карточки.
|
||||||
|
|
||||||
|
## TDD posture
|
||||||
|
|
||||||
|
**Mode = TDD**. Failing test: render с фикстурой single-owner → cards без `.owner-pill`, шапка содержит owner-summary. Render с фикстурой multi-owner → cards содержат `.owner-pill`, шапка без owner-summary (или с list). Затем impl.
|
||||||
|
|
||||||
|
## Key files
|
||||||
|
|
||||||
|
- `src/render.ts` — pre-render scan distinct owners, conditional output
|
||||||
|
- `static/board.css` — стиль для header owner-summary
|
||||||
|
- `tests/render.test.ts` — два теста (single-owner / multi-owner fixtures)
|
||||||
|
|
||||||
|
## Acceptance
|
||||||
|
|
||||||
|
- При single-owner whitelist карточки чище (без duplicate pill); owner один раз в шапке
|
||||||
|
- При multi-owner — pill возвращается, шапка не дублирует
|
||||||
|
- Тесты pass
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- Связанная ops-проверка (см. `.admin/[board-viewer-redeploy-ux-round1]`): верифицировать что `board_viewer_repos` в `/opt/stacks/board-viewer/auth.toml` корректно — `books` по memory `Gitea owner namespace` должен быть `victor/books`, не `OpeItcLoc03/books`. Если auth.toml корректен и whitelist single-owner — UI conditional работает как задумано.
|
||||||
|
|
||||||
|
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: .workshop / 2026-05-22 / trigger: user-ux-feedback-round1 -->
|
||||||
25
.tasks/board-viewer-ux-show-slug.md
Normal file
25
.tasks/board-viewer-ux-show-slug.md
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
# board-viewer-ux-show-slug
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
Карточка не показывает slug визуально. Юзер видит только description (первая строка после `## 🟢 [<slug>] — <desc>`) и не понимает «какая это таска по имени». `data-slug` атрибут есть, но в header карточки не рендерится.
|
||||||
|
|
||||||
|
Добавить slug как видимый sub-heading или badge в верхней части карточки (под/над description-line, в моноширинном шрифте чтобы выделялся).
|
||||||
|
|
||||||
|
## TDD posture
|
||||||
|
|
||||||
|
**Mode = TDD** (project `follow tdd-criteria`). Сначала failing render-test: ожидать что output `renderCard(record)` содержит `<code class="card-slug">board-viewer-pointers</code>` (или эквивалент). Затем impl в `src/render.ts`.
|
||||||
|
|
||||||
|
## Key files
|
||||||
|
|
||||||
|
- `src/render.ts` (рендер карточки — добавить slug-element)
|
||||||
|
- `static/board.css` (стиль `.card-slug` — monospace, dim color, маленький)
|
||||||
|
- `tests/render.test.ts` — новый тест
|
||||||
|
|
||||||
|
## Acceptance
|
||||||
|
|
||||||
|
- Slug виден на каждой карточке (любой статус)
|
||||||
|
- Тест: html-output карточки содержит slug в parseable form (не только в data-атрибуте)
|
||||||
|
- Smoke: визуально на board.kzntsv.site после redeploy — slug читается, не сливается с description
|
||||||
|
|
||||||
|
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: .workshop / 2026-05-22 / trigger: user-ux-feedback-round1 -->
|
||||||
39
.tasks/board-viewer-ux-task-numbers.md
Normal file
39
.tasks/board-viewer-ux-task-numbers.md
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
# board-viewer-ux-task-numbers
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
User: «нам явно не хватает нумерации задач». Сейчас каждая задача — slug (`board-viewer-pointers`). Slug informative, но длинный. Хочется shorthand (`T-001` / `BV-12` / etc.) для разговора, ссылок, memory-references.
|
||||||
|
|
||||||
|
## Design open questions — РЕШИТЬ ДО ИМПЛА
|
||||||
|
|
||||||
|
1. **Scope нумерации:** per-repo (BV-12, BO-3) или global cross-repo (T-78)? Per-repo стабильнее (новый репо не сдвигает существующие numbers).
|
||||||
|
2. **Источник truth:** хранить number в STATUS.md (комментарий или новый field в block)? Или auto-derive из order/position?
|
||||||
|
- **Source-of-truth в STATUS.md** — стабильно (number не меняется), но требует ручной maintenance при создании каждой таски.
|
||||||
|
- **Auto-derive** — нулевая maintenance, но number меняется при reorder/insert.
|
||||||
|
- Recommend: source-of-truth, с конвенцией «при создании новой таски вписать `<!-- num: BV-NN -->` сразу после `## ...` строки». Reader парсит, рендер показывает.
|
||||||
|
3. **Format:** `BV-12`, `BV12`, `T-001`, `#12`? Recommend `BV-12` — short, читается, не конфликтует с slug.
|
||||||
|
4. **Старые таски:** нумеровать ретроактивно? Recommend да, один проход — выписать number для каждой существующей таски в каждом репо, commit отдельно «chore: number existing tasks».
|
||||||
|
|
||||||
|
## TDD posture
|
||||||
|
|
||||||
|
**Mode = TDD** (после resolve design-вопросов). Failing test: парсер извлекает `num` из STATUS.md block, render показывает badge с number в карточке. Затем impl.
|
||||||
|
|
||||||
|
## Pre-impl
|
||||||
|
|
||||||
|
- Brainstorm перед коммитом первой строки кода. Дизайн — короткий (4 вопроса выше), может занять одну session-петлю с user. Если будет нужен heavy brainstorm — стартовать `.workshop/.brainstorm/board-viewer-task-numbers.md` через `recommend-don't-menu` мод.
|
||||||
|
|
||||||
|
## Key files
|
||||||
|
|
||||||
|
- `src/parser.ts` (парсинг `<!-- num: ... -->` comment)
|
||||||
|
- `src/render.ts` (badge на карточке)
|
||||||
|
- STATUS.md всех 5 репо в whitelist (ретроактивная нумерация)
|
||||||
|
- `tests/parser.test.ts` + `tests/render.test.ts`
|
||||||
|
|
||||||
|
## Acceptance
|
||||||
|
|
||||||
|
- Каждая карточка показывает number-badge (`BV-12`) рядом со slug
|
||||||
|
- Тесты pass
|
||||||
|
- Все существующие таски в whitelist-репо имеют `<!-- num: ... -->` (или эквивалент)
|
||||||
|
- Конвенция документирована в `using-tasks` skill (или эквиваленте) — «новые таски имеют number с момента создания»
|
||||||
|
|
||||||
|
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: .workshop / 2026-05-22 / trigger: user-ux-feedback-round1 -->
|
||||||
Reference in New Issue
Block a user