Document session 2026-01-19 and prepare next session
- Add complete session documentation in past-sessions/ - Update NEXT-SESSION.md with Frontend + Agents roadmap - Add K8s manifests for backend deployment - Update README with past-sessions reference Session achievements: - Implemented complete REST API (projects, tasks, agents) - Implemented MCP Server with 4 core tools - Integrated Gitea API client - Successfully deployed backend to K8s at api.fuq.tv - Fixed MariaDB permissions and secrets - CI/CD pipeline working (build #7 successful) Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
867
NEXT-SESSION.md
867
NEXT-SESSION.md
@@ -1,429 +1,658 @@
|
|||||||
# 📋 Próxima Sesión - Checklist Ejecutable
|
# 📋 Próxima Sesión - Frontend Dashboard & Primer Agente
|
||||||
|
|
||||||
**Objetivo**: Completar Backend API y MCP Server básico
|
**Objetivo**: Implementar Frontend Dashboard y desplegar primer agente Claude Code funcional
|
||||||
**Tiempo estimado**: 2-3 horas
|
**Tiempo estimado**: 2-3 horas
|
||||||
|
**Sesión anterior**: `past-sessions/2026-01-19-backend-api-implementation.md`
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## ✅ PRE-REQUISITOS (Verificar antes de empezar)
|
## ✅ PRE-REQUISITOS (Verificar antes de empezar)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 1. Cluster funcionando
|
# 1. Backend funcionando
|
||||||
|
curl -s https://api.fuq.tv/api/health | grep "ok"
|
||||||
|
# Debe retornar: "status":"ok"
|
||||||
|
|
||||||
|
# 2. Base de datos accesible
|
||||||
export KUBECONFIG=~/.kube/aiworker-config
|
export KUBECONFIG=~/.kube/aiworker-config
|
||||||
|
kubectl exec -n control-plane mariadb-0 -- mariadb -uaiworker -pAiWorker2026_UserPass! aiworker -e "SELECT COUNT(*) FROM projects;"
|
||||||
|
# Debe mostrar conteo de proyectos
|
||||||
|
|
||||||
|
# 3. Cluster operativo
|
||||||
kubectl get nodes
|
kubectl get nodes
|
||||||
# Debe mostrar 6 nodos Ready
|
# 6 nodos Ready
|
||||||
|
|
||||||
# 2. Servicios corriendo
|
# 4. Registry accesible
|
||||||
kubectl get pods -n control-plane
|
curl -s -H "Authorization: token 159a5de2a16d15f33e388b55b1276e431dbca3f3" \
|
||||||
# mariadb-0: Running
|
"https://git.fuq.tv/api/v1/packages/admin?type=container" | grep aiworker-backend
|
||||||
# redis-xxx: Running
|
# Debe mostrar paquete
|
||||||
|
|
||||||
kubectl get pods -n gitea
|
|
||||||
# gitea-0: Running
|
|
||||||
|
|
||||||
# 3. Backend local
|
|
||||||
cd backend
|
|
||||||
bun --version
|
|
||||||
# 1.3.6
|
|
||||||
|
|
||||||
# 4. Gitea accesible
|
|
||||||
curl -I https://git.fuq.tv
|
|
||||||
# HTTP/2 200
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Si algo falla, consulta**: `K8S-CLUSTER.md` y `TROUBLESHOOTING.md`
|
**Si algo falla**: Revisar `TROUBLESHOOTING.md` o última sesión en `past-sessions/`
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🎯 PASO 1: Verificar CI/CD (15 min)
|
## 🎯 PASO 1: Crear Frontend Base con Bun (45 min)
|
||||||
|
|
||||||
|
### 1.1 Crear estructura de frontend
|
||||||
|
|
||||||
### 1.1 Revisar último build
|
|
||||||
```bash
|
```bash
|
||||||
# Ver en Gitea Actions
|
cd /Users/hectorros/projects/teamSquadAiWorker
|
||||||
open https://git.fuq.tv/admin/aiworker-backend/actions
|
mkdir -p frontend/{src,public}
|
||||||
|
cd frontend
|
||||||
|
|
||||||
|
# Inicializar proyecto Bun
|
||||||
|
bun init -y
|
||||||
```
|
```
|
||||||
|
|
||||||
**Opciones**:
|
### 1.2 Instalar dependencias
|
||||||
- ✅ **Si build exitoso**: Continuar a paso 2
|
|
||||||
- ❌ **Si build fallido**: Ver logs, corregir, push de nuevo
|
|
||||||
|
|
||||||
### 1.2 Verificar imagen en registry
|
|
||||||
```bash
|
```bash
|
||||||
# Vía UI
|
# React + TypeScript
|
||||||
open https://git.fuq.tv/admin/-/packages
|
bun add react react-dom
|
||||||
|
bun add -d @types/react @types/react-dom
|
||||||
|
|
||||||
# Vía API
|
# Routing
|
||||||
curl https://git.fuq.tv/api/v1/packages/admin/container?type=container
|
bun add react-router-dom
|
||||||
|
|
||||||
|
# UI Components (elegir uno)
|
||||||
|
# Opción A: Shadcn/UI + Tailwind
|
||||||
|
bun add -d tailwindcss postcss autoprefixer
|
||||||
|
bunx tailwindcss init -p
|
||||||
|
|
||||||
|
# Opción B: MUI
|
||||||
|
bun add @mui/material @emotion/react @emotion/styled
|
||||||
|
|
||||||
|
# API Client
|
||||||
|
bun add axios
|
||||||
|
|
||||||
|
# Auth
|
||||||
|
bun add lucia
|
||||||
```
|
```
|
||||||
|
|
||||||
**Debe existir**: `aiworker-backend` con tag `latest`
|
### 1.3 Crear componentes básicos
|
||||||
|
|
||||||
### 1.3 Si no hay imagen, build manual
|
**Estructura necesaria**:
|
||||||
```bash
|
```
|
||||||
# Desde un nodo del cluster (si Docker local no funciona)
|
frontend/src/
|
||||||
ssh root@108.165.47.225 # worker-01
|
├── index.html # HTML entry point
|
||||||
|
├── main.tsx # React root
|
||||||
cd /tmp
|
├── App.tsx # Main app component
|
||||||
git clone https://git.fuq.tv/admin/aiworker-backend.git
|
├── components/
|
||||||
cd aiworker-backend
|
│ ├── Layout.tsx
|
||||||
|
│ ├── ProjectList.tsx
|
||||||
docker build -t git.fuq.tv/admin/aiworker-backend:latest .
|
│ ├── TaskList.tsx
|
||||||
docker login git.fuq.tv -u admin -p 7401126cfb56ab2aebba17755bdc968c20768c27
|
│ └── AgentStatus.tsx
|
||||||
docker push git.fuq.tv/admin/aiworker-backend:latest
|
├── api/
|
||||||
|
│ └── client.ts # Axios client para backend
|
||||||
|
└── types/
|
||||||
|
└── index.ts # TypeScript types
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
### 1.4 Configurar Bun.serve() para frontend
|
||||||
|
|
||||||
## 🎯 PASO 2: Implementar API Routes (45 min)
|
**Crear** `frontend/server.ts`:
|
||||||
|
|
||||||
### 2.1 Crear estructura de routes
|
|
||||||
```bash
|
|
||||||
cd backend/src/api
|
|
||||||
mkdir routes
|
|
||||||
|
|
||||||
# Archivos a crear:
|
|
||||||
# - routes/projects.ts
|
|
||||||
# - routes/tasks.ts
|
|
||||||
# - routes/agents.ts
|
|
||||||
# - routes/index.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2.2 Implementar Projects API
|
|
||||||
|
|
||||||
**Archivo**: `src/api/routes/projects.ts`
|
|
||||||
|
|
||||||
**Endpoints necesarios**:
|
|
||||||
```typescript
|
```typescript
|
||||||
GET /api/projects // List all
|
import index from './src/index.html'
|
||||||
GET /api/projects/:id // Get one
|
|
||||||
POST /api/projects // Create
|
|
||||||
PATCH /api/projects/:id // Update
|
|
||||||
DELETE /api/projects/:id // Delete
|
|
||||||
```
|
|
||||||
|
|
||||||
**Referencia**: `docs/02-backend/api-endpoints.md` (líneas 15-80)
|
Bun.serve({
|
||||||
|
port: 3001,
|
||||||
**Conectar con Bun.serve()**:
|
routes: {
|
||||||
```typescript
|
'/': index,
|
||||||
// En src/index.ts
|
'/api/*': {
|
||||||
import { handleProjectRoutes } from './api/routes/projects'
|
GET: async (req) => {
|
||||||
|
// Proxy to backend
|
||||||
if (url.pathname.startsWith('/api/projects')) {
|
const path = new URL(req.url).pathname.replace(/^\/api/, '')
|
||||||
return handleProjectRoutes(req, url)
|
return fetch(`https://api.fuq.tv/api${path}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
development: {
|
||||||
|
hmr: true,
|
||||||
|
console: true
|
||||||
}
|
}
|
||||||
```
|
|
||||||
|
|
||||||
### 2.3 Implementar Tasks API
|
|
||||||
|
|
||||||
**Archivo**: `src/api/routes/tasks.ts`
|
|
||||||
|
|
||||||
**Endpoints principales**:
|
|
||||||
```typescript
|
|
||||||
GET /api/tasks // List with filters
|
|
||||||
GET /api/tasks/:id // Get details
|
|
||||||
POST /api/tasks // Create
|
|
||||||
PATCH /api/tasks/:id // Update
|
|
||||||
POST /api/tasks/:id/respond // Respond to question
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2.4 Probar APIs localmente
|
|
||||||
```bash
|
|
||||||
# Terminal 1: Port-forward MariaDB
|
|
||||||
kubectl port-forward -n control-plane svc/mariadb 3306:3306 &
|
|
||||||
|
|
||||||
# Terminal 2: Port-forward Redis
|
|
||||||
kubectl port-forward -n control-plane svc/redis 6379:6379 &
|
|
||||||
|
|
||||||
# Terminal 3: Run backend
|
|
||||||
cd backend
|
|
||||||
bun run dev
|
|
||||||
|
|
||||||
# Terminal 4: Test
|
|
||||||
curl http://localhost:3000/api/health
|
|
||||||
curl http://localhost:3000/api/projects
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎯 PASO 3: MCP Server Básico (60 min)
|
|
||||||
|
|
||||||
### 3.1 Crear estructura MCP
|
|
||||||
```bash
|
|
||||||
mkdir -p src/services/mcp
|
|
||||||
# Archivos:
|
|
||||||
# - services/mcp/server.ts
|
|
||||||
# - services/mcp/tools.ts
|
|
||||||
# - services/mcp/handlers.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3.2 Implementar herramientas básicas
|
|
||||||
|
|
||||||
**Herramientas mínimas para MVP**:
|
|
||||||
1. `get_next_task` - Obtener siguiente tarea
|
|
||||||
2. `update_task_status` - Actualizar estado
|
|
||||||
3. `create_branch` - Crear rama en Gitea
|
|
||||||
4. `create_pull_request` - Crear PR
|
|
||||||
|
|
||||||
**Referencia**: `docs/05-agents/mcp-tools.md`
|
|
||||||
|
|
||||||
**Template básico**:
|
|
||||||
```typescript
|
|
||||||
// src/services/mcp/server.ts
|
|
||||||
import { Server } from '@modelcontextprotocol/sdk/server/index.js'
|
|
||||||
|
|
||||||
export class MCPServer {
|
|
||||||
private server: Server
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this.server = new Server({
|
|
||||||
name: 'aiworker-mcp',
|
|
||||||
version: '1.0.0'
|
|
||||||
}, {
|
|
||||||
capabilities: { tools: {} }
|
|
||||||
})
|
})
|
||||||
|
|
||||||
this.setupHandlers()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Implementar handlers...
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3.3 Conectar MCP con Bun.serve()
|
### 1.5 Probar localmente
|
||||||
|
|
||||||
**Opciones**:
|
|
||||||
- **A**: Puerto separado (3100) para MCP
|
|
||||||
- **B**: Ruta `/mcp` en mismo server
|
|
||||||
|
|
||||||
**Recomendación**: Opción A (puerto 3100)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎯 PASO 4: Integración con Gitea (30 min)
|
|
||||||
|
|
||||||
### 4.1 Cliente API de Gitea
|
|
||||||
|
|
||||||
**Archivo**: `src/services/gitea/client.ts`
|
|
||||||
|
|
||||||
**Operaciones necesarias**:
|
|
||||||
```typescript
|
|
||||||
- createRepo(name, description)
|
|
||||||
- createBranch(owner, repo, branch, from)
|
|
||||||
- createPullRequest(owner, repo, {title, body, head, base})
|
|
||||||
- mergePullRequest(owner, repo, number)
|
|
||||||
```
|
|
||||||
|
|
||||||
**Usar**:
|
|
||||||
- Axios para HTTP requests
|
|
||||||
- Base URL: `https://git.fuq.tv/api/v1`
|
|
||||||
- Token: Variable de entorno `GITEA_TOKEN`
|
|
||||||
|
|
||||||
**Referencia**: `docs/02-backend/gitea-integration.md` (líneas 10-200)
|
|
||||||
|
|
||||||
### 4.2 Test de integración
|
|
||||||
```bash
|
```bash
|
||||||
# Crear un repo de prueba vía API
|
bun run server.ts
|
||||||
bun run src/test-gitea.ts
|
# Open http://localhost:3001
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Debe mostrar**:
|
||||||
|
- Dashboard básico
|
||||||
|
- Lista de proyectos (conectado a API)
|
||||||
|
- Sin auth por ahora (agregar en siguiente paso)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🎯 PASO 5: Deploy Backend en K8s (30 min)
|
## 🎯 PASO 2: Implementar Autenticación Básica (30 min)
|
||||||
|
|
||||||
### 5.1 Crear manifests
|
### 2.1 Configurar Lucia Auth
|
||||||
|
|
||||||
**Directorio**: `k8s/backend/`
|
**Referencia**: https://github.com/lucia-auth/lucia
|
||||||
|
|
||||||
**Archivos necesarios**:
|
**Crear** `frontend/src/lib/auth.ts`:
|
||||||
```yaml
|
```typescript
|
||||||
# deployment.yaml
|
import { Lucia } from "lucia"
|
||||||
# service.yaml
|
import { BunSQLiteAdapter } from "@lucia-auth/adapter-sqlite"
|
||||||
# ingress.yaml
|
|
||||||
# secrets.yaml
|
// Por ahora: SQLite local
|
||||||
|
// Después: Migrar a MariaDB del cluster
|
||||||
|
|
||||||
|
const adapter = new BunSQLiteAdapter(db)
|
||||||
|
|
||||||
|
export const lucia = new Lucia(adapter, {
|
||||||
|
sessionCookie: {
|
||||||
|
attributes: {
|
||||||
|
secure: process.env.NODE_ENV === "production"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
**Template deployment**:
|
### 2.2 Crear páginas de auth
|
||||||
|
|
||||||
|
```
|
||||||
|
frontend/src/pages/
|
||||||
|
├── Login.tsx
|
||||||
|
├── Register.tsx
|
||||||
|
└── Dashboard.tsx
|
||||||
|
```
|
||||||
|
|
||||||
|
**Features mínimas**:
|
||||||
|
- Login con email/password
|
||||||
|
- Registro de nuevos usuarios
|
||||||
|
- Logout
|
||||||
|
- Protected routes (redirect si no autenticado)
|
||||||
|
|
||||||
|
### 2.3 Integrar con backend
|
||||||
|
|
||||||
|
**Backend debe tener** (agregar si no existe):
|
||||||
|
```
|
||||||
|
POST /api/auth/register
|
||||||
|
POST /api/auth/login
|
||||||
|
POST /api/auth/logout
|
||||||
|
GET /api/auth/me
|
||||||
|
```
|
||||||
|
|
||||||
|
**Nota**: Si estos endpoints no existen, agregarlos al backend en esta sesión.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 PASO 3: Build y Deploy de Frontend (30 min)
|
||||||
|
|
||||||
|
### 3.1 Crear Dockerfile para frontend
|
||||||
|
|
||||||
|
**Crear** `frontend/Dockerfile`:
|
||||||
|
```dockerfile
|
||||||
|
FROM oven/bun:1.3.6
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY package.json bun.lockb ./
|
||||||
|
RUN bun install --frozen-lockfile
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
RUN bun build src/main.tsx --outdir ./dist --target browser
|
||||||
|
|
||||||
|
EXPOSE 3001
|
||||||
|
|
||||||
|
CMD ["bun", "run", "server.ts"]
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.2 Crear repo en Gitea
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd frontend
|
||||||
|
|
||||||
|
# Inicializar git
|
||||||
|
git init
|
||||||
|
git add .
|
||||||
|
git commit -m "Initial frontend implementation
|
||||||
|
|
||||||
|
- React dashboard with project/task views
|
||||||
|
- Lucia auth integration
|
||||||
|
- API client for backend
|
||||||
|
- Bun.serve() with HMR
|
||||||
|
|
||||||
|
Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>"
|
||||||
|
|
||||||
|
# Crear repo en Gitea (via API o UI)
|
||||||
|
curl -X POST https://git.fuq.tv/api/v1/user/repos \
|
||||||
|
-H "Authorization: token 159a5de2a16d15f33e388b55b1276e431dbca3f3" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"name":"aiworker-frontend","description":"AiWorker Frontend Dashboard","private":false,"auto_init":false}'
|
||||||
|
|
||||||
|
# Agregar remote y push
|
||||||
|
git remote add origin https://git.fuq.tv/admin/aiworker-frontend.git
|
||||||
|
git push -u origin main
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.3 Crear workflow de CI/CD
|
||||||
|
|
||||||
|
**Crear** `.gitea/workflows/build.yml`:
|
||||||
|
```yaml
|
||||||
|
name: Build and Push Frontend
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- name: Build Docker image
|
||||||
|
run: docker build -t git.fuq.tv/admin/aiworker-frontend:${{ gitea.sha }} .
|
||||||
|
- name: Tag as latest
|
||||||
|
run: docker tag git.fuq.tv/admin/aiworker-frontend:${{ gitea.sha }} git.fuq.tv/admin/aiworker-frontend:latest
|
||||||
|
- name: Login to registry
|
||||||
|
run: echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login git.fuq.tv -u admin --password-stdin
|
||||||
|
- name: Push images
|
||||||
|
run: |
|
||||||
|
docker push git.fuq.tv/admin/aiworker-frontend:${{ gitea.sha }}
|
||||||
|
docker push git.fuq.tv/admin/aiworker-frontend:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.4 Deploy en K8s
|
||||||
|
|
||||||
|
**Crear** `k8s/frontend/`:
|
||||||
|
```
|
||||||
|
k8s/frontend/
|
||||||
|
├── deployment.yaml
|
||||||
|
├── service.yaml
|
||||||
|
└── ingress.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
**deployment.yaml**:
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
name: backend
|
name: frontend
|
||||||
namespace: control-plane
|
namespace: control-plane
|
||||||
spec:
|
spec:
|
||||||
replicas: 2
|
replicas: 2
|
||||||
selector:
|
selector:
|
||||||
matchLabels:
|
matchLabels:
|
||||||
app: backend
|
app: frontend
|
||||||
template:
|
template:
|
||||||
spec:
|
spec:
|
||||||
imagePullSecrets:
|
imagePullSecrets:
|
||||||
- name: gitea-registry
|
- name: gitea-registry
|
||||||
containers:
|
containers:
|
||||||
- name: backend
|
- name: frontend
|
||||||
image: git.fuq.tv/admin/aiworker-backend:latest
|
image: git.fuq.tv/admin/aiworker-frontend:latest
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 3000
|
- containerPort: 3001
|
||||||
- containerPort: 3100 # MCP
|
|
||||||
env:
|
env:
|
||||||
- name: DB_HOST
|
- name: BACKEND_URL
|
||||||
value: mariadb.control-plane.svc.cluster.local
|
value: http://backend.control-plane.svc.cluster.local:3000
|
||||||
# ... más env vars
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### 5.2 Crear secrets
|
**ingress.yaml**:
|
||||||
```bash
|
|
||||||
kubectl create secret generic backend-secrets -n control-plane \
|
|
||||||
--from-literal=jwt-secret=your-secret \
|
|
||||||
--from-literal=anthropic-api-key=your-key
|
|
||||||
```
|
|
||||||
|
|
||||||
### 5.3 Deploy
|
|
||||||
```bash
|
|
||||||
kubectl apply -f k8s/backend/
|
|
||||||
kubectl get pods -n control-plane
|
|
||||||
kubectl logs -f deployment/backend -n control-plane
|
|
||||||
```
|
|
||||||
|
|
||||||
### 5.4 Crear Ingress
|
|
||||||
```yaml
|
```yaml
|
||||||
# Para api.fuq.tv
|
apiVersion: networking.k8s.io/v1
|
||||||
host: api.fuq.tv
|
kind: Ingress
|
||||||
backend: backend:3000
|
metadata:
|
||||||
|
name: frontend
|
||||||
|
namespace: control-plane
|
||||||
|
annotations:
|
||||||
|
cert-manager.io/cluster-issuer: letsencrypt-prod
|
||||||
|
spec:
|
||||||
|
tls:
|
||||||
|
- hosts:
|
||||||
|
- app.fuq.tv
|
||||||
|
secretName: frontend-tls
|
||||||
|
rules:
|
||||||
|
- host: app.fuq.tv
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: frontend
|
||||||
|
port:
|
||||||
|
number: 3001
|
||||||
```
|
```
|
||||||
|
|
||||||
### 5.5 Verificar
|
**Deploy**:
|
||||||
```bash
|
```bash
|
||||||
curl https://api.fuq.tv/api/health
|
kubectl apply -f k8s/frontend/
|
||||||
|
kubectl get pods -n control-plane -l app=frontend
|
||||||
|
kubectl get ingress -n control-plane frontend
|
||||||
|
```
|
||||||
|
|
||||||
|
**Verificar**:
|
||||||
|
```bash
|
||||||
|
curl -I https://app.fuq.tv
|
||||||
|
# HTTP/2 200
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🎯 PASO 6: Test End-to-End (15 min)
|
## 🎯 PASO 4: Primer Agente Claude Code (45 min)
|
||||||
|
|
||||||
### 6.1 Crear proyecto vía API
|
### 4.1 Entender arquitectura de agentes
|
||||||
```bash
|
|
||||||
curl -X POST https://api.fuq.tv/api/projects \
|
**Referencia**: `docs/05-agents/`, `AGENT-GUIDE.md`
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{
|
**Agente Claude Code es**:
|
||||||
"name": "test-project",
|
- Un pod en K8s namespace `agents`
|
||||||
"description": "First project"
|
- Corre `claude-code` CLI conectado vía MCP
|
||||||
}'
|
- Tiene acceso al código vía Git clone
|
||||||
|
- Reporta progreso al backend vía MCP tools
|
||||||
|
|
||||||
|
### 4.2 Crear Dockerfile del agente
|
||||||
|
|
||||||
|
**Crear** `agents/Dockerfile`:
|
||||||
|
```dockerfile
|
||||||
|
FROM node:20-alpine
|
||||||
|
|
||||||
|
# Instalar claude-code CLI
|
||||||
|
RUN npm install -g @anthropic/claude-code
|
||||||
|
|
||||||
|
# Instalar herramientas de desarrollo
|
||||||
|
RUN apk add --no-cache git bash curl
|
||||||
|
|
||||||
|
# Configurar MCP
|
||||||
|
COPY mcp-config.json /root/.config/claude-code/config.json
|
||||||
|
|
||||||
|
WORKDIR /workspace
|
||||||
|
|
||||||
|
CMD ["claude-code", "--mcp-server", "$BACKEND_MCP_URL"]
|
||||||
```
|
```
|
||||||
|
|
||||||
### 6.2 Crear tarea
|
### 4.3 Crear configuración MCP
|
||||||
```bash
|
|
||||||
curl -X POST https://api.fuq.tv/api/tasks \
|
**Crear** `agents/mcp-config.json`:
|
||||||
-H "Content-Type: application/json" \
|
```json
|
||||||
-d '{
|
{
|
||||||
"projectId": "xxx",
|
"mcpServers": {
|
||||||
"title": "Test task",
|
"aiworker": {
|
||||||
"description": "First automated task"
|
"url": "http://backend.control-plane.svc.cluster.local:3100",
|
||||||
}'
|
"tools": [
|
||||||
|
"get_next_task",
|
||||||
|
"update_task_status",
|
||||||
|
"create_branch",
|
||||||
|
"create_pull_request"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 6.3 Verificar en DB
|
### 4.4 Crear deployment del agente
|
||||||
|
|
||||||
|
**Crear** `k8s/agents/agent-deployment.yaml`:
|
||||||
|
```yaml
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: claude-agent
|
||||||
|
namespace: agents
|
||||||
|
spec:
|
||||||
|
replicas: 1 # Empezar con 1 agente
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: claude-agent
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: claude-agent
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: agent
|
||||||
|
image: git.fuq.tv/admin/aiworker-agent:latest
|
||||||
|
env:
|
||||||
|
- name: ANTHROPIC_API_KEY
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: agent-secrets
|
||||||
|
key: anthropic-api-key
|
||||||
|
- name: BACKEND_MCP_URL
|
||||||
|
value: http://backend.control-plane.svc.cluster.local:3100
|
||||||
|
- name: GITEA_URL
|
||||||
|
value: https://git.fuq.tv
|
||||||
|
- name: GITEA_TOKEN
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: agent-secrets
|
||||||
|
key: gitea-token
|
||||||
|
- name: AGENT_ID
|
||||||
|
valueFrom:
|
||||||
|
fieldRef:
|
||||||
|
fieldPath: metadata.name
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.5 Crear secret para agente
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
kubectl exec -n control-plane mariadb-0 -- \
|
kubectl create secret generic agent-secrets -n agents \
|
||||||
mariadb -uaiworker -pAiWorker2026_UserPass! aiworker \
|
--from-literal=anthropic-api-key='<TU_API_KEY>' \
|
||||||
-e "SELECT * FROM projects; SELECT * FROM tasks;"
|
--from-literal=gitea-token='159a5de2a16d15f33e388b55b1276e431dbca3f3'
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.6 Desplegar agente
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Crear namespace
|
||||||
|
kubectl create namespace agents
|
||||||
|
|
||||||
|
# Agregar registry secret
|
||||||
|
kubectl create secret docker-registry gitea-registry -n agents \
|
||||||
|
--docker-server=git.fuq.tv \
|
||||||
|
--docker-username=admin \
|
||||||
|
--docker-password=7401126cfb56ab2aebba17755bdc968c20768c27
|
||||||
|
|
||||||
|
# Deploy
|
||||||
|
kubectl apply -f k8s/agents/
|
||||||
|
kubectl get pods -n agents
|
||||||
|
kubectl logs -f -n agents deployment/claude-agent
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.7 Verificar agente registrado
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# El agente debe auto-registrarse al iniciar
|
||||||
|
curl -s https://api.fuq.tv/api/agents | jq
|
||||||
|
# Debe mostrar agente con status "idle"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 PASO 5: Test End-to-End del Flujo Completo (30 min)
|
||||||
|
|
||||||
|
### 5.1 Crear tarea de prueba
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Crear proyecto
|
||||||
|
PROJECT_ID=$(curl -s -X POST https://api.fuq.tv/api/projects \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{
|
||||||
|
"name": "test-agent-flow",
|
||||||
|
"description": "Test de flujo completo con agente",
|
||||||
|
"giteaOwner": "admin",
|
||||||
|
"giteaRepoName": "test-agent-flow"
|
||||||
|
}' | jq -r '.data.id')
|
||||||
|
|
||||||
|
echo "Project ID: $PROJECT_ID"
|
||||||
|
|
||||||
|
# 2. Crear tarea
|
||||||
|
TASK_ID=$(curl -s -X POST https://api.fuq.tv/api/tasks \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d "{
|
||||||
|
\"projectId\": \"$PROJECT_ID\",
|
||||||
|
\"title\": \"Add hello world endpoint\",
|
||||||
|
\"description\": \"Create a simple GET /hello endpoint that returns 'Hello World'\",
|
||||||
|
\"priority\": \"high\"
|
||||||
|
}" | jq -r '.data.id')
|
||||||
|
|
||||||
|
echo "Task ID: $TASK_ID"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.2 Monitorear logs del agente
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Terminal 1: Logs del agente
|
||||||
|
kubectl logs -f -n agents deployment/claude-agent
|
||||||
|
|
||||||
|
# Terminal 2: Ver estado de la tarea
|
||||||
|
watch -n 2 "curl -s https://api.fuq.tv/api/tasks/$TASK_ID | jq '.data.state'"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.3 Verificar flujo completo
|
||||||
|
|
||||||
|
**Debe ocurrir**:
|
||||||
|
1. Agente obtiene tarea con `get_next_task`
|
||||||
|
2. Estado cambia: `backlog` → `in_progress`
|
||||||
|
3. Agente crea branch con `create_branch`
|
||||||
|
4. Agente implementa código
|
||||||
|
5. Agente crea PR con `create_pull_request`
|
||||||
|
6. Estado cambia: `in_progress` → `ready_to_test`
|
||||||
|
7. PR visible en Gitea
|
||||||
|
|
||||||
|
**Verificar PR**:
|
||||||
|
```bash
|
||||||
|
# Ver PRs en Gitea
|
||||||
|
curl -s -H "Authorization: token 159a5de2a16d15f33e388b55b1276e431dbca3f3" \
|
||||||
|
"https://git.fuq.tv/api/v1/repos/admin/test-agent-flow/pulls" | jq
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.4 Revisar dashboard
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Abrir dashboard
|
||||||
|
open https://app.fuq.tv
|
||||||
|
|
||||||
|
# Debe mostrar:
|
||||||
|
# - Proyecto "test-agent-flow"
|
||||||
|
# - Tarea "Add hello world endpoint" con estado "ready_to_test"
|
||||||
|
# - PR link visible
|
||||||
|
# - Agente con status "idle" (completó tarea)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 PASO 6: Webhooks de Gitea (OPCIONAL, 15 min)
|
||||||
|
|
||||||
|
Si hay tiempo, configurar webhooks para notificaciones.
|
||||||
|
|
||||||
|
### 6.1 Crear endpoint de webhook en backend
|
||||||
|
|
||||||
|
**Agregar** a `backend/src/api/routes/webhooks.ts`:
|
||||||
|
```typescript
|
||||||
|
export async function handleGiteaWebhook(req: Request) {
|
||||||
|
const event = req.headers.get('X-Gitea-Event')
|
||||||
|
const payload = await req.json()
|
||||||
|
|
||||||
|
switch (event) {
|
||||||
|
case 'pull_request':
|
||||||
|
// Notificar frontend vía WebSocket
|
||||||
|
break
|
||||||
|
case 'push':
|
||||||
|
// Trigger preview deploy
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6.2 Configurar webhook en Gitea
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Via API
|
||||||
|
curl -X POST https://git.fuq.tv/api/v1/repos/admin/test-agent-flow/hooks \
|
||||||
|
-H "Authorization: token 159a5de2a16d15f33e388b55b1276e431dbca3f3" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{
|
||||||
|
"type": "gitea",
|
||||||
|
"config": {
|
||||||
|
"url": "https://api.fuq.tv/api/webhooks/gitea",
|
||||||
|
"content_type": "json"
|
||||||
|
},
|
||||||
|
"events": ["push", "pull_request"],
|
||||||
|
"active": true
|
||||||
|
}'
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📝 NOTAS IMPORTANTES
|
## 📝 NOTAS IMPORTANTES
|
||||||
|
|
||||||
### Desarrollo Local vs K8s
|
### Frontend con Bun
|
||||||
|
- **Bun.serve()** tiene soporte nativo para React/JSX
|
||||||
|
- HTML imports automáticos: `import index from './index.html'`
|
||||||
|
- HMR funciona out-of-the-box con `development: { hmr: true }`
|
||||||
|
- No necesitas Vite/Webpack
|
||||||
|
|
||||||
**Local (desarrollo)**:
|
### Agentes Claude Code
|
||||||
- Port-forward para MariaDB y Redis
|
- **MCP es clave**: Los agentes se comunican exclusivamente vía MCP
|
||||||
- `bun run dev` con hot-reload
|
- **Sin API REST**: Agentes NO llaman directamente a `/api/`, usan herramientas MCP
|
||||||
- Cambios rápidos
|
- **Auto-registro**: Agente debe llamar `POST /api/agents` al iniciar
|
||||||
|
- **Heartbeat**: Cada 30s llamar `POST /api/agents/:id/heartbeat`
|
||||||
|
|
||||||
**K8s (testing/producción)**:
|
### Auth y Sesiones
|
||||||
- Build → Push → Deploy
|
- Lucia Auth usa cookies HTTPOnly para sesiones
|
||||||
- Migrations automáticas en startup
|
- En desarrollo: cookies inseguras (HTTP)
|
||||||
- Logs con kubectl
|
- En producción: cookies secure (HTTPS)
|
||||||
|
- Considerar migrar SQLite → MariaDB para auth
|
||||||
### Migrations
|
|
||||||
|
|
||||||
**SIEMPRE** automáticas en el código:
|
|
||||||
```typescript
|
|
||||||
// src/index.ts
|
|
||||||
await runMigrations() // Al inicio
|
|
||||||
```
|
|
||||||
|
|
||||||
**NUNCA** manuales con port-forward
|
|
||||||
|
|
||||||
### Secrets
|
|
||||||
|
|
||||||
**Desarrollo**: `.env` (git-ignored)
|
|
||||||
**Producción**: Kubernetes Secrets
|
|
||||||
|
|
||||||
```bash
|
|
||||||
kubectl create secret generic app-secrets -n namespace \
|
|
||||||
--from-env-file=.env.production
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🐛 TROUBLESHOOTING
|
## 🐛 TROUBLESHOOTING
|
||||||
|
|
||||||
### Si backend no arranca
|
### Si frontend no conecta con backend
|
||||||
```bash
|
```bash
|
||||||
# Ver logs
|
# Verificar que backend esté accesible desde frontend pod
|
||||||
kubectl logs -n control-plane deployment/backend
|
kubectl exec -n control-plane deployment/frontend -- \
|
||||||
|
curl http://backend.control-plane.svc.cluster.local:3000/api/health
|
||||||
# Verificar DB connection
|
|
||||||
kubectl exec -n control-plane mariadb-0 -- \
|
|
||||||
mariadb -uaiworker -pAiWorker2026_UserPass! -e "SELECT 1"
|
|
||||||
|
|
||||||
# Verificar Redis
|
|
||||||
kubectl exec -n control-plane deployment/redis -- redis-cli ping
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Si Actions no funciona
|
### Si agente no registra
|
||||||
```bash
|
```bash
|
||||||
# Ver runner
|
# Ver logs del agente
|
||||||
kubectl get pods -n gitea-actions
|
kubectl logs -n agents deployment/claude-agent --tail=50
|
||||||
kubectl logs -n gitea-actions deployment/gitea-runner -c runner
|
|
||||||
|
|
||||||
# Restart runner
|
# Verificar connectivity a backend
|
||||||
|
kubectl exec -n agents deployment/claude-agent -- \
|
||||||
|
curl http://backend.control-plane.svc.cluster.local:3000/api/health
|
||||||
|
```
|
||||||
|
|
||||||
|
### Si CI/CD falla
|
||||||
|
```bash
|
||||||
|
# Ver runner logs
|
||||||
|
kubectl logs -n gitea-actions deployment/gitea-runner -c runner --tail=100
|
||||||
|
|
||||||
|
# Restart runner si está stuck
|
||||||
kubectl rollout restart deployment/gitea-runner -n gitea-actions
|
kubectl rollout restart deployment/gitea-runner -n gitea-actions
|
||||||
```
|
```
|
||||||
|
|
||||||
### Si Ingress no resuelve
|
|
||||||
```bash
|
|
||||||
# Verificar DNS
|
|
||||||
dig api.fuq.tv +short
|
|
||||||
# Debe mostrar: 108.165.47.221 y 108.165.47.203
|
|
||||||
|
|
||||||
# Verificar certificado
|
|
||||||
kubectl get certificate -n control-plane
|
|
||||||
|
|
||||||
# Logs de Ingress
|
|
||||||
kubectl logs -n ingress-nginx deployment/ingress-nginx-controller --tail=50
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## ✅ CHECKLIST DE SESIÓN
|
## ✅ CHECKLIST DE SESIÓN
|
||||||
|
|
||||||
Al final de cada sesión, verificar:
|
Al final de la sesión, verificar:
|
||||||
|
|
||||||
- [ ] Código commitado y pusheado a Gitea
|
- [ ] Frontend deployado en https://app.fuq.tv
|
||||||
- [ ] Build de CI/CD exitoso
|
- [ ] Login/Register funcionando
|
||||||
- [ ] Pods corriendo en K8s
|
- [ ] Dashboard muestra proyectos y tareas
|
||||||
- [ ] Endpoints accesibles vía HTTPS
|
- [ ] Agente corriendo en namespace `agents`
|
||||||
- [ ] Documentación actualizada
|
- [ ] Agente registrado en DB (visible en API)
|
||||||
- [ ] Credenciales documentadas en lugar seguro
|
- [ ] Flujo completo probado: Tarea → Agente → PR
|
||||||
- [ ] Tests básicos pasando
|
- [ ] Código commitado en 2 repos (frontend, agents)
|
||||||
|
- [ ] Builds exitosos en Gitea Actions
|
||||||
|
- [ ] Imágenes en registry
|
||||||
|
- [ ] Documentación de sesión creada en `past-sessions/`
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🎉 META
|
## 🎉 META
|
||||||
|
|
||||||
**Completado**: Infraestructura HA + Backend base
|
**Completado hasta ahora**: Infraestructura HA + Backend API + MCP Server
|
||||||
**Próximo hito**: Backend API funcional + MCP Server
|
**Esta sesión**: Frontend Dashboard + Primer Agente Funcional
|
||||||
**Hito final**: Sistema completo de agentes autónomos
|
**Próximo hito**: Preview Environments + Agents Pool + Monitoring
|
||||||
|
|
||||||
**¡Excelente progreso! Sigue el roadmap y lo tendrás listo pronto! 🚀**
|
**¡Casi llegamos al MVP funcional! 🚀**
|
||||||
|
|||||||
@@ -38,6 +38,9 @@ Tarea → Agente → Código → PR → Preview Deploy → Aprobación → Stagi
|
|||||||
- **[AGENT-GUIDE.md](AGENT-GUIDE.md)** - Guía para agentes IA
|
- **[AGENT-GUIDE.md](AGENT-GUIDE.md)** - Guía para agentes IA
|
||||||
- **[TROUBLESHOOTING.md](TROUBLESHOOTING.md)** - Solución de problemas
|
- **[TROUBLESHOOTING.md](TROUBLESHOOTING.md)** - Solución de problemas
|
||||||
|
|
||||||
|
### 📜 Historial
|
||||||
|
- **[past-sessions/](past-sessions/)** - Documentación de cada sesión de desarrollo
|
||||||
|
|
||||||
### 📖 Documentación Completa
|
### 📖 Documentación Completa
|
||||||
- **[docs/](docs/)** - 40+ archivos de documentación detallada
|
- **[docs/](docs/)** - 40+ archivos de documentación detallada
|
||||||
- `01-arquitectura/` - Diseño del sistema
|
- `01-arquitectura/` - Diseño del sistema
|
||||||
|
|||||||
Reference in New Issue
Block a user