# Identity Backend Architecture ## Objetivo del módulo `identity` `identity` sustituye progresivamente al módulo legacy `auth`. Responsabilidades actuales: - cuentas autenticables - login/password - access token - refresh token rotado - logout - sesión actual - memberships - validación de acceso account-company - base para roles/permisos futuros ## Dominio actual Agregados y conceptos relevantes: ```txt Account RefreshToken CompanyMembership Role ``` `Company` funcional no pertenece a `identity`; vive en `modules/companies`. ## Seguridad Servicios definidos: ```txt IPasswordHasher IAccessTokenIssuer IAccessTokenVerifier IRefreshTokenGenerator IRefreshTokenHasher ``` Decisiones vigentes: - password hashing con `bcrypt` - access token JWT con `accountId` y `email` - refresh token aleatorio - refresh token persistido como hash - no incluir `companyId`, `companySlug`, roles ni permisos en access token ## Builders públicos `identity` expone desde `@erp/identity/api`: ```ts requireIdentityAuthenticated(params: StartParams): RequestHandler[]; requireIdentityTenant(params: StartParams): RequestHandler[]; ``` Uso correcto: ```ts import { requireIdentityTenant } from "@erp/identity/api"; router.use(...requireIdentityTenant(params)); ``` ```ts import { requireIdentityAuthenticated } from "@erp/identity/api"; router.use(...requireIdentityAuthenticated(params)); ``` ## `req.user` Shape mínimo esperado: ```ts { userId: UniqueID; email?: EmailAddress; companyId?: UniqueID; roles?: string[]; } ``` `req.user.companyId` solo se debe poblar cuando el middleware tenant valida correctamente la request. No añadir: - `companySlug` - `company` - `permissions` enriquecidos - `companyStatus` ## Tenant validation `requireIdentityTenant(params)` ya no es solo validación sintáctica. Valida: 1. token válido 2. account autenticable 3. `X-Company-Id` presente 4. UUID válido 5. membership `active` 6. company `active` ## Relación con `companies` - `identity` resuelve membership y accesibilidad - `companies` resuelve la ficha operativa de empresa - no introducir dependencia `identity -> companies` Si un consumidor necesita `slug`, debe resolverlo desde `companies`, no desde auth. ## Prohibiciones de diseño No usar en módulos consumidores: ```ts IdentityInternalDeps; authenticateUserDependencies; getInternal("identity"); ``` No crear helpers locales de auth por módulo como patrón estable. No añadir al access token: - `companyId` - `companySlug` - roles - permisos