2.4 KiB
2.4 KiB
F-154 — Implementer Evidence
Feature
F-154 — Admin: separate customers from internal users (fix, high/high).
Changes (all under project/)
Backend
users/infrastructure/pg-profile-repository.ts(listCustomers→GET /users): Added literaliu.role = 'customer' ANDto both the COUNT and SELECT WHERE clauses. Parameter indices unchanged ($1= email search,$2= limit,$3= offset) since the role filter is a code constant, not a bound parameter (no injection).findCustomerById(/users/:id) is untouched (owner-or-admin, role-agnostic).security/api/security.routes.ts(GET /admin/users): Base condition["role <> 'customer'"]so the Users list NEVER returns storefront customers.?role=admin|editorstill narrows within internal staff viarole = $N.?role=customerresolves to an empty intersection (no leak).whereis always present.
Frontend (apps/admin)
(dashboard)/users/page.tsx: removed thecustomeroption from the Users role filter dropdown. The Customers page is unchanged (already calls/users, now customer-only).
Tests
users/infrastructure/pg-profile-repository.test.ts(NEW, 3 tests): mock pool —listCustomersemitsiu.role = 'customer'on SELECT+COUNT;qstays parametrized as$1.security/api/security.routes.test.ts(NEW, 3 tests): mock Fastify + mock deps —/admin/usersdefault →role <> 'customer';?role=admin→ addsrole = $1with param;?role=customer→ empty (intersection), never returns customers.app/tests/users.itest.tsAC2/AC3: flipped —/usersreturns the customer (ben), not the promoted admin (ana). (DB itest, skipped without TEST_DATABASE_URL.)
Verification
npx vitest run <2 new files>→ 6/6 pass (re-run fresh for this session).npm test→ 206 passed / 56 skipped (itests), 0 failures, no regressions.npm run typecheck→ 0 errors.cd project/apps/admin && npx tsc --noEmit→ 0 errors.npm run lint→ no errors/warnings in files touched.npm run lint:boundaries→ no NEW violation (R1 on security.routes.ts → log-broadcaster is pre-existing: git diff shows the import is untouched by F-154)../scripts/verify.sh→ exit 0.
Risk
Medium-high: list semantics change. Mitigated by: single-user /users/:id unchanged,
no migration (identity_users.role already exists), tsc + lint + tests green, itest updated.