8. Resultados
STATUS: borrador (v1) Estimación: 5-6 páginas
8.1 Presentación del producto final
Quetzy ERP se entrega como un sistema en producción real, accesible bajo el dominio erp.quetzy.eu desde cualquier navegador moderno. El sistema integra en una única aplicación los flujos de comunicación, gestión operativa, control horario, gestión de contexto técnico y comunicaciones en tiempo real, sustituyendo en la práctica a un mínimo de cinco herramientas SaaS distintas (chat, llamadas, tickets, documentación, presencia).
A nivel cuantitativo, el producto entregado en esta v1 se concreta en:
| Métrica | Valor |
|---|---|
| Líneas de TypeScript / TSX | 46.755 |
| Archivos TS / TSX | 311 |
Componentes React (.tsx) | 73 |
Hooks personalizados (use-*.ts) | 34 |
| Endpoints API (Route Handlers) | 44 |
| Schemas Zod (capa de contrato) | 18 |
| Tablas en base de datos | 22 (20 en data_model.sql + 2 en consola Insforge) |
| Features funcionales | 10 (Auth, Chat, Calls, Tickets, Context, Clients, Projects, Hours, Notifications, Presence) |
| Tests unitarios y de integración | 827 (todos pasando) |
| Archivos de test | 70 |
| Coverage statements | 82,22 % |
| Coverage branches | 68,93 % |
| Coverage functions | 84,16 % |
| Coverage lines | 83,50 % |
| Tiempo de ejecución de la suite | 19,74 s |
El sistema corre sobre un VPS Hetzner CX33 (4 vCPU AMD EPYC, 7,6 GiB RAM, 75 GB SSD, Ubuntu Linux), con tres servicios Docker orquestados (erp, livekit, caddy) más la instancia de Insforge BaaS auto-alojada. El despliegue es automático tras merge a main mediante GitHub Actions, con health check y rollback manual disponibles.
8.2 Capturas de pantalla o diagramas finales
Las siguientes vistas en producción demuestran el funcionamiento real del sistema. Las capturas se incluyen en el directorio capturas/ y se referencian aquí como figuras numeradas.

Figura 8.1 — Login
Formulario con validación Zod, mensaje genérico anti-enumeración.
Nota para la versión final: las capturas reales se insertarán en el documento Word desde
capturas/durante el paso de generación del.docx. Se priorizan capturas de la instancia productiva (erp.quetzy.eu), no de localhost.
8.3 Funcionamiento principal
A nivel de uso cotidiano, el sistema se opera siguiendo cuatro flujos diferenciales que demuestran la integración entre módulos:
Flujo 1 — Conversación con captura embebida. El usuario está en una conversación de canal Equipo, captura una imagen con la herramienta del sistema operativo, y pega directamente con Ctrl+V dentro del input de mensaje. El sistema valida tipo y tamaño en cliente (RF-05), sube el archivo a Insforge Storage, persiste la fila en chat_attachment con su storage_key y publica el mensaje vía realtime (RF-07). El destinatario ve la imagen en línea sin recargar.
Flujo 2 — Llamada con compartición de pantalla desde el propio canal. El usuario pulsa el icono de llamada en la cabecera del canal. El sistema crea una sala LiveKit (RF-08), genera un token JWT firmado, conecta vía WebRTC (UDP directo al VPS), publica el track de audio local y suscribe los tracks remotos. Si el otro participante activa la compartición de pantalla, el track de vídeo se muestra en el panel correspondiente. El estado de la llamada se refleja en chat_call mediante el webhook de LiveKit.
Flujo 3 — Ticket que avanza por la máquina de estados. El usuario crea un ticket en estado received. Para avanzar a classified debe asignar complejidad (guard requireComplexity); para avanzar a pr_open debe rellenar pr_url; para llegar a closed debe existir al menos un context_item válido o un close_override_note. La máquina de estados pura (RF-09) rechaza cualquier transición que no satisfaga sus guards, evitando inconsistencias.
Flujo 4 — Contexto crudo extraído por IA y revisado por humano. El usuario pega notas de una reunión como raw_context. El sistema invoca la skill context_extractor con el proveedor configurado (Gemini), parsea la salida JSON estructurada y crea context_items en estado pending_approval (RF-12). El usuario revisa cada item en la swipeable card stack y aprueba o rechaza. Solo los aprobados quedan disponibles para futuros prompts asistidos por IA.
Estos cuatro flujos no son un subconjunto: son el núcleo diferencial del sistema frente a alternativas SaaS fragmentadas.
8.4 Comparación con objetivos iniciales
La siguiente tabla compara cada objetivo específico del Cap 2 con el estado real al cierre de la v1:
| OE | Objetivo | Estado | Evidencia |
|---|---|---|---|
| OE1 | Sistema de chat en tiempo real con texto, audio, adjuntos, reacciones, typing y embebido de proyectos | Cumplido | 16 tests de chat, 7 tablas (chat_*), bucket Storage, realtime vía WebSocket. |
| OE2 | Llamadas WebRTC con audio + screen share, control de estado vía webhook | Cumplido con deuda | Funciona; subsiste bug de audio asimétrico tras reconnect (R-09, deuda explícita). |
| OE3 | Tickets con máquina de estados explícita de 14 estados | Cumplido | ticket-state-machine.ts con transitionPolicies testeado en ticket-state-machine.test.ts. |
| OE4 | context_items con flujo de aprobación humana, raw vs validado, links N:M | Cumplido | 3 tablas (context_item, raw_context, entity_context_link), 12 hooks, 11 endpoints. |
| OE5 | Arquitectura limpia: contratos / interfaces / repositorios / capa de presentación | Cumplido | 18 schemas Zod + doble implementación de repositorios (mock + Insforge) + 7 contextos React. |
| OE6 | Despliegue producción con CI/CD automático, TLS gestionado, >=80 % coverage | Cumplido | Pipeline de 4 jobs en GitHub Actions, Caddy con Let’s Encrypt automático, 82,22 % statements coverage. |
| OE7 | Self-hosting completo, sin SaaS críticos | Cumplido con matiz | Auth, BD, realtime y WebRTC self-hosted. CI sigue dependiendo de GitHub Actions (deuda: migrar a Forgejo + Woodpecker CI). |
| OE8 | Validar metodología de ingeniería de contexto + tickets-como-planes-de-PRs en equipo | Cumplido como prueba de concepto | Manu se incorporó en la fase final, lanzó la PR #70 siguiendo el flujo establecido sin necesidad de onboarding extenso. La metodología se demostró extrapolable a un segundo desarrollador. |
Los ocho objetivos específicos se cumplen, dos de ellos (OE2 y OE7) con deudas explícitas documentadas en otros capítulos.
A nivel de objetivos no funcionales, el sistema satisface también los RNF-01 a RNF-10 con la siguiente excepción honesta: el RNF-02 (escalabilidad a 20 personas concurrentes) NO ha sido validado empíricamente con pruebas de carga. La cifra de “hasta 20 personas” es una estimación basada en el dimensionamiento del VPS y la naturaleza de las cargas observadas; queda como deuda pruebas formales con herramientas tipo k6 o Artillery.
A nivel de la pregunta de investigación que abre el TFG —cuál es la manera más óptima de gestionar productos digitales potenciando el desarrollo por IA sin desplazar al programador— la respuesta empírica que ofrece este trabajo se sostiene sobre tres pilares que el sistema demuestra funcionando:
- Estandarización Git extrema (Conventional Commits, ramas tipadas, squash merge, CI/CD obligatorio) hace que humanos y agentes IA puedan operar sobre el mismo flujo sin perder coherencia.
- Tickets transformados en planes de PRs convierten la planificación en un artefacto ejecutable, eliminando ambigüedad cuando interviene la IA.
context_itemsvalidados por humanos sustituyen la dependencia de bases vectoriales o GraphRAG para inyectar contexto en los modelos, con menos infraestructura y mayor control.
La validación final empírica de esta tesis llega con la incorporación de Manu al equipo en la fase final del proyecto, que pudo lanzar PRs siguiendo el flujo establecido sin requerir onboarding extenso. La metodología, por tanto, escala más allá de un desarrollador unipersonal dentro del rango de equipo pequeño que define el alcance.