# 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)
