# MODELO DE DOMINIO: Autenticación y Autorización **Módulos:** MGN-001 (Fundamentos), MGN-002 (Empresas) **Fecha:** 2025-11-24 **Referencia Odoo:** base, auth_signup **Referencia Gamilit:** auth_management schema --- ## Diagrama de Entidades (Texto UML) ``` [Tenant] - id: UUID (PK) - name: String - subdomain: String - schema_name: String - status: ENUM (active, suspended) - settings: JSONB 1 <----> * [Company] 1 <----> * [User] [Company] - id: UUID (PK) - tenant_id: UUID (FK) - name: String - tax_id: String - currency_id: UUID (FK) - settings: JSONB 1 <----> * [User] [User] - id: UUID (PK) - tenant_id: UUID (FK) - email: String (UNIQUE per tenant) - password_hash: String - full_name: String - status: ENUM (active, inactive, suspended) - is_superuser: Boolean * <----> * [Role] (through UserRole) 1 <----> * [Session] [Role] - id: UUID (PK) - tenant_id: UUID (FK) - name: String - code: String - description: Text * <----> * [Permission] (through RolePermission) [Permission] - id: UUID (PK) - resource: String (ej: 'purchase_orders') - action: ENUM (create, read, update, delete, approve) - description: Text [Session] - id: UUID (PK) - user_id: UUID (FK) - token: String - expires_at: Timestamp - ip_address: String - user_agent: String [UserRole] (many-to-many) - user_id: UUID (FK) - role_id: UUID (FK) [RolePermission] (many-to-many) - role_id: UUID (FK) - permission_id: UUID (FK) ``` ## Entidades Principales ### 1. Tenant (Multi-Tenancy) **Descripción:** Representa un tenant (empresa matriz o grupo). Cada tenant tiene su propio schema PostgreSQL. **Atributos:** - `id`: Identificador único - `name`: Nombre del tenant - `subdomain`: Subdominio (ej: 'acme' → acme.erp.com) - `schema_name`: Nombre del schema PostgreSQL (ej: 'tenant_acme') - `status`: Estado (active, suspended) - `settings`: Configuración JSON (logo, tema, etc.) **Relaciones:** - 1 Tenant → N Companies - 1 Tenant → N Users **Patrón Odoo:** Similar a res.company pero en un nivel superior **Patrón Gamilit:** Implementado con schema-level isolation **RLS Policy:** ```sql -- Usuarios solo ven su tenant CREATE POLICY tenant_isolation ON tenants USING (id = get_current_tenant_id()); ``` ### 2. Company (Empresa) **Descripción:** Empresa dentro de un tenant. Permite multi-empresa. **Atributos:** - `id`: UUID - `tenant_id`: Tenant propietario - `name`: Nombre empresa - `tax_id`: RFC/Tax ID - `currency_id`: Moneda por defecto - `settings`: JSONB (dirección, contacto, etc.) **Relaciones:** - N Companies → 1 Tenant - 1 Company → N Users (usuarios pueden estar en múltiples empresas) **Patrón Odoo:** res.company **Validaciones:** - Un tenant debe tener al menos 1 company - tax_id único por tenant ### 3. User (Usuario) **Descripción:** Usuario del sistema con roles y permisos. **Atributos:** - `id`: UUID - `tenant_id`: Tenant propietario - `email`: Email (único por tenant) - `password_hash`: bcrypt hash - `full_name`: Nombre completo - `status`: active, inactive, suspended - `is_superuser`: Admin total del tenant **Relaciones:** - N Users → 1 Tenant - N Users ←→ N Roles (many-to-many) - 1 User → N Sessions **Patrón Odoo:** res.users **Patrón Gamilit:** auth.users con tenant_id **Validaciones:** - email único por tenant (no global) - password mínimo 8 caracteres - is_superuser requiere aprobación **RLS Policy:** ```sql CREATE POLICY users_own_tenant ON users USING (tenant_id = get_current_tenant_id()); ``` ### 4. Role (Rol) **Descripción:** Rol con permisos asignados (RBAC). **Atributos:** - `id`: UUID - `tenant_id`: Tenant propietario - `name`: Nombre del rol - `code`: Código único (ej: 'admin', 'buyer') - `description`: Descripción **Relaciones:** - N Roles → 1 Tenant - N Roles ←→ N Permissions **Patrón Odoo:** res.groups **Roles predefinidos:** - `admin`: Administrador del tenant - `manager`: Gerente (full access transaccional) - `user`: Usuario normal - `readonly`: Solo lectura ### 5. Permission (Permiso) **Descripción:** Permiso granular sobre recursos. **Atributos:** - `id`: UUID - `resource`: Recurso (tabla/endpoint) (ej: 'purchase_orders') - `action`: create, read, update, delete, approve, cancel **Ejemplo de permisos:** ``` Resource: purchase_orders Actions: create, read, update, delete, approve ``` **Patrón Odoo:** ir.model.access + ir.rule **Implementación:** Validado en backend + RLS policies en BD ### 6. Session (Sesión) **Descripción:** Sesión JWT de usuario. **Atributos:** - `id`: UUID - `user_id`: Usuario propietario - `token`: JWT token - `expires_at`: Expiración - `ip_address`: IP de origen - `user_agent`: Navegador **Patrón Gamilit:** auth.sessions ## Reglas de Negocio ### RN-AUTH-001: Multi-Tenancy Obligatorio - TODO usuario pertenece a exactamente 1 tenant - TODO dato transaccional tiene tenant_id - Aislamiento completo entre tenants (schema-level) ### RN-AUTH-002: RBAC Granular - Usuario puede tener múltiples roles - Permisos se calculan como UNION de permisos de roles - is_superuser bypassa todos los checks ### RN-AUTH-003: Sesiones JWT - Expiración: 8 horas - Refresh token: 30 días - Invalidación: Logout o expiración ### RN-AUTH-004: Passwords Seguros - Mínimo 8 caracteres - Debe incluir: mayúscula, minúscula, número - bcrypt hash (cost factor 12) ## Casos de Uso Principales 1. **UC-AUTH-001:** Login de usuario 2. **UC-AUTH-002:** Registro de nuevo tenant 3. **UC-AUTH-003:** Asignar rol a usuario 4. **UC-AUTH-004:** Validar permisos para acción 5. **UC-AUTH-005:** Reset password 6. **UC-AUTH-006:** Cambiar de empresa (multi-company) ## Validaciones y Constraints ```sql -- Email único por tenant UNIQUE (tenant_id, email) -- Status válidos CHECK (status IN ('active', 'inactive', 'suspended')) -- Al menos 1 admin por tenant -- (trigger custom) -- Session expiration CHECK (expires_at > created_at) ``` ## Índices Requeridos ```sql CREATE INDEX idx_users_tenant_id ON auth.users(tenant_id); CREATE INDEX idx_users_email ON auth.users(email); CREATE INDEX idx_sessions_user_id ON auth.sessions(user_id); CREATE INDEX idx_sessions_token ON auth.sessions(token); CREATE INDEX idx_user_roles_user_id ON auth.user_roles(user_id); ``` ## Referencias - [ALCANCE-POR-MODULO.md - MGN-001](../../01-definicion-modulos/ALCANCE-POR-MODULO.md#mgn-001) - [odoo-base-analysis.md](../../00-analisis-referencias/odoo/odoo-base-analysis.md) - [ADR-006: RBAC](../../adr/ADR-006-rbac-sistema-permisos.md)