Commit Graph

6 Commits

Author SHA1 Message Date
vitya
469ff112cc feat(polish): close all 6 review nitpicks in one sweep
closes board-viewer-polish

- M1 src/parser.ts: comment explaining why **Status:** text field is intentionally
  ignored (emoji is canonical, prevents future-reader head-scratch)
- M2 src/render.ts + tests: clamp future ISO to '0m' (server clock drift safety)
  + inline comment + test
- M3 .tasks/board-viewer-gitea-reader.md: decisions-log clarifying orphan
  per-task files are out of scope by design (STATUS.md = index of record)
- M4 static/board.{js,css} + src/render.ts: filter rebuilt to query records
  (not DOM badge text); 5 status-filter pill buttons in header with active
  toggle state; smoke-verified blocked filter
- M5 deploy/Dockerfile.build: HEALTHCHECK (file fresher than 2×tick) and
  stderr redirect for failures with timestamp
- M6 src/reader.ts: parallelize getLatestCommitIso per-repo via Promise.all
  (preserves block order)

49 tests pass (was 43 pre-polish), typecheck clean, smoke against real Gitea
returns 81 records from 4 repos.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 15:46:47 +03:00
vitya
930e404545 feat(render): card owner pill + short ISO date span
closes board-viewer-card-meta-fix

Review found two acceptance fields missing from cards:
- project_owner was in JSON but never displayed
- last_commit_iso was only consumed for relative age; no absolute date

Now both rendered (server-side src/render.ts + client-side static/board.js
in sync), with 4 new TDD tests:
- renders owner pill when project_owner is set
- omits owner pill when empty
- renders short YYYY-MM-DD date when last_commit_iso is set
- omits date span when null

CSS: .badge.owner = transparent + border (visually distinct from solid
.badge.project), .date = small muted tabular-nums. Smoke-verified in browser.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 15:42:59 +03:00
vitya
c0661fb7b3 feat(viewer): group-by-project toggle + Gitea 404 handling
- static/board.js: full rerender on toggle-grouping; by-project mode = N cols
  per project with status-badge inside cards, sorted by canonical status order
- static/board.css: drop placeholder, add .badge.status
- src/gitea.ts: getLatestCommitIso returns null on 404 (path never existed
  remotely; seen on books repo where some per-task slugs in STATUS.md
  don't have file in default branch) + new test
- .gitignore: dist/ already present; add .playwright-mcp/, board-*.png

Smoke-verified: dist/index.html, 78 records from 4 repos, both toggle modes
work in browser, drawer lazy-fetches markdown.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 14:48:56 +03:00
vitya
5bbbd0b533 feat(render): renderBoard + formatAge + partition (17 tests)
Pure renderer logic for the 5-col kanban view.
- formatAge: m/h/d/w/mo/y with calendar-month arithmetic
- partitionByStatus: canonical 5-col order
- renderBoard: 5 columns, cards with data-slug/data-raw-url/data-archived,
  HTML-escaped fields, JSON embed escaped via \uXXXX (XSS-safe)
- archived flag: done > 14d hidden by default (toggle visible)
- align task acceptance emoji set to 🔴🟡🔵🟢

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 14:43:29 +03:00
vitya
d093693795 feat(reader): Gitea client + config + board orchestrator
closes board-viewer-gitea-reader

- src/gitea.ts: HTTP client (getFile, getLatestCommitIso, rawUrl); DI'd fetch
- src/reader.ts: readBoard(client, repos) → TaskRecord[]
- src/config.ts: TOML config loader with board_viewer_repos whitelist
- 25 tests total (9 parser incl. 3 real-repo fixtures, 7 gitea, 5 reader, 4 config)
- emoji contract 🔴🟡🔵🟢 (open/in_progress/paused/blocked/done)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 12:48:37 +03:00
vitya
1c7e372abf feat(reader): STATUS.md parser + TS project scaffold [skip-tdd: visual for configs]
- vitest+TS scaffold (package.json/tsconfig/vitest.config = config artifacts)
- src/parser.ts: parses STATUS.md blocks → StatusBlock[]
- tests/parser.test.ts: 6 cases (single, multi, blocker, null-blocker, empty, unknown emoji)
- fix emoji contract: align with using-tasks reality ( open / 🔴 in_progress / 🟡 paused / 🔵 blocked / 🟢 done); reader-task acceptance + design doc updated

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 12:44:11 +03:00