# RF-MGN-002-003: Asignación de Usuarios a Empresas (Multi-Empresa) **Módulo:** MGN-002 - Empresas y Organizaciones **Prioridad:** P0 (MVP) **Story Points:** 8 **Estado:** Definido **Fecha:** 2025-11-23 ## Descripción El sistema debe permitir asignar usuarios a múltiples empresas y gestionar roles diferenciados por empresa. Un usuario puede tener rol de "Contador" en Empresa A y "Vendedor" en Empresa B. ## Actores - **Actor Principal:** Administrador de Sistema - **Actores Secundarios:** Usuario Multi-Empresa ## Precondiciones 1. Usuario debe existir (RF-MGN-001-003) 2. Empresa debe existir (RF-MGN-002-001) 3. Roles deben estar definidos (RF-MGN-001-002) ## Flujo Principal 1. Administrador accede a Gestión de Usuarios 2. Administrador selecciona usuario 3. Administrador asigna empresa al usuario 4. Administrador selecciona roles específicos para esa empresa 5. Sistema crea registro en auth.user_companies 6. Sistema crea registros en auth.user_company_roles 7. Usuario queda habilitado para acceder a la empresa 8. Usuario ve empresa en lista de empresas disponibles ## Flujos Alternativos ### FA-1: Cambio de Empresa Activa (Context Switching) 1. Usuario autenticado tiene acceso a múltiples empresas 2. Usuario selecciona otra empresa del selector 3. Sistema valida acceso del usuario a la empresa 4. Sistema actualiza contexto: current_company_id = selected_company_id 5. Sistema ejecuta `SET search_path` si aplica 6. Sistema recarga dashboard con datos de nueva empresa 7. Todas las operaciones subsecuentes usan nueva empresa ### FA-2: Roles Diferentes por Empresa 1. Usuario tiene rol "Contador" en Empresa A 2. Usuario tiene rol "Vendedor" en Empresa B 3. Al cambiar a Empresa A: permisos de contador 4. Al cambiar a Empresa B: permisos de vendedor 5. Sistema valida permisos según empresa activa ### FA-3: Eliminación de Acceso a Empresa 1. Administrador elimina usuario de empresa 2. Sistema valida que usuario no tenga documentos pendientes 3. Sistema elimina registro de auth.user_companies 4. Usuario pierde acceso a esa empresa 5. Si era última empresa, usuario queda sin acceso al sistema ### FA-4: Usuario Sin Empresas Asignadas 1. Usuario intenta iniciar sesión 2. Sistema detecta que no tiene empresas asignadas 3. Sistema retorna error 403: "Usuario sin empresas asignadas. Contacte al administrador" ## Reglas de Negocio - **RN-1:** Usuario puede tener acceso a múltiples empresas - **RN-2:** Usuario puede tener roles diferentes en cada empresa - **RN-3:** Usuario debe tener al menos una empresa asignada para operar - **RN-4:** Empresa activa determina datos visibles y permisos - **RN-5:** Cambio de empresa no requiere logout - **RN-6:** RLS filtra datos automáticamente por empresa activa - **RN-7:** Documentos creados tienen company_id de empresa activa ## Criterios de Aceptación - [ ] Administrador puede asignar usuarios a múltiples empresas - [ ] Administrador puede definir roles diferentes por empresa - [ ] Usuario ve lista de empresas a las que tiene acceso - [ ] Usuario puede cambiar empresa activa sin logout - [ ] Permisos se aplican según roles de empresa activa - [ ] Datos mostrados corresponden a empresa activa (RLS) - [ ] Documentos creados tienen company_id de empresa activa - [ ] Usuario sin empresas no puede operar en el sistema - [ ] Sistema valida acceso a empresa en cada request ## Entidades Involucradas - **Principales:** - auth.user_companies (user_id, company_id, is_default) - auth.user_company_roles (user_id, company_id, role_id) - **Relacionadas:** - auth.users (usuario) - core.companies (empresas) - auth.roles (roles) ## Referencias - [ALCANCE-POR-MODULO.md - MGN-002](../../01-definicion-modulos/ALCANCE-POR-MODULO.md#mgn-002-empresas-y-organizaciones) - [Auth Schema DDL](../database-design/schemas/auth-schema-ddl.sql) - [Core Schema DDL](../database-design/schemas/core-schema-ddl.sql) - [Gap Analysis MGN-002](../../01-definicion-modulos/gaps/GAP-ANALYSIS-MGN-002.md) ## Notas Técnicas - **Patrón Odoo:** res.company + res.users.company_ids (many2many) - **Context Switching:** Actualizar req.company_id en middleware - **RLS:** Filtro automático WHERE company_id = get_current_company_id() - **Función SQL:** ```sql CREATE OR REPLACE FUNCTION get_current_company_id() RETURNS INTEGER AS $$ BEGIN RETURN current_setting('app.current_company_id')::INTEGER; END; $$ LANGUAGE plpgsql; ``` - **Frontend:** Selector de empresas en navbar - **Backend:** Middleware que valida acceso a empresa ## Dependencias - **RF Dependientes:** - RF-MGN-001-003 (Gestión de Usuarios) - RF-MGN-002-001 (Gestión de Empresas) - RF-MGN-001-002 (Roles) - **Bloqueante para:** Todos los módulos transaccionales (requieren company_id)