- Add UpdateCurrentCompanyUseCase to handle company updates. - Create update-current-company.controller.ts to manage update requests. - Implement validation and mapping for update requests using Zod. - Add tests for the update use case and controller to ensure functionality. - Introduce error handling and feedback state management for company details settings. - Create utility functions for error normalization and feedback state resolution. - Implement tests for error handling and feedback state utilities. - Ensure nullable fields are handled correctly in DTOs and forms.
2.9 KiB
Tenant Context
Objetivo
Documentar cómo se resuelve el contexto tenant actual del ERP mediante X-Company-Id y requireIdentityTenant(params).
Header tenant
Las rutas tenant-scoped deben recibir:
Authorization: Bearer <access_token>
X-Company-Id: <uuid-company>
X-Company-Id es el identificador de la company activa en la request.
No usar:
X-Company-SlugcompanySlugen tokenreq.user.companySlug
Middleware público
Para rutas tenant-scoped:
import { requireIdentityTenant } from "@erp/identity/api";
router.use(...requireIdentityTenant(params));
Para rutas solo autenticadas:
import { requireIdentityAuthenticated } from "@erp/identity/api";
router.use(...requireIdentityAuthenticated(params));
Validación real de requireIdentityTenant(params)
Actualmente ya valida:
- access token válido
- account autenticable
X-Company-IdpresenteX-Company-Idcon formato UUID válido- membership
activeenidentity_company_memberships - company
activeencompanies - solo entonces rellena
req.user.companyId
Esto significa que hoy el contexto tenant garantiza:
membership activa
+ company activa
pero no enforcement de permisos granulares por operación.
Semántica esperada de errores
sin Authorization -> 401
token inválido -> 401
cuenta inexistente/no autenticable -> 401
sin X-Company-Id -> 403
X-Company-Id inválido -> 400
company inexistente -> 403
company disabled -> 403
membership inexistente -> 403
membership disabled/invited -> 403
membership active + company active -> entra al controller
Shape mínimo de req.user
{
userId: UniqueID;
email?: EmailAddress;
companyId?: UniqueID;
roles?: string[];
}
No añadir:
companySlugcompanypermissionsenriquecidoscompanyStatus
Módulos tenant-scoped migrados
Actualmente usan requireIdentityTenant(params):
modules/companiesparaGET /companies/current,PATCH /companies/currenty endpoints company-scoped legacymodules/catalogsmodules/customersmodules/customer-invoicesmodules/factuges
modules/supplier queda fuera de esta migración por ahora.
Qué no debe ir en el token
El access token no debe incluir:
companyIdcompanySlug- roles
- permisos
El contexto tenant se resuelve por request con X-Company-Id.
Caso actual: company settings
/settings/company/details opera siempre sobre la company activa.
Endpoints:
GET /companies/current
PATCH /companies/current
Política V1:
usuario autenticado
+ X-Company-Id válido
+ membership activa en esa company
+ company activa
No se aplica todavía un permiso específico como identity:companies:update.
Document context
Si un flujo documental necesita companySlug, debe resolverlo desde companies, por ejemplo:
companyId -> companies:general.finder.findById(...) -> slug