# Flujo de Datos ## Arquitectura de Comunicación ``` ┌──────────┐ ┌──────────┐ ┌──────────┐ │ Frontend │ ◄─────► │ Backend │ ◄─────► │ MySQL │ └──────────┘ └──────────┘ └──────────┘ │ │ │ │ ├──────────────────────┤ │ │ Redis │ │ └──────────────────────┘ │ │ │ ┌─────┴─────┐ │ │ │ │ ┌────▼────┐ ┌───▼────┐ │ │ Gitea │ │ K8s │ │ └─────────┘ └───┬────┘ │ │ │ ┌────▼────────┐ └────────────────────┤ Claude Code │ WebSocket │ Agents │ └─────────────┘ ``` ## 1. Flujo Completo: Creación de Tarea ### 1.1 Usuario Crea Tarea ``` Frontend Backend MySQL Redis │ │ │ │ │ POST /api/tasks │ │ │ ├──────────────────────►│ │ │ │ │ INSERT task │ │ │ ├──────────────────►│ │ │ │ │ │ │ │ PUBLISH task.new │ │ │ ├───────────────────┼────────────────►│ │ │ │ │ │ { taskId, status } │ │ │ │◄──────────────────────┤ │ │ │ │ │ │ │ WS: task_created │ │ │ │◄──────────────────────┤ │ │ ``` **Detalle**: 1. Frontend envía POST a `/api/tasks` con JSON: ```json { "projectId": "uuid", "title": "Implementar login", "description": "Crear sistema de autenticación..." } ``` 2. Backend: - Valida datos - Inserta en MySQL tabla `tasks` - Publica evento en Redis: `task:new` - Añade job a cola BullMQ: `task-queue` - Responde con task creada 3. WebSocket notifica a todos los clientes conectados ### 1.2 Agente Toma Tarea ``` Agent (K8s) Backend (MCP) MySQL BullMQ │ │ │ │ │ MCP: get_next_task │ │ │ ├──────────────────────►│ │ │ │ │ SELECT task │ │ │ ├──────────────────►│ │ │ │ │ │ │ │ UPDATE status │ │ │ ├──────────────────►│ │ │ │ │ │ │ { task details } │ DEQUEUE job │ │ │◄──────────────────────┤◄─────────────────┼─────────────────┤ │ │ │ │ ``` **Detalle**: 1. Agente llama herramienta MCP `get_next_task` 2. Backend: - Query: `SELECT * FROM tasks WHERE state='backlog' ORDER BY created_at LIMIT 1` - Actualiza: `UPDATE tasks SET state='in_progress', assigned_agent_id=?` - Elimina job de BullMQ 3. Responde con detalles completos de la tarea ## 2. Flujo: Agente Pide Información ``` Agent Backend (MCP) MySQL Frontend (WS) │ │ │ │ │ ask_user_question │ │ │ ├─────────────────────►│ │ │ │ │ UPDATE task │ │ │ ├──────────────────►│ │ │ │ state=needs_input │ │ │ │ │ │ │ │ INSERT question │ │ │ ├──────────────────►│ │ │ │ │ │ │ { success: true } │ WS: needs_input │ │ │◄─────────────────────┤──────────────────┼───────────────────►│ │ │ │ │ │ │ │ [Usuario ve] │ │ │ │ [notificación] │ │ │ │ │ │ │ POST /api/tasks/ │ │ │ │ :id/respond │ │ │ │◄──────────────────┼────────────────────┤ │ │ │ │ │ MCP: check_response │ UPDATE response │ │ ├─────────────────────►├──────────────────►│ │ │ │ state=in_progress │ │ │ { response: "..." } │ │ │ │◄─────────────────────┤ │ │ ``` **Detalle**: 1. Agente detecta necesita info (ej: "¿Qué librería usar para auth?") 2. Llama `ask_user_question(taskId, question)` 3. Backend: - Actualiza `tasks.state = 'needs_input'` - Inserta en tabla `task_questions` - Emite WebSocket `task:needs_input` 4. Frontend muestra notificación y badge en kanban 5. Usuario responde vía UI 6. Backend guarda respuesta 7. Agente hace polling o recibe notificación vía MCP ## 3. Flujo: Completar Tarea y Deploy Preview ``` Agent Backend(MCP) Gitea API MySQL K8s API Frontend │ │ │ │ │ │ │ create_branch │ │ │ │ │ ├─────────────────►│ │ │ │ │ │ │ POST /repos/│ │ │ │ │ │ :owner/:repo│ │ │ │ │ │ /branches │ │ │ │ │ ├────────────►│ │ │ │ │ { branch } │ │ │ │ │ │◄─────────────────┤ │ │ │ │ │ │ │ │ │ │ │ [agent works] │ │ │ │ │ │ [commits code] │ │ │ │ │ │ │ │ │ │ │ │ create_pr │ │ │ │ │ ├─────────────────►│ │ │ │ │ │ │ POST /pulls │ │ │ │ │ ├────────────►│ │ │ │ │ { pr_url } │ │ │ │ │ │◄─────────────────┤ │ │ │ │ │ │ │ │ │ │ │ trigger_preview │ │ │ │ │ ├─────────────────►│ │ │ │ │ │ │ UPDATE task │ │ │ │ │ ├────────────┼────────────►│ │ │ │ │ │ │ │ │ │ │ CREATE │ │ CREATE │ │ │ │ namespace │ │ Deployment │ │ ├────────────┼────────────┼──────────►│ │ │ │ │ │ │ │ │ { preview_url } │ │ WS:ready_to_test │ │ │◄─────────────────┤─────────────┼───────────┼───────────┼───────────►│ ``` **Detalle**: 1. **create_branch**: Backend usa Gitea API para crear rama `task-{id}-feature` 2. **Agente trabaja**: Clone, cambios, commits, push 3. **create_pr**: Crea PR con descripción generada 4. **trigger_preview**: - Backend crea namespace K8s: `preview-task-{id}` - Aplica deployment con imagen del proyecto - Configura ingress con URL: `task-{id}.preview.aiworker.dev` - Actualiza `tasks.state = 'ready_to_test'` 5. Frontend muestra botón "Ver Preview" con URL ## 4. Flujo: Merge a Staging ``` User (Frontend) Backend Gitea API K8s API ArgoCD │ │ │ │ │ │ POST /merge │ │ │ │ │ taskIds[] │ │ │ │ ├──────────────►│ │ │ │ │ │ Validate │ │ │ │ │ all approved │ │ │ │ │ │ │ │ │ │ POST /pulls │ │ │ │ │ (merge PRs) │ │ │ │ ├──────────────►│ │ │ │ │ │ │ │ │ │ POST /branches│ │ │ │ │ staging │ │ │ │ ├──────────────►│ │ │ │ │ │ │ │ │ │ Trigger │ Apply │ │ │ │ ArgoCD sync │ manifests │ │ │ ├───────────────┼──────────────┼────────────►│ │ │ │ │ │ │ { status } │ │ │ [Deploys] │ │◄──────────────┤ │ │ │ ``` **Detalle**: 1. Usuario selecciona 2-3 tareas aprobadas 2. Click "Merge a Staging" 3. Backend: - Valida todas están en estado `approved` - Mergea cada PR a `staging` branch - Actualiza estado a `staging` - Triggerea ArgoCD sync 4. ArgoCD detecta cambios y deploya a namespace `staging` ## 5. Comunicación Real-Time (WebSocket) ### Eventos emitidos por Backend: ```typescript // Usuario se conecta socket.on('connect', () => { socket.emit('auth', { userId, token }) }) // Backend emite eventos socket.emit('task:created', { taskId, projectId }) socket.emit('task:status_changed', { taskId, oldState, newState }) socket.emit('task:needs_input', { taskId, question }) socket.emit('task:ready_to_test', { taskId, previewUrl }) socket.emit('agent:status', { agentId, status, currentTaskId }) socket.emit('deploy:started', { environment, taskIds }) socket.emit('deploy:completed', { environment, url }) ``` ### Cliente subscribe: ```typescript socket.on('task:status_changed', (data) => { // Actualiza UI del kanban queryClient.invalidateQueries(['tasks']) }) socket.on('task:needs_input', (data) => { // Muestra notificación toast.info('Un agente necesita tu ayuda') // Mueve card a columna "Needs Input" }) ``` ## 6. Caching Strategy ### Redis Cache Keys: ``` task:{id} → TTL 5min (task details) task:list:{projectId} → TTL 2min (lista de tareas) agent:{id}:status → TTL 30s (estado agente) project:{id} → TTL 10min (config proyecto) ``` ### Invalidación: ```typescript // Al actualizar tarea await redis.del(`task:${taskId}`) await redis.del(`task:list:${projectId}`) // Al cambiar estado agente await redis.setex(`agent:${agentId}:status`, 30, status) ``` ## 7. Queue System (BullMQ) ### Colas: ``` task-queue → Tareas pendientes de asignar deploy-queue → Deploys a ejecutar merge-queue → Merges programados cleanup-queue → Limpieza de preview envs antiguos ``` ### Workers: ```typescript // task-worker.ts taskQueue.process(async (job) => { const { taskId } = job.data // Notifica agentes disponibles vía MCP await notifyAgents({ taskId }) }) // deploy-worker.ts deployQueue.process(async (job) => { const { taskId, environment } = job.data await k8sClient.createDeployment(...) }) ``` ## Resumen de Protocolos | Comunicación | Protocolo | Uso | |--------------|-----------|-----| | Frontend ↔ Backend | HTTP REST + WebSocket | CRUD + Real-time | | Backend ↔ MySQL | TCP/MySQL Protocol | Persistencia | | Backend ↔ Redis | RESP | Cache + PubSub | | Backend ↔ Gitea | HTTP REST | Git operations | | Backend ↔ K8s | HTTP + Kubernetes API | Orquestación | | Backend ↔ Agents | MCP (stdio/HTTP) | Herramientas | | Agents ↔ Gitea | Git Protocol (SSH) | Clone/Push |