Files
brain-of-reese/.agent/user_stories/git-sources-admin.md
T

54 lines
2.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Story: Admin Page to Add / Remove Git Sources
**Phase:** `35_git_sources_admin` · **E2E:** `tests/e2e/test_git_sources_admin.py`
## Narrative
As **the admin (owner)**, today I manage the git repos that feed the
knowledge base by editing `BOR_GIT_SOURCES` in `.env` and restarting. I
want a page only I can access where I can **add and remove git
sources** — no env file, no restart — and have the Sync button
(phase 32) and `import_docs` (phase 28) use that stored list.
- **Given** I am signed in as admin
- **When** I open the Git sources page and add a repo URL (or remove
one)
- **Then** the change is stored in Postgres (`git_sources` table) and
the next sync / import uses the stored list — the
`BOR_GIT_SOURCES` env var remains only a fallback while the table is
empty, and phase 32's fail-loud "no git sources configured" is
preserved when both are empty.
## Acceptance criteria
1. Migration 0006: `git_sources` (id UUID PK, url TEXT UNIQUE NOT
NULL, added_at TIMESTAMPTZ) — reversible, integration-tested
up/down (existing migration-test pattern).
2. Admin-only API (phase 16 pattern — 403 `admin only` anonymous):
`GET /api/git-sources` (DB rows in added order; while the table is
empty, the env list with `from_env: true`), `POST /api/git-sources`
{url} (trimmed, 1–500 chars, `https?://` / `ssh://` / `git@`
shape, 409 on duplicate with a detail that never echoes the URL),
`DELETE /api/git-sources/{id}` (204 / 404).
3. `effective_git_sources()` shared by `app/api/sync.py::_run_sync`
and `scripts/import_docs.py`: DB rows win, env fallback only while
the table is empty, fail-loud unchanged when both are empty; the
sync log line records the list origin (`origin=db|env`).
4. `/git-sources.html` — soft-gated like the Sources page (anonymous:
sign-in gate) with the standard header (phase 34) and an
admin-only "Git sources" nav link on all five pages (phase 29
pattern): sources list (mono URL + added date + per-row Remove),
an add form (labeled input + Add, inline error, never-stale button
per §7.4), an env-fallback note while the table is empty, and a
hint that the KB itself updates via the Sync button.
5. `.env.example` + README: `BOR_GIT_SOURCES` documented as the
empty-table fallback; the admin page is the primary management UI.
6. Unit + integration green, `app/` coverage >90%, story E2E green in
isolation, ruff + pyright clean, one `--no-gpg-sign` commit.
## Playwright Mapping Rule
`tests/e2e/test_git_sources_admin.py` — one story, one file, run in
isolation: anonymous gets the sign-in gate (and 403s on the API); the
admin adds/removes sources on the page (the list updates live, invalid
input gets an inline error) and reaches the page via the "Git
sources" nav link on every page.