Files
aiworker/NEXT-SESSION.md
Hector Ros fcaac6aa3e 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>
2026-01-20 01:06:54 +01:00

15 KiB

📋 Próxima Sesión - Frontend Dashboard & Primer Agente

Objetivo: Implementar Frontend Dashboard y desplegar primer agente Claude Code funcional Tiempo estimado: 2-3 horas Sesión anterior: past-sessions/2026-01-19-backend-api-implementation.md


PRE-REQUISITOS (Verificar antes de empezar)

# 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
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
# 6 nodos Ready

# 4. Registry accesible
curl -s -H "Authorization: token 159a5de2a16d15f33e388b55b1276e431dbca3f3" \
  "https://git.fuq.tv/api/v1/packages/admin?type=container" | grep aiworker-backend
# Debe mostrar paquete

Si algo falla: Revisar TROUBLESHOOTING.md o última sesión en past-sessions/


🎯 PASO 1: Crear Frontend Base con Bun (45 min)

1.1 Crear estructura de frontend

cd /Users/hectorros/projects/teamSquadAiWorker
mkdir -p frontend/{src,public}
cd frontend

# Inicializar proyecto Bun
bun init -y

1.2 Instalar dependencias

# React + TypeScript
bun add react react-dom
bun add -d @types/react @types/react-dom

# Routing
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

1.3 Crear componentes básicos

Estructura necesaria:

frontend/src/
├── index.html         # HTML entry point
├── main.tsx          # React root
├── App.tsx           # Main app component
├── components/
│   ├── Layout.tsx
│   ├── ProjectList.tsx
│   ├── TaskList.tsx
│   └── AgentStatus.tsx
├── api/
│   └── client.ts     # Axios client para backend
└── types/
    └── index.ts      # TypeScript types

1.4 Configurar Bun.serve() para frontend

Crear frontend/server.ts:

import index from './src/index.html'

Bun.serve({
  port: 3001,
  routes: {
    '/': index,
    '/api/*': {
      GET: async (req) => {
        // Proxy to backend
        const path = new URL(req.url).pathname.replace(/^\/api/, '')
        return fetch(`https://api.fuq.tv/api${path}`)
      }
    }
  },
  development: {
    hmr: true,
    console: true
  }
})

1.5 Probar localmente

bun run server.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 2: Implementar Autenticación Básica (30 min)

2.1 Configurar Lucia Auth

Referencia: https://github.com/lucia-auth/lucia

Crear frontend/src/lib/auth.ts:

import { Lucia } from "lucia"
import { BunSQLiteAdapter } from "@lucia-auth/adapter-sqlite"

// 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"
    }
  }
})

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:

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

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:

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:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend
  namespace: control-plane
spec:
  replicas: 2
  selector:
    matchLabels:
      app: frontend
  template:
    spec:
      imagePullSecrets:
      - name: gitea-registry
      containers:
      - name: frontend
        image: git.fuq.tv/admin/aiworker-frontend:latest
        ports:
        - containerPort: 3001
        env:
        - name: BACKEND_URL
          value: http://backend.control-plane.svc.cluster.local:3000

ingress.yaml:

apiVersion: networking.k8s.io/v1
kind: Ingress
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

Deploy:

kubectl apply -f k8s/frontend/
kubectl get pods -n control-plane -l app=frontend
kubectl get ingress -n control-plane frontend

Verificar:

curl -I https://app.fuq.tv
# HTTP/2 200

🎯 PASO 4: Primer Agente Claude Code (45 min)

4.1 Entender arquitectura de agentes

Referencia: docs/05-agents/, AGENT-GUIDE.md

Agente Claude Code es:

  • Un pod en K8s namespace agents
  • 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:

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"]

4.3 Crear configuración MCP

Crear agents/mcp-config.json:

{
  "mcpServers": {
    "aiworker": {
      "url": "http://backend.control-plane.svc.cluster.local:3100",
      "tools": [
        "get_next_task",
        "update_task_status",
        "create_branch",
        "create_pull_request"
      ]
    }
  }
}

4.4 Crear deployment del agente

Crear k8s/agents/agent-deployment.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

kubectl create secret generic agent-secrets -n agents \
  --from-literal=anthropic-api-key='<TU_API_KEY>' \
  --from-literal=gitea-token='159a5de2a16d15f33e388b55b1276e431dbca3f3'

4.6 Desplegar agente

# 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

# 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

# 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

# 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: backlogin_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_progressready_to_test
  7. PR visible en Gitea

Verificar PR:

# 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

# 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:

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

# 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

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

Agentes Claude Code

  • MCP es clave: Los agentes se comunican exclusivamente vía MCP
  • Sin API REST: Agentes NO llaman directamente a /api/, usan herramientas MCP
  • Auto-registro: Agente debe llamar POST /api/agents al iniciar
  • Heartbeat: Cada 30s llamar POST /api/agents/:id/heartbeat

Auth y Sesiones

  • Lucia Auth usa cookies HTTPOnly para sesiones
  • En desarrollo: cookies inseguras (HTTP)
  • En producción: cookies secure (HTTPS)
  • Considerar migrar SQLite → MariaDB para auth

🐛 TROUBLESHOOTING

Si frontend no conecta con backend

# Verificar que backend esté accesible desde frontend pod
kubectl exec -n control-plane deployment/frontend -- \
  curl http://backend.control-plane.svc.cluster.local:3000/api/health

Si agente no registra

# Ver logs del agente
kubectl logs -n agents deployment/claude-agent --tail=50

# 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

# 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

CHECKLIST DE SESIÓN

Al final de la sesión, verificar:

  • Frontend deployado en https://app.fuq.tv
  • Login/Register funcionando
  • Dashboard muestra proyectos y tareas
  • Agente corriendo en namespace agents
  • Agente registrado en DB (visible en API)
  • Flujo completo probado: Tarea → Agente → PR
  • 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

Completado hasta ahora: Infraestructura HA + Backend API + MCP Server Esta sesión: Frontend Dashboard + Primer Agente Funcional Próximo hito: Preview Environments + Agents Pool + Monitoring

¡Casi llegamos al MVP funcional! 🚀