# Identity And Companies ## Objetivo Documentar la separación actual entre `modules/identity` y `modules/companies`, evitando mezclar autenticación, memberships y ficha operativa de empresa. ## Responsabilidades por módulo ### `modules/identity` Gestiona: - `Account` - login - refresh - logout - session - `RefreshToken` - `CompanyMembership` - acceso `account-company` - roles/permisos futuros Endpoints activos: ```http POST /identity/auth/login POST /identity/auth/refresh POST /identity/auth/logout GET /identity/auth/session ``` El access token contiene solo: ```ts { accountId: string; email: string; } ``` No debe contener: - `companyId` - `companySlug` - roles - permisos ### `modules/companies` Es la fuente de verdad de la ficha operativa de empresa. `Company` funcional vive en `modules/companies`. Campos actuales de `companies`: ```txt id legal_name trade_name tin slug email phone website status created_at updated_at ``` Índices actuales: ```txt UNIQUE(slug) INDEX(status) INDEX(tin) ``` `slug` pertenece a `companies`, no a auth ni al token. ## Relación entre ambos módulos - `CompanyMembership` vive en `identity`. - `Company` vive en `companies`. - No mover memberships a `companies`. - No evolucionar `identity.Company` como ficha operativa ERP. - No usar `customers` para representar la empresa tenant. ## Servicios públicos ### `identity:general` Expone autenticación y acceso por membership. Uso conceptual: ```ts companyAccess.canAccessCompany(...) companyAccess.findAccessibleCompanyIds(...) ``` `identity` devuelve IDs accesibles por membership, no fichas completas de empresa. ### `companies:general` Expone consulta de empresas y validación de empresa activa. Uso conceptual: ```ts ICompanyPublicServices { finder: ICompanyPublicFinder; } ``` ## Por qué no existe `GET /identity/companies` No se documenta `GET /identity/companies` como endpoint válido porque produciría acoplamiento circular: ```txt identity -> companies -> identity ``` Si `identity` devolviera fichas completas de company, tendría que depender de `companies`. Como `companies` ya depende de `identity` para autenticación, el diseño correcto es: - `identity` resuelve membership y accesibilidad por ID - `companies` resuelve la ficha completa de empresa El endpoint vigente para el frontend es: ```http GET /companies/available Authorization: Bearer ``` Tampoco debe documentarse ni introducirse `GET /account/companies` como variante válida. ## Dependencias permitidas Para módulos tenant-scoped que usan `requireIdentityTenant(params)`, la dependencia explícita debe ser hacia: - `identity` - `companies` Porque el middleware tenant compone: ```txt identity:general.companyAccess companies:general.finder ``` ## Dependencias prohibidas No introducir: - `identity -> companies` - recomposición manual de internals de `identity` - `IdentityInternalDeps` - `getInternal("identity")` desde módulos consumidores - helpers locales de auth por módulo como patrón estable ## `GET /companies/available` Semántica actual: - requiere `Authorization` - no requiere `X-Company-Id` - usa `requireIdentityAuthenticated(params)` - devuelve companies activas accesibles para la cuenta autenticada La disponibilidad se calcula con: ```txt membership active en identity + company active en companies ```