# Architect — F-006 Users: profile, addresses, RBAC done -> work/artifacts/F-006/architect.md ## Deliverables - specs/F-006-users-rbac/SPEC.md, DESIGN.md, TASKS.md, TESTS.md ## Key decisions 1. **Cross-module auth por inyección, no por imports**: R1 prohíbe que `users` importe `identity`. identity exporta `createSessionAuthenticator` por su index; el composition root lo crea y lo inyecta en `registerUsersRoutes`. El contrato (`CurrentUser`, `Authenticate`, `requireRole`) vive en `src/shared/auth.ts`. 2. **Role en identity_users** (migración 003): fuente única de verdad de autorización, viaja con el usuario autenticado, imposible de escalar vía API (register siempre crea 'customer'; solo DB/migración cambia roles). 3. **Authz antes que existencia**: no-owner recibe 403 sin importar si el recurso existe (AC1 literal; sin enumeración). 4. **Tablas users_profiles / users_addresses** con FK a identity_users solo como integridad de schema; queries runtime tocan únicamente tablas `users_*` (regla de prefijo intacta). 5. **Admin endpoint dentro de users**: GET /users lista profiles (tabla propia). Nada obliga a users a leer identity_users en runtime. 6. **Cero dependencias nuevas**. ## Security posture - Session resolution server-side (hash de token, expiración y revocación en SQL). - Owner-or-admin en cada ruta; admin-only con requireRole. - Role jamás proviene del cliente: sale del JOIN sessions+users en DB. ## Risks - Profiles lazy (no auto-create en register): GET /users lista solo profiles existentes. Aceptado para el slice; documentado.