469ff112ccaceb2be0cdb952a5f2d54328f54e33
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>
board-viewer
About
Read-only HTML kanban-viewer над .tasks/*.md + Gitea API. Рендерит 5-колоночную доску (⚪ open / 🔴 in-progress / 🟡 paused / 🔵 blocked / 🟢 done) по агрегированным таскам из всех whitelisted проектов.
Хост: board.kzntsv.site за traefik на VDS. Обновление: cron-тик ~5 мин, перегенерация статической HTML.
Design: .wiki/concepts/board-viewer.md (canonical). Process trace: ~/projects/.workshop/.archive/2026-05-22-board-viewer.md.
Quick start
npm install
npm test # 43 tests
npm run typecheck
# Local build (writes ./dist):
node --experimental-strip-types src/cli.ts <path-to-auth.toml>
# auth.toml needs: gitea_url, gitea_token, board_viewer_repos = ["owner/repo", ...]
# See deploy/auth.toml.example for the full shape.
# Then open dist/index.html via any static server, e.g.
( cd dist && python -m http.server 8765 ) &
# → http://localhost:8765/
Deploy
See deploy/README.md — Docker-compose stack on VDS, Traefik route + basic-auth.
Architecture
src/parser.ts STATUS.md (markdown) → StatusBlock[] (pure)
src/gitea.ts Gitea HTTP API (DI'd fetch) → file content + last commit ISO + raw URL
src/reader.ts readBoard(client, repos) → TaskRecord[] (orchestrator)
src/render.ts renderBoard(records, opts) → HTML string (pure)
src/cli.ts load config → reader → render → dist/index.html + dist/static/
static/ CSS + ESM JS (filter, drawer, toggle-grouping)
Read-only: write-side intentionally absent. Drag-drop blocked on upstream
projects-meta bug cluster — see brainstorm trace.
Description
Languages
TypeScript
73.1%
JavaScript
16.7%
CSS
10.2%