- Updated general requirements document to clarify its historical context and remove outdated technical details. - Revised template documentation to serve as a base for writing prompts, emphasizing its auxiliary nature. - Enhanced architecture documentation with clear distinctions between canonical and complementary documents. - Added a new document for backend prompt base to centralize common context for backend prompts. - Created a dedicated README for customer invoices, organizing current contracts, operational support, and historical context. - Improved clarity and structure in various customer invoice documents, consolidating operational semantics and referencing canonical sources.
145 lines
2.7 KiB
Markdown
145 lines
2.7 KiB
Markdown
# Identity Backend Architecture
|
|
|
|
Documento complementario de diseño backend.
|
|
|
|
Para contratos operativos vigentes, prevalecen:
|
|
|
|
- `tenant-context.md`
|
|
- `identity-auth-api.md`
|
|
- `identity-and-companies.md`
|
|
- `modules/identity/README.md`
|
|
|
|
## 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
|