# board-viewer-whitelist-auto-discovery ## Goal Текущий `board_viewer_repos` в `auth.toml` — explicit list репо. При добавлении нового репо нужен edit + restart. Zero-maintenance подход: хранить **list of orgs/users**, build-контейнер сам discover'ит репо через Gitea API. ## Design open questions — РЕШИТЬ ДО ИМПЛА 1. **Schema:** `board_viewer_repos: [...]` остаётся как backward-compat (explicit list)? Или заменяется на `board_viewer_namespaces: ["victor", "cancel_music", "OpeItcLoc03"]`? - Recommend: **обе**. Namespace-list автодискаверит, explicit-list оверрайдит / включает специальные. Build merge'ит обе. 2. **Filter criteria:** что считать «board-able» репо? - Recommend: репо имеет файл `.tasks/STATUS.md` на default branch (через `/api/v1/repos///contents/.tasks/STATUS.md` HEAD-probe). Если 404 — пропустить тихо. 3. **API endpoint:** `/api/v1/orgs//repos` для org'ов, `/api/v1/users//repos` для users. Какой namespace что — knowable заранее? Или try-both? - Recommend: try org → fall back to user. Кэшировать результат на время сессии build-контейнера (next-tick refresh). 4. **Pagination:** Gitea API limit ~50 репо/page. Сколько у нас всего на org? `OpeItcLoc03` ≥5, `victor` ≥10, `cancel_music` ≥4. Single page достаточно сейчас, но добавить pagination loop на будущее. 5. **Error handling:** API rate-limit, network blip, partial response. Build-контейнер должен сделать best-effort, не crash'нуть entire tick. 6. **Exclusions:** в namespace может быть много not-board-able репо (forks, archives, dotfiles). Filter — только по `.tasks/STATUS.md` существованию (см. #2). Может быть нужны явные exclude-patterns (`board_viewer_exclude: ["**/legacy-*"]`)? Recommend: defer пока не появится конкретный кейс. ## TDD posture **Mode = TDD**. Failing test'ы: - Unit `gitea.ts.listOrgRepos(org)`: возвращает `repo[]` для namespace через mock-fetch - Unit `gitea.ts.hasStatusMd(owner, repo)`: HEAD-probe, true/false - Unit `config.ts`: merge `board_viewer_namespaces` + `board_viewer_repos` → deduped list - Integration: build-контейнер с namespace-config'ом → reader gets ~N repos - E2E smoke на dev: namespace=victor → board показывает stostayer.new + books + pilonuxt etc. (те у которых .tasks/STATUS.md) ## Key files - `src/gitea.ts` — новые методы `listOrgRepos`, `listUserRepos`, `hasStatusMd` - `src/config.ts` — schema: `board_viewer_namespaces?: string[]`, merge logic - `src/reader.ts` — собрать full repo-list before iterating - `tests/gitea.test.ts`, `tests/config.test.ts`, `tests/reader.test.ts` - `deploy/auth.toml.example` — пример с обеими опциями - `deploy/README.md` — описать обе schema ## Pre-impl - Brainstorm перед коммитом первой строки кода — 6 design-вопросов выше. Single-session с user'ом, если рекомендации принимаются — стартовать impl с design-комментарием в decisions log. Если возникает дилемма — `.workshop/.brainstorm/board-viewer-whitelist-auto-discovery.md`. ## Acceptance criteria - Build-контейнер с `board_viewer_namespaces = ["victor", "cancel_music", "OpeItcLoc03"]` автоматом подтягивает все репо у которых есть `.tasks/STATUS.md` - Добавление нового репо в namespace → виден на board без edit'а auth.toml (только next-tick через 5 мин) - Обратная совместимость: existing `board_viewer_repos` всё ещё работает (merge'ится) - Все тесты pass + новые тесты для namespace-discovery - Smoke на board.kzntsv.site — видны репо со всех 3 namespace'ов ## Notes - Связано с quick-win ops-таской `~/projects/.admin/.tasks/board-viewer-expand-whitelist.md` — пока эта code-таска не сделана, админ edit'ит whitelist руками. - Может быть скомбинирована с round2 UX-фиксами (если они появятся). Не блокер для round1 review umbrella.