Complete documentation for future sessions

- CLAUDE.md for AI agents to understand the codebase
- GITEA-GUIDE.md centralizes all Gitea operations (API, Registry, Auth)
- DEVELOPMENT-WORKFLOW.md explains complete dev process
- ROADMAP.md, NEXT-SESSION.md for planning
- QUICK-REFERENCE.md, TROUBLESHOOTING.md for daily use
- 40+ detailed docs in /docs folder
- Backend as submodule from Gitea

Everything documented for autonomous operation.

Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Hector Ros
2026-01-20 00:36:53 +01:00
commit db71705842
49 changed files with 19162 additions and 0 deletions

View File

@@ -0,0 +1,316 @@
# 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 |

View File

@@ -0,0 +1,430 @@
# Modelo de Datos (MySQL)
## Diagrama ER
```
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Projects │───────│ Tasks │───────│ Agents │
└─────────────┘ 1:N └─────────────┘ N:1 └─────────────┘
│ 1:N
┌────▼────────┐
│ Questions │
└─────────────┘
┌─────────────┐ ┌─────────────┐
│ TaskGroups │───────│ Deploys │
└─────────────┘ 1:N └─────────────┘
```
## Schema SQL
### Tabla: projects
```sql
CREATE TABLE projects (
id VARCHAR(36) PRIMARY KEY,
name VARCHAR(255) NOT NULL,
description TEXT,
-- Gitea integration
gitea_repo_id INT,
gitea_repo_url VARCHAR(512),
gitea_owner VARCHAR(100),
gitea_repo_name VARCHAR(100),
default_branch VARCHAR(100) DEFAULT 'main',
-- Kubernetes
k8s_namespace VARCHAR(63) NOT NULL UNIQUE,
-- Infrastructure config (JSON)
docker_image VARCHAR(512),
env_vars JSON,
replicas INT DEFAULT 1,
cpu_limit VARCHAR(20) DEFAULT '500m',
memory_limit VARCHAR(20) DEFAULT '512Mi',
-- MCP config (JSON)
mcp_tools JSON,
mcp_permissions JSON,
-- Status
status ENUM('active', 'paused', 'archived') DEFAULT 'active',
-- Timestamps
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_status (status),
INDEX idx_k8s_namespace (k8s_namespace)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
```
### Tabla: tasks
```sql
CREATE TABLE tasks (
id VARCHAR(36) PRIMARY KEY,
project_id VARCHAR(36) NOT NULL,
-- Task info
title VARCHAR(255) NOT NULL,
description TEXT,
priority ENUM('low', 'medium', 'high', 'urgent') DEFAULT 'medium',
-- State machine
state ENUM(
'backlog',
'in_progress',
'needs_input',
'ready_to_test',
'approved',
'staging',
'production',
'cancelled'
) DEFAULT 'backlog',
-- Assignment
assigned_agent_id VARCHAR(36),
assigned_at TIMESTAMP NULL,
-- Git info
branch_name VARCHAR(255),
pr_number INT,
pr_url VARCHAR(512),
-- Preview deployment
preview_namespace VARCHAR(63),
preview_url VARCHAR(512),
preview_deployed_at TIMESTAMP NULL,
-- Metadata
estimated_complexity ENUM('trivial', 'simple', 'medium', 'complex') DEFAULT 'medium',
actual_duration_minutes INT,
-- Timestamps
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
started_at TIMESTAMP NULL,
completed_at TIMESTAMP NULL,
deployed_staging_at TIMESTAMP NULL,
deployed_production_at TIMESTAMP NULL,
FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE,
FOREIGN KEY (assigned_agent_id) REFERENCES agents(id) ON DELETE SET NULL,
INDEX idx_project_state (project_id, state),
INDEX idx_state (state),
INDEX idx_assigned_agent (assigned_agent_id),
INDEX idx_created_at (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
```
### Tabla: task_questions
```sql
CREATE TABLE task_questions (
id VARCHAR(36) PRIMARY KEY,
task_id VARCHAR(36) NOT NULL,
-- Question
question TEXT NOT NULL,
context TEXT,
asked_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
-- Response
response TEXT,
responded_at TIMESTAMP NULL,
responded_by VARCHAR(36),
-- Status
status ENUM('pending', 'answered', 'skipped') DEFAULT 'pending',
FOREIGN KEY (task_id) REFERENCES tasks(id) ON DELETE CASCADE,
INDEX idx_task_status (task_id, status),
INDEX idx_status (status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
```
### Tabla: agents
```sql
CREATE TABLE agents (
id VARCHAR(36) PRIMARY KEY,
-- K8s info
pod_name VARCHAR(253) NOT NULL UNIQUE,
k8s_namespace VARCHAR(63) DEFAULT 'agents',
node_name VARCHAR(253),
-- Status
status ENUM('idle', 'busy', 'error', 'offline', 'initializing') DEFAULT 'initializing',
current_task_id VARCHAR(36),
-- Capabilities
capabilities JSON, -- ['javascript', 'python', 'react', ...]
max_concurrent_tasks INT DEFAULT 1,
-- Health
last_heartbeat TIMESTAMP NULL,
error_message TEXT,
restarts_count INT DEFAULT 0,
-- Metrics
tasks_completed INT DEFAULT 0,
total_runtime_minutes INT DEFAULT 0,
-- Timestamps
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (current_task_id) REFERENCES tasks(id) ON DELETE SET NULL,
INDEX idx_status (status),
INDEX idx_pod_name (pod_name),
INDEX idx_last_heartbeat (last_heartbeat)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
```
### Tabla: task_groups
```sql
CREATE TABLE task_groups (
id VARCHAR(36) PRIMARY KEY,
project_id VARCHAR(36) NOT NULL,
-- Grouping
task_ids JSON NOT NULL, -- ['task-id-1', 'task-id-2', ...]
-- Staging
staging_branch VARCHAR(255),
staging_pr_number INT,
staging_pr_url VARCHAR(512),
staging_deployed_at TIMESTAMP NULL,
-- Production
production_deployed_at TIMESTAMP NULL,
production_rollback_available BOOLEAN DEFAULT TRUE,
-- Status
status ENUM('pending', 'staging', 'production', 'rolled_back') DEFAULT 'pending',
-- Metadata
created_by VARCHAR(36),
notes TEXT,
-- Timestamps
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE,
INDEX idx_project_status (project_id, status),
INDEX idx_status (status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
```
### Tabla: deployments
```sql
CREATE TABLE deployments (
id VARCHAR(36) PRIMARY KEY,
project_id VARCHAR(36) NOT NULL,
task_group_id VARCHAR(36),
-- Deployment info
environment ENUM('preview', 'staging', 'production') NOT NULL,
deployment_type ENUM('manual', 'automatic', 'rollback') DEFAULT 'manual',
-- Git info
branch VARCHAR(255),
commit_hash VARCHAR(40),
-- K8s info
k8s_namespace VARCHAR(63),
k8s_deployment_name VARCHAR(253),
image_tag VARCHAR(255),
-- Status
status ENUM('pending', 'in_progress', 'completed', 'failed', 'rolled_back') DEFAULT 'pending',
-- Results
url VARCHAR(512),
error_message TEXT,
logs TEXT,
-- Timing
started_at TIMESTAMP NULL,
completed_at TIMESTAMP NULL,
duration_seconds INT,
-- Metadata
triggered_by VARCHAR(36),
-- Timestamps
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE,
FOREIGN KEY (task_group_id) REFERENCES task_groups(id) ON DELETE SET NULL,
INDEX idx_project_env (project_id, environment),
INDEX idx_status (status),
INDEX idx_created_at (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
```
### Tabla: agent_logs
```sql
CREATE TABLE agent_logs (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
agent_id VARCHAR(36) NOT NULL,
task_id VARCHAR(36),
-- Log entry
level ENUM('debug', 'info', 'warn', 'error') DEFAULT 'info',
message TEXT NOT NULL,
metadata JSON,
-- Timestamp
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (agent_id) REFERENCES agents(id) ON DELETE CASCADE,
FOREIGN KEY (task_id) REFERENCES tasks(id) ON DELETE SET NULL,
INDEX idx_agent_created (agent_id, created_at),
INDEX idx_task_created (task_id, created_at),
INDEX idx_level (level)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
```
## Índices y Optimizaciones
### Índices Compuestos Importantes
```sql
-- Búsqueda de tareas por proyecto y estado
CREATE INDEX idx_tasks_project_state ON tasks(project_id, state, created_at);
-- Búsqueda de agentes disponibles
CREATE INDEX idx_agents_available ON agents(status, last_heartbeat)
WHERE status = 'idle';
-- Logs recientes por agente
CREATE INDEX idx_agent_logs_recent ON agent_logs(agent_id, created_at DESC)
USING BTREE;
```
### Particionamiento (para logs)
```sql
-- Particionar agent_logs por mes
ALTER TABLE agent_logs PARTITION BY RANGE (YEAR(created_at) * 100 + MONTH(created_at)) (
PARTITION p202601 VALUES LESS THAN (202602),
PARTITION p202602 VALUES LESS THAN (202603),
PARTITION p202603 VALUES LESS THAN (202604),
-- ... auto-crear con script
PARTITION p_future VALUES LESS THAN MAXVALUE
);
```
## Queries Comunes
### Obtener siguiente tarea disponible
```sql
SELECT * FROM tasks
WHERE state = 'backlog'
AND project_id = ?
ORDER BY
priority DESC,
created_at ASC
LIMIT 1
FOR UPDATE SKIP LOCKED;
```
### Agentes disponibles
```sql
SELECT * FROM agents
WHERE status = 'idle'
AND last_heartbeat > DATE_SUB(NOW(), INTERVAL 60 SECOND)
ORDER BY tasks_completed ASC
LIMIT 1;
```
### Dashboard: Métricas de proyecto
```sql
SELECT
COUNT(*) as total_tasks,
SUM(CASE WHEN state = 'backlog' THEN 1 ELSE 0 END) as backlog,
SUM(CASE WHEN state = 'in_progress' THEN 1 ELSE 0 END) as in_progress,
SUM(CASE WHEN state = 'needs_input' THEN 1 ELSE 0 END) as needs_input,
SUM(CASE WHEN state = 'ready_to_test' THEN 1 ELSE 0 END) as ready_to_test,
SUM(CASE WHEN state = 'production' THEN 1 ELSE 0 END) as completed,
AVG(actual_duration_minutes) as avg_duration
FROM tasks
WHERE project_id = ?;
```
### Historial de deployments
```sql
SELECT
d.*,
tg.task_ids,
COUNT(t.id) as tasks_count
FROM deployments d
LEFT JOIN task_groups tg ON d.task_group_id = tg.id
LEFT JOIN tasks t ON JSON_CONTAINS(tg.task_ids, CONCAT('"', t.id, '"'))
WHERE d.project_id = ?
AND d.environment = 'production'
GROUP BY d.id
ORDER BY d.created_at DESC
LIMIT 20;
```
## Migraciones con Drizzle
```typescript
// drizzle/schema.ts
import { mysqlTable, varchar, text, timestamp, json, int, mysqlEnum } from 'drizzle-orm/mysql-core'
export const projects = mysqlTable('projects', {
id: varchar('id', { length: 36 }).primaryKey(),
name: varchar('name', { length: 255 }).notNull(),
description: text('description'),
giteaRepoId: int('gitea_repo_id'),
giteaRepoUrl: varchar('gitea_repo_url', { length: 512 }),
// ... resto campos
createdAt: timestamp('created_at').defaultNow(),
updatedAt: timestamp('updated_at').defaultNow().onUpdateNow(),
})
export const tasks = mysqlTable('tasks', {
id: varchar('id', { length: 36 }).primaryKey(),
projectId: varchar('project_id', { length: 36 }).notNull().references(() => projects.id),
title: varchar('title', { length: 255 }).notNull(),
state: mysqlEnum('state', [
'backlog', 'in_progress', 'needs_input',
'ready_to_test', 'approved', 'staging', 'production', 'cancelled'
]).default('backlog'),
// ... resto campos
})
```
## Backup Strategy
```bash
# Daily backup
mysqldump -u root -p aiworker \
--single-transaction \
--quick \
--lock-tables=false \
> backup-$(date +%Y%m%d).sql
# Restore
mysql -u root -p aiworker < backup-20260119.sql
```

View File

@@ -0,0 +1,140 @@
# Overview General - AiWorker
## Concepto
AiWorker es un sistema de orquestación de agentes IA que automatiza el ciclo completo de desarrollo de software mediante:
1. **Dashboard Web**: Interfaz central para gestionar proyectos y tareas
2. **Consolas Web Persistentes**: Terminales web conectadas a pods de Claude Code en K8s
3. **Kanban Board Inteligente**: Gestión visual de tareas con estados automáticos
4. **Agentes Autónomos**: Claude Code trabajando en tareas asignadas
5. **Deployments Automatizados**: Preview, staging y producción orquestados
## Arquitectura de Alto Nivel
```
┌─────────────────────────────────────────────────────────────────┐
│ Dashboard Web │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Kanban │ │ Consolas │ │ Project │ │
│ │ Board │ │ Web │ │ Manager │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└────────────────────────┬────────────────────────────────────────┘
│ HTTP/WebSocket
┌────────────────────────▼────────────────────────────────────────┐
│ Backend (Bun + Express) │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ API │ │ MCP │ │ Gitea │ │ K8s │ │
│ │ Server │ │ Server │ │ Client │ │ Client │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
└────────┬───────────────┬─────────────┬─────────────┬───────────┘
│ │ │ │
┌────▼────┐ ┌───▼────┐ ┌───▼────┐ ┌────▼─────┐
│ MySQL │ │ Redis │ │ Gitea │ │ K8s │
└─────────┘ └────────┘ └────────┘ └──────────┘
┌───────────────────────────────┘
┌──────────▼──────────────────────────────────────┐
│ Kubernetes Cluster │
│ ┌──────────────┐ ┌─────────────────────────┐ │
│ │ Agents │ │ Project Namespaces │ │
│ │ Namespace │ │ ├── dev │ │
│ │ │ │ ├── preview/<task-id> │ │
│ │ Claude Code │ │ ├── staging │ │
│ │ Pods │ │ └── production │ │
│ └──────────────┘ └─────────────────────────┘ │
└─────────────────────────────────────────────────┘
```
## Componentes Principales
### 1. Dashboard Web (Frontend)
- **Tecnología**: React 19.2 + TailwindCSS + Vite
- **Funciones**:
- Kanban board para gestión de tareas
- Consolas web interactivas (xterm.js)
- Gestión de proyectos
- Monitoring en tiempo real
### 2. Backend API
- **Tecnología**: Bun 1.3.6 + Express + TypeScript
- **Funciones**:
- API REST para frontend
- MCP Server para agentes
- Orquestación de tareas
- Integración con Gitea y K8s
### 3. Base de Datos
- **MySQL 8.0**: Almacenamiento persistente
- **Redis**: Colas, cache, pub/sub
### 4. Gitea
- **Servidor Git auto-alojado**
- **API compatible con GitHub**
- **Gestión de repos, branches, PRs**
### 5. Kubernetes Cluster
- **Orquestación de contenedores**
- **Namespaces por proyecto y entorno**
- **Auto-scaling de agentes**
### 6. Claude Code Agents
- **Pods persistentes en K8s**
- **Conectados vía MCP Server**
- **Workspace aislado por agente**
## Estados de Tareas
```
Backlog → En Progreso → Necesita Respuestas
Usuario responde
┌───────────────┘
Listo para Probar
(Preview deploy)
Aprobado
Staging (merge grupal)
Producción
```
## Flujo de Trabajo Típico
1. **Usuario crea proyecto** → Sistema crea repo en Gitea + namespace en K8s
2. **Usuario crea tareas** → Se añaden al backlog del kanban
3. **Agente disponible** → Toma siguiente tarea vía MCP
4. **Agente trabaja** → Clone, branch, código, commits
5. **¿Necesita info?** → Cambia estado a "Necesita Respuestas"
6. **Completa tarea** → Push + PR + deploy preview
7. **Usuario prueba** → En ambiente preview aislado
8. **Aprueba** → Marca para staging
9. **Merge grupal** → Agrega 2-3 tareas + merge a staging
10. **Deploy staging** → Tests automáticos
11. **Deploy producción** → Aprobación final
## Ventajas del Sistema
**Automatización completa**: Desde tarea hasta producción
**Aislamiento**: Cada tarea en su propio preview environment
**Trazabilidad**: Todo cambio vinculado a tarea y PR
**Escalabilidad**: Agentes auto-escalables en K8s
**Flexibilidad**: Agentes pueden pedir ayuda al usuario
**Control**: Usuario aprueba cada fase importante
## Seguridad
- Namespaces aislados en K8s
- RBAC por agente
- Secrets management
- Network policies
- Auditoría de acciones
## Próximos Pasos
Ver documentación específica de cada componente en las secciones correspondientes.

View File

@@ -0,0 +1,208 @@
# Stack Tecnológico
## Frontend
### Core
- **React 19.2**: Framework UI principal
- **Vite**: Build tool y dev server
- **TypeScript**: Type safety
- **TailwindCSS 4.x**: Styling utility-first
### Librerías UI
- **@dnd-kit/core**: Drag and drop para kanban
- **xterm.js**: Emulador de terminal web
- **lucide-react**: Iconos modernos
- **react-hot-toast**: Notificaciones
- **recharts**: Gráficas y métricas
### Estado y Data Fetching
- **@tanstack/react-query**: Server state management
- **zustand**: Client state management (ligero y simple)
- **socket.io-client**: WebSocket para real-time
### Routing
- **react-router-dom**: Navegación SPA
## Backend
### Core
- **Bun 1.3.6**: Runtime JavaScript ultra-rápido
- **Express**: Framework HTTP
- **TypeScript**: Type safety
### Database
- **MySQL 8.0**: Base de datos relacional principal
- **mysql2**: Driver MySQL para Node.js
- **Drizzle ORM**: ORM TypeScript-first moderno
- Type-safe
- Ligero
- Excelente DX con Bun
### Cache y Colas
- **Redis 7.x**: Cache y message broker
- **BullMQ**: Sistema de colas robusto
- **ioredis**: Cliente Redis
### Comunicación con Agentes
- **@modelcontextprotocol/sdk**: SDK oficial MCP
- **socket.io**: WebSocket server
### Integraciones
- **@kubernetes/client-node**: Cliente oficial K8s
- **octokit** (adaptado): Cliente API Gitea
- **axios**: HTTP client
### Desarrollo
- **tsx**: TypeScript execution
- **nodemon**: Hot reload
- **prettier**: Code formatting
- **eslint**: Linting
## Infrastructure
### Containerización
- **Docker 24.x**: Containerización
- **Docker Compose**: Orquestación local
### Orchestration
- **Kubernetes 1.28+**: Orquestación de contenedores
- **kubectl**: CLI
- **helm**: Package manager
- **kustomize**: Configuration management
### Git Server
- **Gitea latest**: Servidor Git auto-alojado
- Ligero (~100MB)
- API REST compatible GitHub
- Webhooks nativos
### CI/CD y GitOps
- **ArgoCD**: GitOps continuous delivery
- **GitHub Actions** (o Gitea Actions): CI pipelines
### Monitoring y Logging
- **Prometheus**: Métricas
- **Grafana**: Visualización
- **Loki**: Logs aggregation
- **Jaeger**: Distributed tracing (opcional)
### Networking
- **Nginx Ingress Controller**: Routing
- **cert-manager**: TLS certificates
## Agentes
### Claude Code
- **Claude Code CLI**: Herramienta oficial de Anthropic
- **Model**: Claude Sonnet 4.5
- **MCP Tools**: Comunicación con backend
## Development Tools
### Package Management
- **bun**: Package manager principal
- **npm**: Fallback para compatibilidad
### Testing
- **Vitest**: Unit testing (compatible con Bun)
- **@testing-library/react**: React testing
- **Playwright**: E2E testing
### Code Quality
- **TypeScript 5.x**: Type checking
- **ESLint**: Linting
- **Prettier**: Formatting
- **husky**: Git hooks
## Versiones Específicas
```json
{
"frontend": {
"react": "19.2.0",
"vite": "^6.0.0",
"typescript": "^5.6.0",
"tailwindcss": "^4.0.0"
},
"backend": {
"bun": "1.3.6",
"express": "^4.19.0",
"mysql2": "^3.11.0",
"drizzle-orm": "^0.36.0",
"bullmq": "^5.23.0",
"@modelcontextprotocol/sdk": "^1.0.0"
},
"infrastructure": {
"kubernetes": "1.28+",
"docker": "24.0+",
"gitea": "1.22+",
"redis": "7.2+",
"mysql": "8.0+"
}
}
```
## Justificación de Tecnologías
### ¿Por qué Bun?
- **Velocidad**: 3-4x más rápido que Node.js
- **TypeScript nativo**: Sin configuración adicional
- **APIs modernas**: Compatibilidad Web Standard
- **Tooling integrado**: Bundler, test runner, package manager
### ¿Por qué MySQL?
- **Madurez**: Batalla-probado en producción
- **Rendimiento**: Excelente para lecturas/escrituras
- **Transacciones**: ACID compliance
- **Ecosistema**: Herramientas maduras (backup, replicación)
### ¿Por qué Drizzle ORM?
- **Type-safety**: Inferencia total de tipos
- **Performance**: Query builder sin overhead
- **DX**: Migraciones automáticas
- **Bun compatible**: Primera clase
### ¿Por qué Gitea?
- **Ligero**: Binario único, bajo consumo
- **Auto-alojado**: Control total
- **API familiar**: Compatible con GitHub
- **Simple**: Instalación en minutos
### ¿Por qué React 19.2 sin Next.js?
- **Simplicidad**: SPA sin server-side complexity
- **Control total**: Sin abstracciones extra
- **Rendimiento**: Nuevo compilador React
- **Features**: Transitions, Server Actions cliente-side
## Alternativas Consideradas
| Necesidad | Elegido | Alternativas | Razón |
|-----------|---------|--------------|-------|
| Runtime | Bun | Node, Deno | Velocidad + DX |
| DB | MySQL | PostgreSQL, MongoDB | Familiaridad + Madurez |
| ORM | Drizzle | Prisma, TypeORM | Type-safety + Performance |
| Git | Gitea | GitLab, Gogs | Simplicidad + Features |
| Frontend | React | Vue, Svelte | Ecosistema + React 19 |
| Orchestration | K8s | Docker Swarm, Nomad | Industry standard |
## Dependencias Críticas
```bash
# Backend
bun add express mysql2 drizzle-orm ioredis bullmq
bun add @modelcontextprotocol/sdk socket.io
bun add @kubernetes/client-node axios
# Frontend
bun add react@19.2.0 react-dom@19.2.0
bun add @tanstack/react-query zustand
bun add socket.io-client xterm
bun add @dnd-kit/core react-router-dom
```
## Roadmap Tecnológico
**Fase 1 (MVP)**: Stack actual
**Fase 2**: Añadir Prometheus + Grafana
**Fase 3**: Implementar tracing con Jaeger
**Fase 4**: Multi-tenancy y sharding de DB