Files
mercadodevida/work/artifacts/F-154/implementer.md
2026-08-22 08:35:46 +02:00

2.4 KiB

F-154 — Implementer Evidence

Feature

F-154 — Admin: separate customers from internal users (fix, high/high).

Changes (all under project/)

Backend

  1. users/infrastructure/pg-profile-repository.ts (listCustomersGET /users): Added literal iu.role = 'customer' AND to 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).
  2. security/api/security.routes.ts (GET /admin/users): Base condition ["role <> 'customer'"] so the Users list NEVER returns storefront customers. ?role=admin|editor still narrows within internal staff via role = $N. ?role=customer resolves to an empty intersection (no leak). where is always present.

Frontend (apps/admin)

  • (dashboard)/users/page.tsx: removed the customer option 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 — listCustomers emits iu.role = 'customer' on SELECT+COUNT; q stays parametrized as $1.
  • security/api/security.routes.test.ts (NEW, 3 tests): mock Fastify + mock deps — /admin/users default → role <> 'customer'; ?role=admin → adds role = $1 with param; ?role=customer → empty (intersection), never returns customers.
  • app/tests/users.itest.ts AC2/AC3: flipped — /users returns 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.