Documento Visión general Vista general Componentes Capas del backend Flujos principales Visión general Plantilla de ADR ADR-0001: Monolito modular con capas limpias en el backend ADR-0002: CQRS ligero: escrituras por dominio, lecturas optimizadas ADR-0003: Frontend modular por funcionalidad con capas ADR-0004: TypeScript en el frontend ADR-0005: Quasar como librería de interfaz ADR-0006: Contrato de la API: REST versionada, respuestas y errores ADR-0007: MySQL 8.4 LTS como base de datos ADR-0008: Estado y prioridad como tablas catálogo ADR-0009: Sin relaciones polimórficas: toda referencia es una FK ADR-0010: ULID público y BIGINT interno ADR-0011: Borrado lógico, usuarios desactivados y FK con RESTRICT ADR-0012: Bloqueo optimista en incidentes ADR-0013: Búsqueda por texto con índice FULLTEXT ADR-0014: Estrategia de crecimiento por etapas, sin particionamiento ADR-0015: Autenticación con Laravel Sanctum y token Bearer ADR-0016: Argon2id y política de contraseñas ADR-0017: MFA con TOTP para todos los usuarios ADR-0018: Recuperación de contraseña por correo y TOTP ADR-0019: Cifrado en tránsito y en reposo ADR-0020: El backend como única autoridad ADR-0021: Roles construidos sobre permisos granulares ADR-0022: Logs del sistema: solo eventos relevantes, agrupados por huella ADR-0023: Acciones de sistema dentro del alcance de la aplicación ADR-0024: Tiempo real con Reverb y mensajes sin datos ADR-0025: Contenedores: gateway de origen único y una sola imagen de Laravel ADR-0026: Despliegue en VPS con el mismo docker compose ADR-0027: Diseño por tokens, mobile first y estilos por bloque de vista ADR-0028: Identidad visual de Trazo ADR-0029: Gráficos con componentes SVG propios ADR-0030: Dashboard personalizable guardado en el servidor ADR-0031: Estrategia de pruebas ADR-0032: Análisis estático, estilo y seguridad automatizada ADR-0033: Flujo de Git con cuatro ramas ADR-0034: CI/CD con GitHub Actions y promoción de la misma imagen ADR-0035: Documentación en Markdown, con ADR y trazabilidad al código ADR-0036: Exportación en CSV ADR-0037: Idempotency-Key en la creación de incidentes ADR-0038: Versiones del stack ADR-0039: Quasar integrado como plugin de Vite ADR-0040: Axios como base del cliente HTTP ADR-0041: El CI prueba el backend dentro del stack de Docker ADR-0042: Duración de la sesión y bloqueo progresivo por huella del correo ADR-0043: Reglas de acceso a incidentes en una sola clase de dominio ADR-0044: Listado de incidentes filtrado en SQL con la misma regla de visibilidad ADR-0045: Listado en el front con los filtros en la URL y una presentación por vista ADR-0046: Pruebas E2E en las cuatro vistas, con axe bloqueante y sesión por la API ADR-0047: Métricas del dashboard con la visibilidad del listado y caché invalidada por cambios ADR-0048: Diseño del dashboard guardado widget por widget, con los ocultos en su lugar ADR-0049: La sesión solo se cierra cuando la API la rechaza ADR-0050: Editor del dashboard con grid-layout-plus, sin sus estilos inyectados y con alternativa de teclado ADR-0051: MFA en la práctica: token de un ingreso a medias, sin atajo local y avisos por correo ADR-0052: Recuperación y cambio de contraseña: pase de un solo uso, HMAC, Have I Been Pwned y segundo factor ADR-0053: Administración de usuarios: jerarquía por nivel, permisos por persona y reautenticación ADR-0054: La matriz de permisos se siembra solo para roles y permisos nuevos ADR-0055: Edición de roles: rol de la cima bloqueado, nivel único, roles de sistema y sin correo masivo ADR-0056: Auditoría global: dos registros con permisos separados, alcance por jerarquía y paginación por cursor ADR-0057: Tiempo real en la práctica: canales por alcance, avisos sin datos y Reverb detrás del gateway ADR-0058: Exportación en la práctica: CSV para Excel en español, tope de filas y registro en la auditoría ADR-0059: Sistema en la práctica: salud medida desde la app, eventos agrupados y acciones con reautenticación ADR-0060: Pasada de calidad: CSP estricta, CORS cerrado, contrato OpenAPI, ZAP y cobertura exigida ADR-0061: Entrega verificada desde cero ADR-0062: Correos cifrados en la cola ADR-0063: Pantalla que no se descarga ADR-0064: Respaldo diario de MySQL ADR-0065: Documentación de funciones ADR-0066: Llave de la app sin depender del entrypoint ADR-0067: Pantallas precompiladas en desarrollo ADR-0068: El modo final es el que arranca por defecto ADR-0069: Al cambiar de rol, la persona queda con los permisos exactos del rol nuevo ADR-0070: Rechazar contraseñas predecibles aunque sean largas ADR-0071: Nota al cambiar de estado y reapertura con aprobación ADR-0072: Asignarse el incidente al crearlo ADR-0073: Largo del título de un incidente ADR-0074: Código del incidente por año ADR-0075: Menús que se abren donde caben ADR-0076: Conversación del incidente ADR-0077: Centro de notificaciones ADR-0078: Mis incidentes (Kanban, Lista, Calendario y Mi día) ADR-0079: Menú en un dock abajo y centrado, sin encabezado ADR-0080: Listado de incidentes como lista agrupada con el avance del plazo ADR-0081: Dashboard centrado en el riesgo ADR-0082: Formulario del incidente que guía mientras se escribe ADR-0083: Detalle del incidente con su camino, el siguiente paso y una sola actividad ADR-0084: Detalle con historial reciente, ficha a la par y un panel de chat y actividad ADR-0085: Avisos de coordinación para quienes reparten el trabajo ADR-0086: Nombres y apellidos por separado, con el nombre completo calculado por la base ADR-0087: Cuentas por rol creadas desde el entorno del servidor ADR-0088: Despliegue detrás del proxy de TLS que ya existe en el servidor ADR-0089: Incidentes de muestra en el sitio de evaluación ADR-0090: Una validación por ruta Visión general Mejoras aplicadas Mejoras propuestas
Estado: Aceptada
Fecha: 2026-10-31
Contexto
El sistema debe operar con grandes volúmenes sin degradarse. Las pantallas de mayor carga (listado con filtros y dashboard) solo leen datos, mientras que las escrituras deben respetar reglas estrictas, como las transiciones de estado.
Alternativas evaluadas
Que todo pase por el mismo camino de dominio y repositorios.
CQRS completo, con modelos de lectura separados y sincronización por eventos.
CQRS ligero: la misma base de datos, pero caminos distintos para leer y para escribir.
Decisión
CQRS ligero:
Escrituras: pasan por casos de uso que aplican las reglas del dominio.
Lecturas pesadas: usan query services dedicados, con consultas optimizadas, eager loading e índices pensados para ellas.
Alternativas descartadas
Un solo camino: obliga a que las lecturas atraviesen capas que no aportan nada al consultar, y dificulta optimizar.
CQRS completo: suma una segunda base o proyección, consistencia eventual y más infraestructura, sin una necesidad real en este alcance.
Consecuencias
El listado y el dashboard se optimizan sin tocar las reglas de negocio.
Si el volumen crece, el lado de lectura puede apuntar a una réplica solo con configuración.