Peated QA
Use after Peated code changes need manual behavior checks. This is not a test/lint checklist.
Select Surfaces
| Changed area |
QA |
apps/server/src/orpc/routes/** |
API + any UI/CLI caller |
apps/server/src/worker/**, uploads, queues |
API + worker side effect |
apps/cli/** |
CLI + backing API/DB effect |
apps/web/** |
UI + API calls it depends on |
| schema/migration/data model |
API + CLI + UI path that reads/writes it |
Start Local Runtime
For normal web UI QA, prefer the root pnpm dev command. It starts the web
app, API, worker, package watchers, and shared .env.local setup together,
which matches the expected local development runtime. Use the narrower commands
below only when intentionally isolating one surface.
| Need |
Command |
URL |
| Full app |
pnpm dev |
web: http://localhost:3200, API: http://localhost:4300 |
| API only |
pnpm dev:server:api |
http://localhost:4300 |
| API + worker |
docker compose up -d redis; pnpm dev:server |
http://localhost:4300 |
| Web |
pnpm dev:web |
http://localhost:3200 |
| CLI |
pnpm cli <cmd> |
loads .env.local |
Fallback paired ports when 3200 is busy:
- API:
PORT=4301 CORS_HOST=http://localhost:3202 API_SERVER=http://localhost:4301 URL_PREFIX=http://localhost:3202 pnpm exec dotenv -e .env.local -- pnpm --filter @peated/server start:api
- Web:
API_SERVER=http://localhost:4301 URL_PREFIX=http://localhost:3202 pnpm exec dotenv -e .env.local -- pnpm --dir apps/web exec next dev -p 3202
API QA
- Identify exact route file and operation.
- Hit local API, not
peated.com: http://localhost:4300.
- For public reads, use
curl against the route or spec-shaped endpoint.
- For protected writes, create/login a throwaway local user and send
Authorization: Bearer <token>.
- Check success response, validation failure, auth failure, and not-found/conflict when relevant.
- Verify DB-visible side effects when mutation behavior matters.
- If the route is used by web/CLI, QA that caller too.
Useful refs:
- Local OpenAPI in dev:
http://localhost:4300/spec.json
- Production API host for comparison only:
https://api.peated.com
- Public API paths are under
/v1/*.
For protected local API QA, use the stable local QA account. Reusing the same
account keeps test data bounded and makes repeated QA runs predictable:
pnpm cli users create qa@example.com password123 --verified --accept-terms --if-exists
pnpm cli users generate-token qa@example.com
Keep the printed token out of committed docs and final reports. Use
Authorization: Bearer <token> for protected local API requests.
CLI QA
- Run the changed command through root scripts, not direct
tsx: pnpm cli <cmd>.
- For aliases, prefer root scripts when present:
pnpm bottles, pnpm entities, pnpm tastings, pnpm mocks, pnpm user, pnpm db.
- Use a harmless local fixture or throwaway record.
- Verify stdout/stderr, exit status, and DB/API side effect.
- For destructive commands, use dry-run/help first when available; otherwise use local throwaway data only.
- If a CLI command drives server logic, also QA the matching API route or DB result.
Classifier QA
Use this for changes under packages/bottle-classifier/** or
apps/server/src/agents/bottleClassifier/**.
- For bottle-name checks, run:
pnpm cli classifier run "Ardbeg Uigeadail".
- For image checks, run:
pnpm cli classifier run --image /path/to/bottle.jpg or
pnpm cli classifier run --image https://example.com/bottle.jpg.
- For exact contract payloads, run:
pnpm cli classifier run --input-file /tmp/classifier-input.json.
- Use
--initial-only when the check should stay closed-set and avoid follow-up
bottle/web search.
- Live classifier runs use
.env.local, local DB adapters, and OpenAI config.
They may call OpenAI and local search depending on the reference.
- Pair manual classifier smoke checks with package validation:
pnpm --filter @peated/bottle-classifier typecheck and focused tests or evals.
Minimal input-file payload:
{
"reference": { "name": "Ardbeg Uigeadail" },
"candidateExpansion": "initial_only"
}
UI QA
- Start API and web with matched origins.
- Read
docs/development/local-web-checks.md before protected,
owner-only, or moderator UI checks.
- Choose the auth primitive before opening the target route:
- Public/read-only route: no session setup.
- Normal protected workflow: use the UI login path.
- Owner/moderator-only visual check: use the local verification playbook to
create a session cookie for the exact user/role being inspected, then
reload the target route.
- Protected mutation: use a real local user and access token/session, not a
display-only cookie.
- Use
agent-browser for browser checks.
- Open the exact target route after auth is ready, then inspect it with both
accessibility snapshots and screenshots.
- Verify desktop and mobile widths for changed user-facing flows.
- Prefer normal login:
/login?redirectTo=/addBottle -> Sign in with Email -> Or sign in with a password.
- For local protected UI checks, seed a throwaway verified active user with
termsAcceptedAt, then log in through the UI. Do not use bearer-token API
setup or a manually sealed _session cookie for UI QA unless normal UI login
is blocked by unrelated local service noise.
- For moderator flows, set that throwaway user
mod: true.
- For bottle entry changes, check
/addBottle and /bottles/<id>/edit.
- Inspect rendered state, network/API outcome, persistence after reload, and error/empty/loading states when changed.
- Clean up throwaway local users/records when done.
Agent-browser primitives:
- Set the viewport before capture: desktop first, then mobile.
- Use
snapshot -i -c to verify reachable controls and table/list structure.
- Save screenshots under
/tmp with names that include the route and viewport.
- For owner-only columns or controls, verify the public state only if it is part
of the requested behavior; otherwise authenticate first and avoid spending
time on the wrong state.
Finish With Evidence
Report:
- Surfaces QAed: API / CLI / UI.
- Commands and URLs used.
- Browser viewport(s), if UI.
- Data used or created.
- Pass/fail per scenario.
- Any skipped surface and why.
1---2name: peated-qa3description: Use when manually QAing Peated changes across the API, CLI, or web UI; selecting smoke checks after code changes; using agent-browser for Peated flows; verifying local behavior beyond tests and lint.4---56# Peated QA78Use after Peated code changes need manual behavior checks. This is not a test/lint checklist.910## Select Surfaces1112| Changed area | QA |13| -------------------------------------------- | ---------------------------------------- |14| `apps/server/src/orpc/routes/**` | API + any UI/CLI caller |15| `apps/server/src/worker/**`, uploads, queues | API + worker side effect |16| `apps/cli/**` | CLI + backing API/DB effect |17| `apps/web/**` | UI + API calls it depends on |18| schema/migration/data model | API + CLI + UI path that reads/writes it |1920## Start Local Runtime2122For normal web UI QA, prefer the root `pnpm dev` command. It starts the web23app, API, worker, package watchers, and shared `.env.local` setup together,24which matches the expected local development runtime. Use the narrower commands25below only when intentionally isolating one surface.2627| Need | Command | URL |28| ------------ | ----------------------------------------------- | ---------------------------------------------------------- |29| Full app | `pnpm dev` | web: `http://localhost:3200`, API: `http://localhost:4300` |30| API only | `pnpm dev:server:api` | `http://localhost:4300` |31| API + worker | `docker compose up -d redis`; `pnpm dev:server` | `http://localhost:4300` |32| Web | `pnpm dev:web` | `http://localhost:3200` |33| CLI | `pnpm cli <cmd>` | loads `.env.local` |3435Fallback paired ports when `3200` is busy:3637- API:38 `PORT=4301 CORS_HOST=http://localhost:3202 API_SERVER=http://localhost:4301 URL_PREFIX=http://localhost:3202 pnpm exec dotenv -e .env.local -- pnpm --filter @peated/server start:api`39- Web:40 `API_SERVER=http://localhost:4301 URL_PREFIX=http://localhost:3202 pnpm exec dotenv -e .env.local -- pnpm --dir apps/web exec next dev -p 3202`4142## API QA43441. Identify exact route file and operation.452. Hit local API, not `peated.com`: `http://localhost:4300`.463. For public reads, use `curl` against the route or spec-shaped endpoint.474. For protected writes, create/login a throwaway local user and send `Authorization: Bearer <token>`.485. Check success response, validation failure, auth failure, and not-found/conflict when relevant.496. Verify DB-visible side effects when mutation behavior matters.507. If the route is used by web/CLI, QA that caller too.5152Useful refs:5354- Local OpenAPI in dev: `http://localhost:4300/spec.json`55- Production API host for comparison only: `https://api.peated.com`56- Public API paths are under `/v1/*`.5758For protected local API QA, use the stable local QA account. Reusing the same59account keeps test data bounded and makes repeated QA runs predictable:6061```bash62pnpm cli users create qa@example.com password123 --verified --accept-terms --if-exists63pnpm cli users generate-token qa@example.com64```6566Keep the printed token out of committed docs and final reports. Use67`Authorization: Bearer <token>` for protected local API requests.6869## CLI QA70711. Run the changed command through root scripts, not direct `tsx`: `pnpm cli <cmd>`.722. For aliases, prefer root scripts when present: `pnpm bottles`, `pnpm entities`, `pnpm tastings`, `pnpm mocks`, `pnpm user`, `pnpm db`.733. Use a harmless local fixture or throwaway record.744. Verify stdout/stderr, exit status, and DB/API side effect.755. For destructive commands, use dry-run/help first when available; otherwise use local throwaway data only.766. If a CLI command drives server logic, also QA the matching API route or DB result.7778## Classifier QA7980Use this for changes under `packages/bottle-classifier/**` or81`apps/server/src/agents/bottleClassifier/**`.82831. For bottle-name checks, run:84 `pnpm cli classifier run "Ardbeg Uigeadail"`.852. For image checks, run:86 `pnpm cli classifier run --image /path/to/bottle.jpg` or87 `pnpm cli classifier run --image https://example.com/bottle.jpg`.883. For exact contract payloads, run:89 `pnpm cli classifier run --input-file /tmp/classifier-input.json`.904. Use `--initial-only` when the check should stay closed-set and avoid follow-up91 bottle/web search.925. Live classifier runs use `.env.local`, local DB adapters, and OpenAI config.93 They may call OpenAI and local search depending on the reference.946. Pair manual classifier smoke checks with package validation:95 `pnpm --filter @peated/bottle-classifier typecheck` and focused tests or evals.9697Minimal input-file payload:9899```json100{101 "reference": { "name": "Ardbeg Uigeadail" },102 "candidateExpansion": "initial_only"103}104```105106## UI QA1071081. Start API and web with matched origins.1092. Read `docs/development/local-web-checks.md` before protected,110 owner-only, or moderator UI checks.1113. Choose the auth primitive before opening the target route:112 - Public/read-only route: no session setup.113 - Normal protected workflow: use the UI login path.114 - Owner/moderator-only visual check: use the local verification playbook to115 create a session cookie for the exact user/role being inspected, then116 reload the target route.117 - Protected mutation: use a real local user and access token/session, not a118 display-only cookie.1194. Use `agent-browser` for browser checks.1205. Open the exact target route after auth is ready, then inspect it with both121 accessibility snapshots and screenshots.1226. Verify desktop and mobile widths for changed user-facing flows.1237. Prefer normal login:124 `/login?redirectTo=/addBottle` -> `Sign in with Email` -> `Or sign in with a password`.1258. For local protected UI checks, seed a throwaway verified active user with126 `termsAcceptedAt`, then log in through the UI. Do not use bearer-token API127 setup or a manually sealed `_session` cookie for UI QA unless normal UI login128 is blocked by unrelated local service noise.1299. For moderator flows, set that throwaway user `mod: true`.13010. For bottle entry changes, check `/addBottle` and `/bottles/<id>/edit`.13111. Inspect rendered state, network/API outcome, persistence after reload, and error/empty/loading states when changed.13212. Clean up throwaway local users/records when done.133134Agent-browser primitives:135136- Set the viewport before capture: desktop first, then mobile.137- Use `snapshot -i -c` to verify reachable controls and table/list structure.138- Save screenshots under `/tmp` with names that include the route and viewport.139- For owner-only columns or controls, verify the public state only if it is part140 of the requested behavior; otherwise authenticate first and avoid spending141 time on the wrong state.142143## Finish With Evidence144145Report:146147- Surfaces QAed: API / CLI / UI.148- Commands and URLs used.149- Browser viewport(s), if UI.150- Data used or created.151- Pass/fail per scenario.152- Any skipped surface and why.