- Módulo HITL (/cases): 6 patrones de formularios dinámicos para 53 tipos de caso con validación Zod - Módulo Monitor (/monitor): streaming token-a-token en tiempo real, auto-scroll y notas internas vía WebSocket - Arquitectura híbrida: REST (canal autoritativo) + WebSocket (difusión/streaming) - MSW para desarrollo sin backend, hooks de notificaciones/sonido/título preservados - Backend legacy movido a legacy/, archivos residuales eliminados de raíz
8.8 KiB
Claro Cases — Dashboard HITL
Dashboard Human-in-the-Loop (HITL) para que asesores humanos gestionen peticiones enviadas por un agente virtual durante conversaciones con clientes, y monitoreen la operación en tiempo real.
🏗️ Arquitectura
┌──────────────────────────────────────────────────┐
│ Frontend React (este repo) │
│ │
│ /cases ──▶ Gestión HITL (formularios dinámicos)│
│ /monitor ──▶ Monitoreo en tiempo real │
│ │
│ REST (POST) ──▶ Backend Python (canal escritura) │
│ WebSocket ◀── Backend Python (difusión/stream) │
└──────────────────────────────────────────────────┘
- REST es el canal autoritativo de escritura (resolución de casos)
- WebSocket es para difusión de eventos y streaming en tiempo real
- MSW (Mock Service Worker) simula el backend en modo desarrollo
Stack
| Componente | Tecnología |
|---|---|
| Framework | React 19 + TypeScript |
| Build | Vite 6 |
| Estado global | Zustand |
| Ruteo | React Router (/cases, /monitor) |
| Estilos | Tailwind CSS v4 (CSS-first con @theme) |
| Validación | Zod |
| Iconos | Lucide React |
| Mocks | MSW (Mock Service Worker) |
📂 Estructura del Proyecto
claro-cases/
├── index.html # Vite entry point
├── package.json # Dependencias y scripts
├── vite.config.ts # Configuración Vite + Tailwind + alias @/
├── tsconfig.json # TypeScript config
├── .env # Variables de entorno (VITE_*)
├── SPECIFICATION.md # Bitácora de desarrollo
├── BACKEND_HANDOFF.md # Contratos para equipo Python
├── Consulta de aplicativos... # CSV con 53 tipos de caso
│
├── src/
│ ├── main.tsx # Entry point React + MSW condicional
│ ├── App.tsx # Router principal
│ ├── index.css # Tailwind v4 @theme + @custom-variant dark
│ │
│ ├── types/
│ │ ├── index.ts # Interfaces: CaseRequest, Conversation, Message, etc.
│ │ └── wsProtocol.ts # Schemas Zod de eventos WebSocket
│ │
│ ├── data/
│ │ └── caseTypeDefinitions.ts # 53 tipos de caso con uiPattern y formFields
│ │
│ ├── services/
│ │ ├── api.ts # Cliente REST (fetch nativo)
│ │ └── wsClient.ts # Cliente WebSocket con reconexión
│ │
│ ├── store/
│ │ └── useAppStore.ts # Zustand store: cases, conversations, ui
│ │
│ ├── hooks/
│ │ ├── useNotification.ts # Notificaciones escritorio HTML5
│ │ ├── useSound.ts # Alerta sonora Web Audio API
│ │ ├── useTitleFlash.ts # Parpadeo de título de pestaña
│ │ └── index.ts # Barrel export
│ │
│ ├── components/
│ │ ├── layout/
│ │ │ ├── AppShell.tsx # Shell global (WS init, tema oscuro)
│ │ │ ├── Header.tsx # Logo, badge, indicador WS, toggle tema
│ │ │ └── Sidebar.tsx # Nav: Casos / Monitor
│ │ │
│ │ ├── cases/
│ │ │ ├── CaseCard.tsx # Tarjeta de caso (sidebar)
│ │ │ ├── CaseDetail.tsx # Panel de detalle
│ │ │ ├── FormRenderer.tsx # Formulario dinámico (6 patrones UI)
│ │ │ ├── TypeBadge.tsx # Badge de tipo de solicitud
│ │ │ └── ApplicativeFilter.tsx # Filtro por aplicativo
│ │ │
│ │ ├── monitor/
│ │ │ ├── ConversationCard.tsx # Tarjeta de conversación
│ │ │ ├── ChatFeed.tsx # Feed de mensajes con auto-scroll
│ │ │ ├── MessageBubble.tsx # Burbuja por rol (user/agent/system/internal)
│ │ │ ├── InternalNoteBanner.tsx # Inyección de notas internas
│ │ │ └── InternalNotesGroup.tsx # Acordeón de notas agrupadas
│ │ │
│ │ └── shared/
│ │ ├── StatusBadge.tsx # Badge de estado (PENDING/IN_PROGRESS/RESOLVED/FAILED)
│ │ ├── SearchBar.tsx # Input con debounce 300ms
│ │ ├── TabsBar.tsx # Pestañas: Todos/Pendientes/Finalizados
│ │ ├── EmptyState.tsx # Estado vacío centrado
│ │ ├── Modal.tsx # Overlay modal con backdrop blur
│ │ └── Timer.tsx # Cronómetro independiente (localStorage)
│ │
│ ├── pages/
│ │ ├── CasesPage.tsx # Vista /cases: sidebar + detalle
│ │ └── MonitorPage.tsx # Vista /monitor: conversaciones + chat
│ │
│ └── mocks/
│ ├── browser.ts # MSW setup
│ └── handlers.ts # 10 casos mock + 3 conversaciones
│
├── public/
│ └── mockServiceWorker.js # MSW service worker
│
└── legacy/ # Backend legacy Node.js + SQLite
├── server.js
├── db.js
├── schema.sql
├── package.json
└── public/ # Frontend vanilla original
🚀 Ejecución
Prerrequisitos
- Node.js 20+
Instalación
npm install
Desarrollo (con MSW — sin backend real)
npm run dev
http://localhost:5173/cases— Gestión de casos HITLhttp://localhost:5173/monitor— Monitoreo de conversaciones
Con VITE_ENABLE_MSW=true en .env, el MSW simula el backend automáticamente. Para usar un backend real, cambia a VITE_ENABLE_MSW=false.
Build de producción
npm run build # Genera dist/
npm run preview # Previsualiza el build
🎨 Sistema de Diseño
El tema está definido en src/index.css mediante la directiva @theme de Tailwind v4:
| Token | Valor |
|---|---|
--color-accent-orange |
#ff4e00 |
--color-accent-yellow |
#ffa600 |
--color-accent-red |
#f80018 |
--color-accent-green |
#10b981 |
--color-bg-base |
#f0f2f5 |
--color-bg-surface |
#ffffff |
--color-bg-elevated |
#f8fafc |
| Tipografía | Inter (Google Fonts) |
Modo oscuro: toggle vía @custom-variant dark + clase .dark en <html>.
📡 Contratos de Integración
El backend Python debe implementar los contratos documentados en BACKEND_HANDOFF.md. Resumen rápido:
REST (canal autoritativo)
| Método | Ruta | Descripción |
|---|---|---|
GET |
/api/v1/cases?status=&applicative=&search=&offset=&limit= |
Listar casos (filtrable, paginado) |
GET |
/api/v1/cases/:id |
Obtener caso |
POST |
/api/v1/cases/:id/resolve |
Resolver caso (único canal de escritura) |
GET |
/api/v1/conversations/active |
Conversaciones activas |
WebSocket (/ws/dashboard)
- Server → Client:
init_state,conversation_started,agent_stream_started/chunk/completed,hitl_request,hitl_resolved - Client → Server:
internal_note(notas internas del asesor) - Envelope:
{ type, eventId, occurredAt, payload }
🤖 Modo Mock (MSW)
El proyecto incluye 10 casos de ejemplo y 3 conversaciones simuladas para desarrollo sin backend:
# .env
VITE_ENABLE_MSW=true
Los mocks cubren los 6 patrones de UI (SIMPLE_CONFIRMATION, CONFIRMATION_WITH_VALUE, MULTI_FIELD_FORM, DATE_SIMPLE, FREE_TEXT, READ_ONLY) y múltiples aplicativos (AC+, ASCARD, DiMe, Formatos SGCS, Mi asistencia 360, RR).
🔐 Seguridad
advisorIdNUNCA es enviado por el frontend. El backend deriva la identidad del asesor desde el token de sesión (REST) o conexión WebSocket autenticada.- La resolución de casos es exclusivamente REST — no hay ruta de escritura por WebSocket que pueda ser explotada.
📚 Documentación Adicional
| Archivo | Contenido |
|---|---|
SPECIFICATION.md |
Bitácora completa: fases de diseño, auditoría, implementación y QA |
BACKEND_HANDOFF.md |
Contratos REST/WS detallados para el equipo Python |
Consulta de aplicativos - Claro - Facturación.csv |
53 tipos de caso con pasos, objetivos y formatos de respuesta |
legacy/README.md |
Documentación del backend legacy (Node.js + SQLite) |