# QA Audit Plan — 2026-06-25 > **Loop**: [010 — The full product evaluation loop](https://signals.forwardfuture.com/loop-library/loops/full-product-evaluation-loop/) > **Verify**: Every inventoried product surface meets its documented acceptance criteria. The final full regression run covers every inventoried surface and its finite risk-based edge cases in the production-like local environment, with each reproducible bug fixed and backed by evidence. ## Scope - **Surfaces**: `/admin/*` (all 19 modules) + public/auth pages - **Role**: `platform_admin` via `dev_session` cookie - **Environment**: Local Postgres 16 in Docker (`routeqa-pg` on :5433), `npm run dev` on :4000 - **Data scale**: 2 brands, ~1000 products, 100 stops, 1000 customers, 2000 orders per brand, plus communications/wholesale/time-tracking/water-log/audit data ## Env Differences from Production (recorded per loop spec) 1. **Neon Auth stubbed**: `neon_auth.user` table is a minimal local stub (no real auth provider). `dev_session` cookie impersonates roles. 2. **Migration 0002 skipped**: `0002_admin_password.sql` references a legacy `users` table that does not exist in the current schema (post-Neon-Auth migration). Recorded as applied in `_migrations` to skip cleanly. Documented for fix in a follow-up. 3. **Migration 0000 added**: `0000_qa_neon_auth_stub.sql` creates the `neon_auth` schema stub before `0001_init.sql` runs. Local-only. 4. **Seed file**: `db/seeds/2026-qa-audit-scale.sql` (QA-only) replaces the broken `db/seed.ts` (column drift). Local-only. 5. **API keys**: Stripe / Resend / Square placeholders (`sk_test_placeholder_for_qa_audit`, etc.) so imports don't crash. Real network calls would fail; we don't exercise them. 6. **Database port**: 5433 (not 5432 — that's n8n's Postgres). ## Phases - [x] **Phase 1**: Environment bootstrap (Postgres container, migrations, seed, dev server, auth verification) - [ ] **Phase 2**: Inventory every feature/route/control/state/workflow → `INVENTORY.md` - [ ] **Phase 3**: Define acceptance criteria + finite risk-based edge cases → `ACCEPTANCE-CRITERIA.md` - [ ] **Phase 4**: Write Playwright spec harness → `tests/e2e/audit/` - [ ] **Phase 5**: Execute Playwright runs, log bugs → `BUGS.md` - [ ] **Phase 6**: Triage shared causes/dependencies - [ ] **Phase 7**: Implement fixes with regression tests - [ ] **Phase 8**: Re-run affected paths + full inventory; stop at clean pass ## Risk Tiers (depth-weighted testing) | Tier | Examples | Playwright depth | |---|---|---| | **Critical** | Auth, RBAC, order mutation, payment flows, customer data exposure | Full coverage including bypass attempts | | **High** | Settings, communications send, wholesale lifecycle, water-log entry | Each button + edge case | | **Medium** | Listing/pagination, filters, search, exports | Happy path + edge cases (empty, many) | | **Low** | Static display pages, help text, "About" pages | Smoke test only | ## Artifacts ``` docs/qa/audit-2026-06-25/ ├── PLAN.md # this file ├── INVENTORY.md # every feature, route, control, state, workflow ├── ACCEPTANCE-CRITERIA.md # criteria + edge cases per item ├── BUGS.md # bug log with reproduction evidence ├── ENV-DIFF.md # env differences from prod └── evidence/ # screenshots, network captures tests/e2e/audit/ ├── helpers/ # shared Playwright utilities ├── auth/ # public + auth page tests └── admin/ # per-module admin tests ``` ## Stop Condition Per loop: stop only at a clean full pass OR an explicit blocked handoff (with documented blocker).