Uecko_ERP/docs/architecture/identity-backend-architecture.md

136 lines
2.5 KiB
Markdown
Raw Normal View History

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