Saltar a contenido

0010. Flujo de acceso y panel de aplicaciones (pantallas de entrada)

Estado: Propuesto Fecha: 2026-09-08 Autor: Duval Alcivar Módulo(s) afectado(s): svc-identidad, frontend (React 18)

Contexto

La plataforma tiene varias aplicaciones (ERP, CRM) y cada empresa contrata solo algunas. Además, un mismo usuario puede trabajar en varias empresas. Necesitamos definir qué pantallas ve el usuario desde que abre la app hasta que entra a trabajar, y qué valida el backend en cada paso.

El mockup de referencia (sigfa-erp-crm.html) muestra tres pantallas: login → panel de aplicaciones → vista de módulo. Este ADR define el comportamiento de las dos primeras; la tercera (menú del módulo) está en el ADR 0012.

Conceptos

Término Qué es
Aplicación Un producto de la plataforma: ERP, CRM (tabla cat_aplicaciones, ADR 0006).
Módulo Una sección dentro de una aplicación (ej. Inventario, RRHH). Se muestran como tarjetas en el panel.
Panel La pantalla después del login: muestra las aplicaciones contratadas por la empresa con sus módulos.
pre_token Token temporal (5 min, ADR 0018) que se emite al validar la contraseña; solo sirve para elegir empresa, no da acceso a datos.

Decisión

Flujo completo

flowchart TD
    A["🖥️ LOGIN<br/>usuario + contraseña"]
    B{"¿credenciales válidas?"}
    C{"¿cuántas empresas?"}
    E["📋 MODAL<br/>elegir empresa"]
    D["📲 PANEL DE MÓDULOS<br/>carga directa"]
    F["🧭 MÓDULO<br/>menú lateral por permisos"]

    A --> B

    B -->|"✅ sí"| C
    B -.->|"❌ no"| A

    C -->|"más de 1"| E
    C -->|"1 sola"| D
    E --> D

    D --> F

    classDef login fill:#eaf1fa,stroke:#2b6cb0,color:#1e4e85,stroke-width:2px;
    classDef decision fill:#f5f3ff,stroke:#6d5bd0,color:#4b3a9e,stroke-width:2px;
    classDef panel fill:#e8f5f0,stroke:#1f7a5c,color:#155941,stroke-width:2px;
    classDef modal fill:#f7ecf2,stroke:#8a3b63,color:#63294a,stroke-width:2px;
    classDef modulo fill:#fff7e6,stroke:#b4622a,color:#8a4d1a,stroke-width:2px;

    class A login;
    class B,C decision;
    class D panel;
    class E modal;
    class F modulo;

Pantalla 1 — Login

El formulario pide solo usuario y contraseña. Al enviar:

  1. El backend valida las credenciales (Argon2id), que el usuario esté activo y consulta sus empresas (rel_usuario_empresa activas).
  2. Responde con la lista de empresas del usuario y un pre_token.

Por qué no pedir la empresa junto con la contraseña: porque eso obligaría a mostrar las empresas disponibles antes de saber quién es el usuario (cualquiera podría probar usernames y ver a qué empresas pertenecen). Las empresas solo se revelan después de validar la contraseña.

Paso intermedio — ¿modal o directo?

Con las credenciales ya validadas, el frontend decide según cuántas empresas tenga el usuario:

  • Una sola empresa → no se muestra nada: el frontend envía esa empresa al paso 2 automáticamente y carga directo el panel de módulos. El usuario ni siquiera nota el paso intermedio.
  • Más de una empresa → se abre un modal (ventana emergente sobre el login) que lista las empresas del usuario. Al elegir una, se envía pre_token + empresa_id al paso 2, se recibe el access_token y se carga el panel.

Pantalla 2 — Panel de aplicaciones

Una vez autenticado, el frontend carga el panel:

GET /api/v1/navegacion/panel

El backend responde con las aplicaciones contratadas por la empresa (rel_empresa_aplicacion) y, dentro de cada una, solo los módulos a los que el usuario tiene permiso (ver ADR 0007/0012). La respuesta alimenta la grilla de tarjetas del mockup, agrupadas por núcleo (Core / ERP / CRM):

{
  "empresa": { "id": 1, "nombre": "Sigfa Alimentos S.A." },
  "aplicaciones": [
    {
      "codigo": "erp",
      "nombre": "ERP Sigfa",
      "dominio": "sigfa.com.ec",
      "modulos": [
        { "codigo": "inventario", "nombre": "Inventario", "icono": "box" },
        { "codigo": "rrhh", "nombre": "RRHH / Nómina", "icono": "users" }
      ]
    },
    {
      "codigo": "crm",
      "nombre": "CRM SigfaPro",
      "dominio": "sigfapro.com.ec",
      "modulos": [
        { "codigo": "clientes", "nombre": "Clientes", "icono": "users" }
      ]
    }
  ]
}

Reglas del panel:

  • Si una aplicación no tiene ningún módulo visible para el usuario, la aplicación completa no se muestra (una empresa puede tener ERP contratado pero este usuario solo ve módulos del CRM).
  • El panel no muestra módulos desactivados (is_activo = false) ni ocultos (is_visible = false), aunque el usuario tenga permiso.
  • Los datos del panel se cachean en el frontend por la duración de la sesión; se recargan al iniciar sesión o al cambiar de empresa.

Cambio de empresa sin cerrar sesión

Un usuario con varias empresas puede cambiar de empresa desde el menú de usuario (sin volver al login): el frontend llama a POST /api/v1/auth/login/empresa con un refresh válido y la nueva empresa_id; el backend emite un nuevo par de tokens con el nuevo empresa_id y el panel se recarga.

Alternativas descartadas

  • Pedir la empresa junto con usuario y contraseña en un solo formulario — obliga a listar empresas antes de autenticar (fuga de información) o a que el usuario se sepa el ID de memoria.
  • Un subdominio por empresa (empresa1.sigfa.com) — complejo de operar con pocas empresas; el selector en el login cubre el mismo caso.
  • Cargar el panel completo en el token JWT — inflaría el token; el panel se consulta una vez por sesión y se cachea en el cliente.

Consecuencias

  • El login queda en dos pasos seguros: las empresas del usuario nunca se exponen sin contraseña válida.
  • La mayoría de usuarios (los de una sola empresa) no ven ningún paso extra: entran directo al panel tras el login.
  • El panel refleja exactamente lo que el usuario puede usar: ni más (no ve módulos sin permiso) ni menos (no pierde acceso a lo contratado).
  • El cambio de empresa es una operación rápida sin cerrar sesión, útil para usuarios que operan varias empresas del grupo.
  • La seguridad del pre_token (expiración corta y un solo uso) quedó resuelta en el ADR 0018: JWT firmado con scope: "pre-auth", consumo registrado en trx_pre_tokens y replay tratado como fuga.

Orden de lectura (cómo encaja con los demás ADRs)

Este ADR narra el flujo con pantallas de la entrada del usuario. La parte técnica de la firma está en el 0011, los tipos/permisos en el 0007 y lo que se muestra dentro (menú / sidebar) en el 0012:

# ADR Qué aporta
0001 · 0002 Concepto y stack Qué es el servicio y con qué herramientas
0003 · 0005 Catálogos y modelos Catálogos, empresas y usuarios
0006 · 0007 Navegación y permisos Aplicaciones/módulos/menú y tipos/permisos
0008 · 0009 Gestión Alta de empresa; gestión de usuarios y permisos
0010 (este) Flujo de acceso y panel El flujo: login → modal de empresa → panel → módulo
0011 Login: firma JWT y claves Cómo se firma el token que produce este flujo
0012 Menú y permisos Qué se muestra al entrar (panel y sidebar)
flowchart LR
    A["0001 · 0002<br/>concepto y stack"] --> B["0003 · 0005<br/>catálogos y modelos"]
    B --> C["0006 · 0007<br/>navegación y permisos"]
    C --> D["0008 · 0009<br/>gestión"]
    D --> E["0010<br/>flujo y pantallas"]
    E --> F["0011<br/>firma y claves"]
    E --> G["0012<br/>menú y permisos"]

El orden lógico de lectura completo (con los pendientes) está en el README.md del índice.