feat: scaffold Brain of Reese — FastAPI RAG chat over Postgres 17 + pgvector
Foundation (phase 01, verified): - FastAPI app: /api/health, /api/suggestions, /api/chat (placeholder), static frontend served locally (no CDN) - Postgres 17 + pgvector via db/Containerfile + compose.yaml (podman compose up -d db), Alembic initial migration (documents, chunks with vector(768), query_log) - LLM client targeting https://aipi.reeseapps.com/v1 (turbo/embed); scripts/llm_probe.py verified models + 768-dim embeddings live - Conditional debugpy: imported only when DEBUGPY=1 (attach on demand, :5678); logging config for clean single-line logs - Frontend shell: mobile-first chat + Sources pages, tokens, a11y baselines - Tests: 24 unit+integration (99% coverage on app/), ruff + pyright clean, Playwright smoke E2E (3 tests) against a deterministic mock LLM - Planning: .agent/PLAN.md (architecture + LOCKED decisions), AGENTS.md, 6 user stories, 7 phase files (one story / one phase / one Playwright suite each)
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
# Phase 05 — Story: Suggestion Chips
|
||||
|
||||
**Story:** `.agent/user_stories/suggestion-chips.md`
|
||||
**Context:** `.agent/PLAN.md` §7 (UI/UX), story file for chip spec
|
||||
|
||||
## Goal
|
||||
Zero-friction onboarding: 3–4 real example questions on first load,
|
||||
clickable → filled → submitted, keyboard-first, mobile-scrollable.
|
||||
|
||||
## Implementation steps
|
||||
1. `app/config.py` — confirm `suggestions` is env-overridable
|
||||
(`BOR_SUGGESTIONS` as JSON list via pydantic-settings) and tune the
|
||||
defaults against the *actually imported* Homelab/Deployments topics
|
||||
(read a sample of `documents` titles; pick questions real answers
|
||||
exist for).
|
||||
2. `app.js` — extract a `renderChips(container, items, {onSelect})` helper;
|
||||
real `<button type="button" class="suggestion-chip" role="listitem">`
|
||||
inside `#suggestions[role="list"]`; onboarding `onSelect` = fill
|
||||
`#message-input` + focus + `composer.requestSubmit()`. Reuse the same
|
||||
helper for deflection chips (Phase 04) with the same submit behavior.
|
||||
3. Empty-state lifecycle: first user message hides `#empty-state` (already
|
||||
done in `addMessage`) — verify chips don't linger in the conversation.
|
||||
4. Mobile CSS check: chip row `nowrap + overflow-x auto` at ≤640px (tokens
|
||||
already exist — verify, don't duplicate).
|
||||
|
||||
## UI Verification
|
||||
Against the story: pills 999px radius, ≥44px, brand-soft/brand-ink (≥6:1),
|
||||
hover/active states; desktop centered wrap vs mobile single scroll row;
|
||||
Tab order reaches chips before the composer input is required; screen
|
||||
reader: group labeled "Suggested questions". Screenshot pass 1280px + 375px.
|
||||
|
||||
## Testing & Quality
|
||||
- Unit/integration: `GET /api/suggestions` honors `BOR_SUGGESTIONS` env
|
||||
override (JSON list); default list has ≥3 non-empty strings.
|
||||
- Coverage: **>90%** on `app/` (JS is covered by E2E).
|
||||
|
||||
## Playwright Execution Phase
|
||||
Run ONLY this story's suite:
|
||||
|
||||
```bash
|
||||
uv run pytest tests/e2e/test_suggestion_chips.py -v --no-cov
|
||||
```
|
||||
|
||||
Implements the story mapping: chips render (≥3, role=list); chip click
|
||||
submits (user bubble with exact chip text + mock reply); keyboard Tab+Enter
|
||||
activates; 375px chip row is a horizontal scroll row.
|
||||
|
||||
## Success criteria
|
||||
- [ ] onboarding chips render from the API; click = one-tap question
|
||||
- [ ] keyboard + SR usable; mobile scroll row
|
||||
- [ ] deflection chips share the component + submit behavior
|
||||
- [ ] unit + integration green, coverage >90%
|
||||
- [ ] story E2E green in isolation
|
||||
- [ ] committed
|
||||
|
||||
## Commit
|
||||
```bash
|
||||
git add -A && git commit --no-gpg-sign -m "feat(ui): onboarding suggestion chips with one-tap submit, keyboard access, and mobile scroll row"
|
||||
```
|
||||
Reference in New Issue
Block a user