clase:daw:daw-proyecto:tema04
Diferencias
Muestra las diferencias entre dos versiones de la página.
| Ambos lados, revisión anteriorRevisión previaPróxima revisión | Revisión previa | ||
| clase:daw:daw-proyecto:tema04 [2026/10/13 23:54] – IA: mini SDD con modo plan, contexto, skills de convenciones, MCP, permisos, primer CRUD claude | clase:daw:daw-proyecto:tema04 [2026/10/14 14:08] (actual) – Tema nuevo «2. IA y agentes»: los temas 2 a 7 pasan a ser 3 a 8, con sus referencias cruzadas renumeradas claude | ||
|---|---|---|---|
| Línea 1: | Línea 1: | ||
| - | ====== 4. IA en el proyecto ====== | + | ====== 4. Docker |
| - | Objetivo del tema: usar bien al agente para programar. No se enseña a programar; se enseña a **pedir** el trabajo | + | Objetivo del tema: cada worktree tiene **su propia aplicación completa funcionando** (base de datos, backend |
| - | Lo que ya está contado en el [[cursos:sdd:start|curso de programación con IA]] y aquí no se repite: qué es el [[cursos:sdd:10-spec-driven-development|Spec-driven development]] y por qué encaja con los agentes, los modos Plan y Build de [[cursos:sdd:03-opencode# | + | Lo que ya sabéis y aquí no se repite: imágenes y contenedores ([[clase: |
| - | ===== Mini SDD con el modo plan ===== | + | ===== Tres contenedores |
| - | Los frameworks de SDD completos (OpenSpec, Spec Kit, cc-sdd) generan requisitos, diseño y tareas en documentos separados. Para un proyecto | + | La aplicación son tres contenedores, uno por caja del diagrama C4 de contenedores: |
| - | - **La intención escrita en un fichero** antes de tocar código, revisada por una persona. | + | ^ Servicio ^ Imagen ^ Qué hace ^ |
| - | - **Ejecutarla con el contexto limpio**, | + | | '' |
| + | | '' | ||
| + | | '' | ||
| - | Ese es el flujo de cada issue: | + | El navegador solo habla con '' |
| - | < | + | Los dos Dockerfile son **multi-stage** |
| - | start | + | |
| - | :En el worktree del issue, | + | |
| - | entrar en modo plan; | + | |
| - | :Decir qué se quiere | + | |
| - | que pregunte lo que no esté claro; | + | |
| - | :El agente propone el plan; | + | |
| - | repeat | + | |
| - | :Leerlo y corregirlo; | + | |
| - | repeat while (¿hay algo que cambiar?) is (sí) | + | |
| - | :Salir del modo plan: | + | |
| - | el agente guarda planes/ | + | |
| - | y no hace nada más; | + | |
| - | :/clear; | + | |
| - | :Ejecuta @planes/ | + | |
| - | :El agente implementa y pasa los tests; | + | |
| - | stop | + | |
| - | </ | + | |
| - | ==== 1. Planificar ==== | + | <sxh bash; |
| + | FROM maven: | ||
| + | WORKDIR /app | ||
| + | COPY pom.xml . | ||
| + | RUN --mount=type=cache, | ||
| + | COPY src ./src | ||
| + | RUN --mount=type=cache, | ||
| - | En Claude Code, '' | + | FROM eclipse-temurin: |
| + | RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/* | ||
| + | COPY --from=build | ||
| + | ENTRYPOINT [" | ||
| + | </ | ||
| - | Lo que se le dice: | + | El '' |
| - | <code> | + | <sxh bash; |
| - | Quiero implementar el issue #12 (gh issue view 12). Antes de proponer nada, hazme | + | FROM node:22 AS build |
| - | las preguntas que necesites. El resultado de este plan es SOLO el fichero | + | WORKDIR /app |
| - | planes/ | + | COPY package*.json |
| - | </ | + | RUN npm ci |
| + | COPY . . | ||
| + | RUN npx ng build --configuration production | ||
| - | El plan tiene que decir **qué** y **cómo**: | + | FROM nginx:alpine |
| + | COPY nginx.conf / | ||
| + | COPY --from=build / | ||
| + | </ | ||
| - | * Cambios en la base de datos (la migración), | + | <sxh plain; |
| - | * Las decisiones de diseño que haya tomado y por qué. | + | server { |
| - | * Los **criterios de aceptación**: | + | |
| + | root / | ||
| - | **Revisarlo es el trabajo humano del flujo.** Es mucho más barato corregir una frase del plan que corregir el código que sale de ella. Si el plan tiene algo que no convence, se le dice y se repite hasta que esté bien. | + | location /api/ { |
| + | proxy_pass http:// | ||
| + | } | ||
| - | ==== 2. Guardar y limpiar ==== | + | location / { |
| + | try_files $uri $uri/ /index.html; | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| - | Al aprobar el plan, el agente guarda | + | El '' |
| - | Por qué: al salir del modo plan, por defecto el agente implementa en la **misma conversación**, | + | ===== Producción |
| - | ==== 3. Ejecutar ==== | + | Docker Compose carga '' |
| - | < | + | * '' |
| - | Ejecuta @planes/12-alta-clientes.md. Al acabar, compila | + | * '' |
| - | </ | + | |
| - | El agente implementa con el contexto limpio: solo tiene '' | + | <sxh yaml;title:compose.yaml> |
| + | services: | ||
| + | db: | ||
| + | image: mariadb: | ||
| + | environment: | ||
| + | MARIADB_DATABASE: | ||
| + | MARIADB_USER: | ||
| + | MARIADB_PASSWORD: | ||
| + | MARIADB_ROOT_PASSWORD: | ||
| + | volumes: | ||
| + | - db-data:/ | ||
| + | networks: | ||
| + | - interna | ||
| + | healthcheck: | ||
| + | test: [" | ||
| + | interval: 5s | ||
| + | retries: 20 | ||
| - | ==== La carpeta planes/ ==== | + | backend: |
| + | build: ./backend | ||
| + | environment: | ||
| + | SPRING_DATASOURCE_URL: | ||
| + | SPRING_DATASOURCE_USERNAME: | ||
| + | SPRING_DATASOURCE_PASSWORD: | ||
| + | depends_on: | ||
| + | db: | ||
| + | condition: service_healthy | ||
| + | networks: | ||
| + | - interna | ||
| + | healthcheck: | ||
| + | test: [" | ||
| + | interval: 5s | ||
| + | retries: 20 | ||
| - | '' | + | frontend: |
| + | build: ./frontend | ||
| + | environment: | ||
| + | VIRTUAL_HOST: | ||
| + | depends_on: | ||
| + | backend: | ||
| + | condition: service_healthy | ||
| + | networks: | ||
| + | - interna | ||
| + | - proxy | ||
| - | Es un **registro** de lo que se pidió, | + | volumes: |
| + | db-data: | ||
| + | |||
| + | networks: | ||
| + | interna: | ||
| + | proxy: | ||
| + | external: true | ||
| + | name: nginx-proxy-network | ||
| + | </ | ||
| + | |||
| + | Los '' | ||
| + | |||
| + | <sxh yaml; | ||
| + | services: | ||
| + | db: | ||
| + | ports: | ||
| + | - " | ||
| + | |||
| + | backend: | ||
| + | ports: | ||
| + | - " | ||
| + | environment: | ||
| + | SPRING_PROFILES_ACTIVE: | ||
| + | |||
| + | frontend: | ||
| + | build: | ||
| + | target: build | ||
| + | command: npx ng serve --host 0.0.0.0 --proxy-config proxy.conf.json | ||
| + | volumes: | ||
| + | - ./ | ||
| + | - / | ||
| + | ports: | ||
| + | - " | ||
| + | </ | ||
| + | |||
| + | Lo que cambia en desarrollo: | ||
| + | |||
| + | | ||
| + | * **El frontend pasa a '' | ||
| + | * **El backend | ||
| + | * **Datos de prueba** activados (abajo). | ||
| + | |||
| + | <note important> | ||
| + | |||
| + | ===== Un compose por worktree ===== | ||
| + | |||
| + | Dos worktrees con el mismo '' | ||
| + | |||
| + | <sxh bash; | ||
| + | COMPOSE_PROJECT_NAME=mi-proyecto-12-alta-clientes | ||
| + | DB_PORT=33112 | ||
| + | BACKEND_PORT=8112 | ||
| + | FRONTEND_PORT=4212 | ||
| + | DB_PASSWORD=dev | ||
| + | </ | ||
| + | |||
| + | * '' | ||
| + | * Los puertos los busca ''/ | ||
| + | * Las variables llevan valor por defecto, '' | ||
| + | |||
| + | ''/ | ||
| + | |||
| + | ===== La primera tabla ===== | ||
| + | |||
| + | Hasta ahora el backend no tiene base de datos. Se añaden ahora, con un prompt directo al agente (el flujo de trabajo de verdad llega en el tema 5; esto es solo para tener algo que ver): | ||
| + | |||
| + | * Dependencias '' | ||
| + | * Una migración '' | ||
| + | * Un '' | ||
| + | |||
| + | El esquema **siempre** va en migraciones de Flyway, '' | ||
| + | |||
| + | ===== Datos de prueba ===== | ||
| + | |||
| + | Cada worktree arranca con la base de datos vacía: no hay nada que ver en la aplicación ni se pueden escribir tests E2E que dependan de que exista un cliente. Los datos de prueba se separan del esquema: | ||
| < | < | ||
| - | planes/ es histórico: la fuente de verdad es el código. No leas planes antiguos salvo que te lo pidan. | + | backend/src/ |
| + | ├── migration/ | ||
| + | └── datos-prueba/ | ||
| </ | </ | ||
| - | ==== Cuándo usar el flujo ==== | + | Los de '' |
| - | ^ Tamaño del cambio ^ Cómo ^ | + | <sxh plain; |
| - | | Trivial: un texto, un color, una validación de un campo | Prompt directo, sin plan | | + | spring.flyway.locations=classpath:db/ |
| - | | Todo lo demás | Plan → fichero → '' | + | </sxh> |
| - | | Un CRUD | ''/ | + | |
| - | ===== El contexto del agente ===== | + | * En desarrollo el perfil lo activa '' |
| + | * En producción '' | ||
| + | * Para volver al estado inicial (antes de pasar los E2E, por ejemplo): '' | ||
| - | El contexto es todo lo que el modelo tiene delante en una conversación: | + | Cada entidad nueva trae su '' |
| - | * **Una conversación por tarea.** ''/ | + | ===== El script app.sh ===== |
| - | * **El modelo bueno para planificar, el barato para ejecutar** cosas claras. ''/ | + | |
| - | * **No pegar logs enteros.** Solo el error y las líneas de alrededor. | + | |
| - | * **Mirar el contador.** ''/ | + | |
| - | ===== Skills | + | Operar la aplicación es siempre lo mismo y no necesita ninguna inteligencia, |
| - | El agente escribe código | + | <sxh bash; |
| + | # | ||
| + | # La aplicación | ||
| + | set -e | ||
| + | cd " | ||
| + | case " | ||
| + | start) | ||
| + | docker network inspect nginx-proxy-network >/ | ||
| + | docker compose up -d --build --wait | ||
| + | [ -f .env ] && | ||
| + | echo " | ||
| + | stop) | ||
| + | status) docker compose ps ;; | ||
| + | logs) | ||
| + | *) echo "uso: $0 start | stop [-v] | status | logs"; exit 1 ;; | ||
| + | esac | ||
| + | </ | ||
| - | ^ Skill ^ Qué contiene ^ | + | * '' |
| - | | '' | + | * '' |
| - | | '' | + | |
| + | * Trabaja sobre la carpeta en la que está y lee su '' | ||
| - | La arquitectura es la que ya conocéis | + | < |
| - | **Se escriben a partir del código, no de la teoría.** Después del primer CRUD, revisado | + | ===== Dónde corren Maven y los tests ===== |
| - | La '' | + | Las imágenes son de **ejecución**: |
| - | <sxh yaml> | + | ^ Qué ^ Dónde ^ Contra qué ^ |
| - | --- | + | | '' |
| - | name: convenciones-backend | + | | '' |
| - | description: Cómo se escribe el código del backend en este proyecto | + | | '' |
| - | --- | + | |
| - | </sxh> | + | |
| - | ===== MCP ===== | + | Son los tres comandos de tests del proyecto. Maven y npm funcionan igual en Linux, Windows y Mac, y son lo que ejecutan el alumno, el agente y CI (tema 7). '' |
| - | Dos servidores MCP y ninguno más (qué es un MCP: [[cursos:sdd:02-skills-agentes-mcp# | + | ==== npm run ==== |
| + | |||
| + | '' | ||
| + | |||
| + | <sxh json;title:frontend/ | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | "test:e2e": " | ||
| + | } | ||
| + | </ | ||
| - | * **Context7**: | + | Los dos scripts resetean la base de datos del worktree, esperan a que la aplicación |
| - | * **Playwright MCP**: el agente abre la aplicación | + | |
| - | Se configuran con '' | + | Esto va en '' |
| - | ===== Permisos del agente | + | ===== Ejercicios |
| - | En el tema 1 se permitió lo básico. Para programar, el agente | + | ==== Ejercicio |
| + | * Crea un issue «Aplicación en Docker» e inícialo con ''/ | ||
| + | * Pide al agente los dos '' | ||
| + | * Añade '' | ||
| + | * '' | ||
| + | * Entra en '' | ||
| - | | + | ==== Ejercicio 2 ==== |
| - | * **Pregunta**: | + | |
| - | * **Denegado**: | + | * Crea '' |
| + | * '' | ||
| + | * Arranca con '' | ||
| + | * Cambia un texto de la página de Angular, guarda | ||
| - | En OpenCode, lo mismo en la clave '' | + | ==== Ejercicio 3 ==== |
| + | * Añade a '' | ||
| + | * Escribe | ||
| + | * ''/ | ||
| - | ===== Práctica ===== | + | ==== Ejercicio 4 ==== |
| + | * Escribe '' | ||
| + | * Amplía ''/ | ||
| + | * Finaliza el issue. | ||
| - | - Configurar Context7 y Playwright MCP y completar los permisos. | + | ==== Ejercicio 5 ==== |
| - | | + | * Crea dos issues cualesquiera, |
| - | - De ese CRUD, las skills | + | |
| - | | + | * Finaliza los dos y comprueba |
clase/daw/daw-proyecto/tema04.1791928452.txt.gz · Última modificación: por claude
