Files
mercadodevida/work/artifacts/F-006/reviewer.json
rikrdo 546971280f feat(F-006): users profile, addresses and RBAC
- users module: profile + address CRUD behind use cases (users_profiles,
  users_addresses)
- roles customer/admin on identity_users; role resolved from DB per request
- shared auth contract (Authenticate, requireRole, requireOwnerOrAdmin)
  injected from composition root; users never imports identity
- authorization runs before existence checks; address SQL scoped by user_id
- @fastify/cookie registered once at app root (cross-module)
- migrations 003_identity_roles + 004_users (reversible)
- no new npm dependencies; tests: unit 52, integration 22

Gates: reviewer/security/qa APPROVED; verify.sh green
2026-08-15 09:28:15 +02:00

36 lines
2.3 KiB
JSON

{
"feature_id": "F-006",
"agent": "reviewer",
"verdict": "APPROVED",
"reviewed_files": [
"project/migrations/003_identity_roles.js",
"project/migrations/004_users.js",
"project/src/shared/auth.ts",
"project/src/shared/tests/auth.test.ts",
"project/src/modules/identity/infrastructure/session-authenticator.ts",
"project/src/modules/identity/infrastructure/pg-user-repository.ts",
"project/src/modules/identity/api/identity.routes.ts",
"project/src/modules/identity/index.ts",
"project/src/modules/users/domain/*",
"project/src/modules/users/application/*",
"project/src/modules/users/infrastructure/pg-profile-repository.ts",
"project/src/modules/users/infrastructure/pg-address-repository.ts",
"project/src/modules/users/api/users.routes.ts",
"project/src/app/build-app.ts",
"project/src/app/tests/users.itest.ts",
"project/src/infrastructure/db/tests/migrations.itest.ts"
],
"checks": [
"Module boundaries: users never imports identity; auth arrives by injection through shared/auth.ts (boundary lint green, 52 files)",
"Authorization order: every users route runs authenticate -> param validation -> requireOwnerOrAdmin BEFORE any data access; non-owner always gets 403",
"SQL ownership: address operations are scoped by user_id in every query (list/create/update/delete), so a known foreign addressId cannot be touched",
"Dynamic UPDATE built only from a hardcoded column whitelist; all values parameterized",
"Migrations additive and reversible: 003 adds role with CHECK + default, 004 owns users_* tables with FKs and ON DELETE CASCADE; full rollback verified in itest",
"Acceptance criteria AC1-AC4 each exercised by a dedicated integration test; AC5 via verify.sh"
],
"non_blocking_observations": [
"GET /users lists rows from users_profiles, i.e. users who have touched their profile at least once; users without a profile row are not listed. Acceptable for F-006 (AC only requires admin-only access semantics); a future admin-listing ticket should decide between an identity-owned user listing port or renaming the endpoint."
],
"evidence": "npm test: 52 passed; npm run test:integration: 22 passed against PostgreSQL 16; lint, boundary check, typecheck, build clean; live smoke exercised all authorization paths"
}