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/14 12:34] – /developer pasa a ser /code, con review (hallazgos como tareas en review.md) e impl <plan> (hace las tareas de review.md o de un plan a mano); /sdd spec impl solo para la spec 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 como una especificación | + | 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, [[cursos:sdd:11-kiro|cc-sdd (Kiro)]] con sus fases y su memoria del proyecto, | + | Lo que ya sabéis y aquí no se repite: imágenes y contenedores ([[clase: |
| - | ===== Un solo camino: la spec ===== | + | ===== Tres contenedores |
| - | En este proyecto todo issue se hace igual, sea un CRUD o un cambio pequeño: primero una **especificación** en ficheros (requisitos, | + | La aplicación son tres contenedores, uno por caja del diagrama C4 de contenedores: |
| - | La spec la genera **cc-sdd** (la versión libre del flujo de Kiro), pero el alumno no escribe sus comandos: los envuelve una skill del proyecto, | + | ^ Servicio ^ Imagen ^ Qué hace ^ |
| + | | '' | ||
| + | | '' | ||
| + | | '' | ||
| - | < | + | El navegador solo habla con '' |
| - | npx cc-sdd@latest --claude-skills --lang es (OpenCode: --opencode-skills) | + | |
| - | </code> | + | |
| - | Ese es el flujo de cada issue: | + | Los dos Dockerfile son **multi-stage** y los escribe la IA. Lo único que hay que vigilar: |
| - | <uml> | + | <sxh bash; |
| - | start | + | FROM maven:3.9-eclipse-temurin-25 AS build |
| - | :/git-flow start N | + | WORKDIR |
| - | y ./app.sh start; | + | COPY pom.xml |
| - | :/sdd spec create | + | RUN --mount=type=cache,target=/root/.m2 mvn -q dependency:go-offline |
| - | requisitos, diseño y tareas | + | COPY src ./src |
| - | en .kiro/specs/N-slug/; | + | RUN --mount=type=cache, |
| - | repeat | + | |
| - | | + | |
| - | repeat while (¿hay algo que cambiar?) is (sí: /sdd spec create otra vez) | + | |
| - | :/clear; | + | |
| - | :/sdd spec impl | + | |
| - | una tarea tras otra, | + | |
| - | tests unitarios y de arquitectura | + | |
| - | después de cada una; | + | |
| - | :Probar en el navegador; | + | |
| - | stop | + | |
| - | </ | + | |
| - | ==== /sdd spec create ==== | + | FROM eclipse-temurin: |
| + | RUN apt-get update && apt-get install -y curl && rm -rf /var/ | ||
| + | COPY --from=build / | ||
| + | ENTRYPOINT [" | ||
| + | </ | ||
| - | Se lanza en el worktree del issue, sin argumentos: el número del issue está en el nombre | + | El '' |
| - | - '' | + | <sxh bash; |
| - | - '' | + | FROM node:22 AS build |
| - | - ''/ | + | WORKDIR |
| - | - ''/ | + | COPY package*.json . |
| + | RUN npm ci | ||
| + | COPY . . | ||
| + | RUN npx ng build --configuration production | ||
| - | Y se para. El resultado son tres ficheros en '' | + | FROM nginx: |
| + | COPY nginx.conf /etc/nginx/conf.d/default.conf | ||
| + | COPY --from=build / | ||
| + | </ | ||
| - | **Revisar esos ficheros es el trabajo humano del flujo.** Es mucho más barato corregir una frase de la spec que corregir el código que sale de ella. Qué mirar en cada uno: | + | <sxh plain; |
| + | server { | ||
| + | listen 80; | ||
| + | root / | ||
| - | ^ Fichero ^ Qué tiene que tener ^ | + | location /api/ { |
| - | | '' | + | |
| - | | '' | + | } |
| - | | '' | + | |
| - | Si se cambia algo en '' | + | location |
| + | try_files $uri $uri/ /index.html; | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| - | ==== /sdd spec impl ==== | + | El '' |
| - | Conversación nueva (''/ | + | ===== Producción |
| - | < | + | Docker Compose carga '' |
| - | /sdd spec impl | + | |
| - | </ | + | |
| - | Por dentro es '' | + | * '' |
| + | * '' | ||
| - | Solo implementa la spec. Lo que no viene de una spec (las correcciones de una revisión, un plan escrito a mano) se hace con ''/ | + | <sxh 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 | ||
| - | Por qué el ''/ | + | 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 | ||
| - | ==== La carpeta de la spec ==== | + | frontend: |
| + | build: ./ | ||
| + | environment: | ||
| + | VIRTUAL_HOST: | ||
| + | depends_on: | ||
| + | backend: | ||
| + | condition: service_healthy | ||
| + | networks: | ||
| + | - interna | ||
| + | - proxy | ||
| - | '' | + | volumes: |
| + | db-data: | ||
| - | Es un **registro** de lo que se pidió, no documentación: cuando el código cambie después, la spec no se actualiza. Para que el agente no se confunda con specs viejas, '' | + | networks: |
| + | interna: | ||
| + | proxy: | ||
| + | external: true | ||
| + | name: nginx-proxy-network | ||
| + | </ | ||
| - | < | + | Los '' |
| - | .kiro/ | + | |
| - | </ | + | |
| - | ==== La skill /sdd ==== | + | <sxh yaml; |
| + | services: | ||
| + | db: | ||
| + | ports: | ||
| + | - " | ||
| - | Es corta, porque el trabajo lo hacen los comandos de cc-sdd. Recibe el subcomando en '' | + | backend: |
| + | ports: | ||
| + | | ||
| + | environment: | ||
| + | SPRING_PROFILES_ACTIVE: | ||
| - | <sxh yaml;title:.claude/ | + | frontend: |
| - | --- | + | build: |
| - | name: sdd | + | target: build |
| - | description: | + | command: npx ng serve --host 0.0.0.0 --proxy-config proxy.conf.json |
| - | allowed-tools: | + | |
| - | --- | + | - ./frontend:/app |
| + | | ||
| + | ports: | ||
| + | - " | ||
| </ | </ | ||
| - | Todas las skills de tarea del proyecto son así: ''/< | + | Lo que cambia en desarrollo: |
| - | ===== El primer CRUD ===== | + | * **Se publican los puertos**, para entrar desde el navegador y para que Maven y Playwright lleguen a la base de datos y al frontend desde el host. |
| + | * **El frontend pasa a '' | ||
| + | * **El backend no tiene recarga en caliente**: cada cambio en Java es '' | ||
| + | * **Datos de prueba** activados (abajo). | ||
| - | La práctica central del tema es el primer CRUD del proyecto, hecho con '' | + | <note important> |
| - | Se resuelve con el primer CRUD y solo con él: se genera la spec, y en '' | + | ===== Un compose |
| - | ===== El steering: las dos arquitecturas ===== | + | Dos worktrees con el mismo '' |
| - | Para que el segundo CRUD salga igual que el primero **de verdad**, con las mismas capas, los mismos nombres y los mismos tests, no basta con pedirlo bien: el agente tiene que tener la arquitectura escrita y leerla antes de diseñar. Eso es el // | + | <sxh bash;title:.env> |
| + | COMPOSE_PROJECT_NAME=mi-proyecto-12-alta-clientes | ||
| + | DB_PORT=33112 | ||
| + | BACKEND_PORT=8112 | ||
| + | FRONTEND_PORT=4212 | ||
| + | DB_PASSWORD=dev | ||
| + | </sxh> | ||
| - | ==== Cuándo | + | * '' |
| + | * Los puertos los busca ''/ | ||
| + | * Las variables llevan valor por defecto, '' | ||
| - | ''/ | + | ''/ |
| - | < | + | ===== La primera tabla ===== |
| - | / | + | |
| - | </ | + | |
| - | Los tres ficheros que genera, '' | + | 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): |
| - | ==== Dos arquitecturas, dos ficheros ==== | + | * Dependencias '' |
| + | * Una migración '' | ||
| + | * Un '' | ||
| - | Lo específico de cada parte no va en esos tres, sino en dos ficheros de steering | + | El esquema |
| - | <sxh plain; | + | ===== Datos de prueba ===== |
| - | --- | + | |
| - | inclusion: fileMatch | + | |
| - | fileMatchPattern: | + | |
| - | --- | + | |
| - | # Arquitectura del servidor | + | |
| - | ... | + | |
| - | </ | + | |
| - | Y '' | + | Cada worktree arranca |
| - | ^ '' | + | < |
| - | | Las capas '' | + | backend/src/main/resources/db/ |
| - | | Nombres: '' | + | ├── migration/ <- esquema: V1__clientes.sql, V2__pedidos.sql ... |
| - | | Dónde se valida (Bean Validation en el '' | + | └── datos-prueba/ <- datos: R__clientes.sql, R__pedidos.sql ... |
| - | | Migraciones '' | + | </code> |
| - | | Cómo se prueban los unitarios: JUnit 5 y Mockito, sin Spring | '' | + | |
| - | La lección: | + | Los de '' |
| - | ==== Las skills de convenciones ==== | + | <sxh plain; |
| + | spring.flyway.locations=classpath: | ||
| + | </ | ||
| - | El steering solo lo leen los comandos de cc-sdd. Las demás skills del proyecto ('' | + | * En desarrollo el perfil |
| + | * En producción | ||
| + | * Para volver al estado inicial | ||
| - | <sxh yaml;title: | + | Cada entidad nueva trae su '' |
| - | --- | + | |
| - | name: convenciones-backend | + | |
| - | description: | + | |
| - | --- | + | |
| - | Lee .kiro/ | + | |
| - | </ | + | |
| - | Y '' | + | ===== El script app.sh ===== |
| - | ===== El contexto | + | Operar la aplicación es siempre lo mismo y no necesita ninguna inteligencia, |
| - | El contexto es todo lo que el modelo tiene delante en una conversación: '' | + | <sxh bash;title:app.sh> |
| + | # | ||
| + | # 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 | ||
| + | </ | ||
| - | | + | * '' |
| - | * **El modelo bueno para especificar, | + | * '' |
| - | * **No pegar logs enteros.** Solo el error y las líneas | + | * '' |
| - | | + | * Trabaja sobre la carpeta en la que está y lee su '' |
| - | ===== MCP ===== | + | < |
| - | Dos servidores MCP y ninguno más (qué es un MCP: [[cursos: | + | ===== Dónde corren Maven y los tests ===== |
| - | | + | Las imágenes son de **ejecución**: el backend es un JRE sin Maven y el frontend |
| - | | + | |
| - | Se configuran con '' | + | ^ Qué ^ Dónde ^ Contra qué ^ |
| + | | '' | ||
| + | | '' | ||
| + | | '' | ||
| - | ===== Permisos | + | 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 |
| - | En el tema 2 se permitió lo básico. Para programar, el agente tiene que poder compilar, pasar tests y levantar la aplicación sin preguntar en cada paso. La lista de '' | + | ==== npm run ==== |
| - | * **Permitido**: | + | '' |
| - | * **Pregunta**: escribir ficheros fuera del worktree, '' | + | |
| - | * **Denegado**: | + | |
| - | En OpenCode, lo mismo en la clave '' | + | <sxh json; |
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Los dos scripts resetean | ||
| + | |||
| + | Esto va en '' | ||
| ===== Ejercicios ===== | ===== Ejercicios ===== | ||
| ==== Ejercicio 1 ==== | ==== Ejercicio 1 ==== | ||
| - | * Configura Context7 | + | * Crea un issue «Aplicación en Docker» e inícialo con ''/ |
| - | * Comprueba que funcionan: pide al agente la forma actual de declarar una ruta en Angular | + | * Pide al agente los dos '' |
| - | * Completa | + | * Añade '' |
| + | * '' | ||
| + | * Entra en '' | ||
| ==== Ejercicio 2 ==== | ==== Ejercicio 2 ==== | ||
| - | * Crea un issue «Skill /sdd» e inícialo con ''/ | + | * En el mismo worktree, pide al agente que añada JPA, MariaDB y Flyway, la migración '' |
| - | * Instala cc-sdd en la raíz del repositorio | + | * Crea '' |
| - | * Escribe la skill '' | + | * '' |
| - | * Añade a '' | + | * Arranca con '' |
| + | * Cambia un texto de la página de Angular, guarda y comprueba que el navegador se recarga solo. | ||
| ==== Ejercicio 3 ==== | ==== Ejercicio 3 ==== | ||
| - | * Crea un issue para la primera entidad de tu proyecto | + | * Añade a '' |
| - | * '' | + | * Escribe en '' |
| - | * Lee '' | + | * ''/ |
| - | * '' | + | |
| - | * Prueba la aplicación en la URL del worktree: listado, alta, edición, borrado | + | |
| - | * Lee el código generado clase por clase y corrígelo: es la referencia de todos los CRUD que vienen después. | + | |
| ==== Ejercicio 4 ==== | ==== Ejercicio 4 ==== | ||
| - | * En el mismo worktree, lanza '' | + | * Escribe |
| - | * Con '' | + | * Amplía |
| - | * Escribe | + | * Finaliza el issue. |
| - | * '' | + | |
| - | * ''/ | + | ==== Ejercicio 5 ==== |
| - | * Mira '' | + | * Crea dos issues cualesquiera, |
| + | * Cambia los datos de prueba | ||
| + | * Finaliza los dos y comprueba con '' | ||
clase/daw/daw-proyecto/tema04.1791974081.txt.gz · Última modificación: por claude
