M3 Review→Publish UI (#77): one-column flow, searchable pickers, fig/feat tags, e2e
- Review screen: slug-resolved species/wcat groupers, case-insensitive attrs, fig-*/feat-* tag pickers (METADATA-30/40), AI-assist labels + AI bubbles. - App orchestrator: single writable flow store, capture→review→publish, Resume boot. - API client (slabs.ts) mirroring live backend routes; Blob name fix. - Playwright e2e (7 tests, hermetic mock): canvas PNG seed, client-UUID mock, SKU blur commit, ready-state reactive fix; expect timeout 4s, 2 workers. - e2e green 7/7 in 6s; check_requirements + check_coverage PASS.
This commit is contained in:
@@ -14,6 +14,32 @@
|
||||
|
||||
- Subagents run on one local GPU and cannot handle concurrency. Invoke one at a time; never in parallel.
|
||||
|
||||
## Build & test (verified commands)
|
||||
|
||||
Frontend (`frontend/`, Svelte 4 + Vite + TS, no router):
|
||||
|
||||
```
|
||||
cd frontend && npm install
|
||||
npm run test # node --import tsx --test src/**/*.test.ts (unit)
|
||||
npm run build # tsc --noEmit && vite build (type-check + build)
|
||||
npm run test:e2e # playwright test (see Pitfalls: mocks the API)
|
||||
```
|
||||
|
||||
Backend (`backend/`, FastAPI + stdlib sqlite, no ORM, deps pinned in `backend/requirements.txt`):
|
||||
|
||||
```
|
||||
cd backend && python -m pytest tests/ -q
|
||||
uvicorn backend.app:app --host 127.0.0.1 --port 18081
|
||||
```
|
||||
|
||||
No Makefile, no CI workflows, no Gitea CI — nothing runs in a pipeline; the only automation is the local commands above plus the human UAT walk (`deploy/uat_walk.sh`).
|
||||
|
||||
## Conventions
|
||||
|
||||
- The LIVE FastAPI routes in `backend/*.py` are the API source of truth; `docs/contracts/API.md` is aspirational and can drift (it describes a polling model the backend never shipped). Read the router, not the doc, before wiring a client.
|
||||
- Frontend is one Svelte app, no router: `App.svelte` switches on a `writable` flow store. Screens live under `frontend/src/<area>/`.
|
||||
- Commit subjects: `feat(scope): …` / `fix(scope): …` / `test(scope): …` / `chore(scope): …`, often citing a requirement ID or Gitea number.
|
||||
|
||||
## Gates (must pass before claiming work complete)
|
||||
|
||||
Run from repo root:
|
||||
@@ -25,6 +51,14 @@ python tools/check_coverage.py
|
||||
|
||||
Exit 0 on both = pass.
|
||||
|
||||
## Pitfalls
|
||||
|
||||
- E2E mocks the API: `tests/e2e/*.spec.ts` use Playwright `page.route('**/api/v1/**')` with fixture ids — there is **no live backend** under e2e. A green `test:e2e` is not proof the real backend works; that's the human `deploy/uat_walk.sh` (real Woo, never a mock — QUALITY-105).
|
||||
- Ports on the 5060 UAT host (192.168.1.202): FastAPI `18083`, FE `18082`/`10881` are typically already up (compose on `deploy/docker-compose.yml`). Check before binding; don't assume `18081` is free.
|
||||
- `SLAB_UAT_UNMASK_SECRETS=1` makes `GET /settings` return decrypted Woo/inference secrets — dev-test only, never set in prod (SETTINGS-75 masking is the default).
|
||||
- Never hardcode live Woo category/term ids into app code (QUALITY-105 / METADATA-5); resolve groupers by slug (`species`, `wcat`) at runtime.
|
||||
- `tsc` won't catch Svelte template errors; `npm run build` (which runs `tsc --noEmit`) is the real type gate for the frontend.
|
||||
|
||||
## Pointers (read these for everything else)
|
||||
|
||||
- Docs map and shipped status: `docs/README.md`
|
||||
|
||||
Reference in New Issue
Block a user