Skip to content

Lab: Workspace Angular + Laravel

Documento vivo. Este guión se va completando y ajustando conforme avanza la implementación real. Las secciones marcadas con [por definir] se actualizarán con las decisiones reales del equipo.

Paso a paso para construir, desde cero, un workspace bien configurado con:

  • Un proyecto Angular (Signals, standalone-first)
  • Un proyecto Laravel (API-first)
  • Repos de frontend y backend como git submodules del workspace raíz
  • copilot-instructions.md global al workspace
  • Instrucciones específicas por repo (path-specific)
  • Angular CLI MCP Server y contexto AI oficial de Angular
  • Laravel Boost para dar al agente contexto específico del proyecto
  • Agentes Planner, Coder y Reviewer adaptados al stack
  • Hooks de formato activos
  • Docker para PostgreSQL
  • Makefile para gestionar el entorno
  • Verificación end-to-end

Estos son los pasos exactos que se siguen durante la configuración. Cada uno se detalla más abajo.

#PasoDescripción
0Grupo GitLabCrear grupo de GitLab con los repos: estimai-workspace, estimai-front, estimai-back
1WorkspaceCrear proyecto workspace con README desde GitLab y clonarlo en local
2Angular CLIInstalar Angular CLI: pnpm install -g @angular/cli
3Proyecto AngularCrear proyecto: ng new estimai-front --package-manager pnpm (Tailwind + AI config para Copilot). Levantar y verificar
4Push AngularSubir proyecto Angular a GitLab (repo separado)
5Proyecto LaravelCrear proyecto sin starter kit, con Pest para testing y Boost para agentes AI. Driver PostgreSQL. Aceptar configuraciones de Boost
6Push LaravelSubir al repo
7Docker PostgreSQLPreparar entorno Docker para PostgreSQL
8MakefilePreparar Makefile para gestionar el repo
9Verificar stackLevantar Docker con make docker-up, ejecutar make migrate, arrancar Laravel con make dev y comprobar
10Push cambiosSubir cambios a ambos repos
11Limpiar localEliminar directorios front y back en local
12SubmodulesAbrir el workspace y añadir los dos repos como submódulos
13Configuración IAPreparar Makefile, PLAN.md, README.md, instrucciones IA, skills, etc. PLAN.md prepara .PLAN/ con fases atómicas para agentes
14VSCode configAñadir mcp.json, settings.json, etc.

Crear un grupo en GitLab que contendrá los tres repositorios del proyecto:

grupo-estimai/
├── estimai-workspace ← repo raíz con submodulos
├── estimai-front ← repo Angular
└── estimai-back ← repo Laravel

Esto permite gestionar permisos, CI/CD y variables de entorno a nivel de grupo.


Crear el proyecto estimai-workspace desde GitLab con README (para que el repo no esté vacío) y clonarlo en local:

Terminal window
git clone <url-grupo>/estimai-workspace.git
cd estimai-workspace

Terminal window
pnpm install -g @angular/cli

Verificar la instalación:

Terminal window
ng version

Terminal window
ng new estimai-front --package-manager pnpm

El wizard interactivo preguntará por estilos y SSR. Seleccionar Tailwind para estilos. Configurar la parte de AI para GitHub Copilot cuando el wizard lo pregunte.

Levantar y verificar:

Terminal window
cd estimai-front
pnpm start
# http://localhost:4200

Comprobar que el proyecto compila y se ve correctamente en el navegador.

Standalone es el default desde Angular v20. No añadir standalone: true en los decoradores — ya está asumido por el framework.


Crear el repo estimai-front en el grupo de GitLab y subir:

Terminal window
cd estimai-front
git remote set-url origin <url-grupo>/estimai-front.git
git push -u origin main

Crear el proyecto Laravel sin starter kit, con Pest para testing, configurando Boost para mejorar agentes AI y el driver para PostgreSQL:

Terminal window
laravel new estimai-back

Durante el wizard:

  • Starter kit: None
  • Testing framework: Pest
  • Database: PostgreSQL

Instalar Laravel Boost:

Terminal window
cd estimai-back
composer require laravel/boost --dev
php artisan boost:install

Aceptar todas las configuraciones de Boost:

  • ✅ AI guidelines
  • ✅ Agent skills
  • ✅ Boost MCP server configuration

Boost detecta automáticamente el IDE y los agentes activos. Los archivos de guía personalizados del equipo van en .ai/guidelines/*.md.


Terminal window
cd estimai-back
git remote set-url origin <url-grupo>/estimai-back.git
git push -u origin main

Preparar un docker-compose.yml en el directorio del backend (o en el workspace, según se prefiera):

services:
postgres:
image: postgres:17
container_name: estimai-postgres
environment:
POSTGRES_DB: estimai
POSTGRES_USER: estimai
POSTGRES_PASSWORD: estimai
ports:
- '5432:5432'
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:

Configurar el .env de Laravel para apuntar a este contenedor:

DB_CONNECTION=pgsql
DB_HOST=127.0.0.1
DB_PORT=5432
DB_DATABASE=estimai
DB_USERNAME=estimai
DB_PASSWORD=estimai

Crear un Makefile para gestionar el entorno de forma cómoda:

.PHONY: docker-up docker-down dev migrate fresh test
docker-up:
docker compose up -d
docker-down:
docker compose down
dev:
cd estimai-back && composer run dev
migrate:
cd estimai-back && php artisan migrate
fresh:
cd estimai-back && php artisan migrate:fresh --seed
test:
cd estimai-back && php artisan test
front:
cd estimai-front && pnpm start

Terminal window
make docker-up # Levantar PostgreSQL
make migrate # Ejecutar migraciones
make dev # Arrancar Laravel en http://localhost:8000

Comprobar:

  • PostgreSQL responde en el puerto 5432
  • Las migraciones se ejecutan sin errores
  • Laravel arranca correctamente
  • El frontend (si aún está en local) sigue funcionando en el puerto 4200

Subir los cambios a ambos repos (docker-compose, Makefile, configuración Boost, etc.):

Terminal window
cd estimai-back && git add . && git commit -m "feat: docker + makefile + boost config" && git push
cd ../estimai-front && git add . && git commit -m "feat: initial angular setup" && git push

Eliminar los directorios de front y back en local. Los vamos a recuperar como submódulos en el siguiente paso:

Terminal window
rm -rf estimai-front estimai-back

Abrir el workspace (estimai-workspace) y añadir los dos repos como git submodules:

Terminal window
cd estimai-workspace
git submodule add <url-grupo>/estimai-front.git estimai-front
git submodule add <url-grupo>/estimai-back.git estimai-back
git commit -m "feat: add front and back as submodules"
git push

Verificar:

Terminal window
git submodule status

En otra máquina, al clonar:

Terminal window
git clone --recurse-submodules <url-grupo>/estimai-workspace.git
# o si ya está clonado sin submodulos
git submodule update --init --recursive

Paso 13 — Configuración IA del workspace

Section titled “Paso 13 — Configuración IA del workspace”

Con el workspace montado y los submódulos funcionando, es hora de configurar todo lo relacionado con IA: instrucciones, agentes, prompts, skills y el PLAN.md inicial.

estimai-workspace/
.vscode/
mcp.json
settings.json
.github/
copilot-instructions.md
instructions/
agents/
prompts/
.PLAN/ ← cada fase detallada y atómica
fase-01-setup.md
fase-02-auth.md
...
PLAN.md ← plan general del proyecto
README.md
Makefile
estimai-front/ ← git submodule
estimai-back/ ← git submodule

El PLAN.md inicial del proyecto NO es el plan completo — es el plan para preparar el directorio .PLAN/ donde cada fase está bien detallada y atómica para poder ser ejecutada de forma independiente por un agente.

# PLAN.md — EstimAI
## Objetivo
Preparar el directorio `.PLAN/` con las fases del proyecto.
Cada fase debe ser un archivo markdown independiente, lo suficientemente
detallado y atómico para que un agente pueda ejecutarlo sin contexto adicional.
## Fases previstas
1. Setup completo del entorno (Docker, migraciones, seeds)
2. Autenticación y autorización (Sanctum + guards Angular)
3. [definir con el equipo]
4. [definir con el equipo]
## Reglas para cada fase
- Cada fichero en `.PLAN/` es autocontenido
- Incluye: objetivo, ficheros afectados, acceptance criteria, tests esperados
- Un agente debe poder ejecutar la fase sin preguntas

Angular ofrece archivos de contexto oficiales para LLMs. Descargar en el workspace:

Terminal window
# Descargar best-practices.md oficial de Angular para Copilot
curl -o .github/instructions/angular-best-practices.instructions.md \
https://angular.dev/assets/context/best-practices.md

Este archivo contiene las reglas oficiales para que los modelos generen código Angular idiomático: componentes standalone, Signals, control flow nativo, input()/output() functions, etc.

Angular también publica contexto completo para LLMs en:

  • https://angular.dev/llms.txt — índice de documentación
  • https://angular.dev/assets/context/llms-full.txt — contexto completo

Instrucciones que aplican a todos los ficheros del workspace. Van en .github/copilot-instructions.md.

# Instrucciones globales del workspace
## Stack
- Frontend: Angular v21 (standalone-first, Signals, OnPush) — en /frontend
- Backend: Laravel 13 (API-first, PHP 8.1+) — en /backend
- Base de datos: [por definir]
- CI/CD: GitLab CI/CD
- Control de versiones: GitLab self-hosted
## Idioma y formato
- Comentarios en código: español
- Mensajes de commit: inglés, formato conventional commits (feat:, fix:, refactor:, etc.)
- Nombres de variables, funciones y clases: inglés
## Angular — reglas clave
- Standalone es el default desde v20 — NO escribir `standalone: true` en los decoradores
- Usar `input()` y `output()` en vez de `@Input()` y `@Output()`
- Control flow nativo: `@if`, `@for`, `@switch` — no `*ngIf`, `*ngFor`, `*ngSwitch`
- Estado reactivo con `signal()`, `computed()`, `effect()` — no BehaviorSubject en componentes
- ChangeDetectionStrategy.OnPush en todos los componentes
- Inyección con `inject()` — no constructor injection
## Laravel — reglas clave
- Controllers solo orquestan: sin lógica de negocio
- Form Requests para toda validación
- Policies para toda autorización
- JsonResource para transformar modelos
- Códigos HTTP semánticos
## Reglas absolutas
- No generar credenciales, tokens, contraseñas ni datos personales reales
- No modificar ficheros de entorno (.env) directamente
- No hacer DROP ni TRUNCATE sin confirmación explícita
- No usar `console.log` ni `dd()` en código de producción

Estado: [borrador — ajustar con convenciones reales del equipo]


Cada instrucción se activa solo para los ficheros que coinciden con applyTo.

Angular — .github/instructions/angular.instructions.md

Section titled “Angular — .github/instructions/angular.instructions.md”
---
applyTo: 'frontend/src/**/*.ts'
---
## Componentes Angular
- Standalone por defecto desde v20 — NO escribir `standalone: true` en el decorador @Component.
- `ChangeDetectionStrategy.OnPush` en todos los componentes.
- Inyección con `inject()`, no constructor injection.
- Host bindings: usar `host: {}` en el decorador en vez de `@HostBinding`/`@HostListener`.
## Inputs y outputs
- Usar las funciones `input()` y `output()` — no los decoradores `@Input()`/`@Output()`.
- Input opcional: `input<Tipo | undefined>(undefined)`.
- Input requerido: `input.required<Tipo>()`.
## Control flow
- Nativo: `@if`, `@for`, `@switch` — nunca `*ngIf`, `*ngFor`, `*ngSwitch`.
- `@for` requiere `track`: `@for (item of items; track item.id)`.
## Estado reactivo
- `signal()` para estado local del componente.
- `computed()` para valores derivados.
- `effect()` solo para side effects — no para derivar estado.
- No `BehaviorSubject` para estado de componente.
## Naming
- Selector: kebab-case (app-user-card)
- Clase: PascalCase (UserCardComponent)
- Signals: camelCase (userCount, isLoading)

Laravel — .github/instructions/laravel.instructions.md

Section titled “Laravel — .github/instructions/laravel.instructions.md”
---
applyTo: 'backend/app/**/*.php'
---
## Controllers Laravel
- Solo orquestan: reciben request, llaman servicio/action, devuelven respuesta.
- Máximo 10-15 líneas por método.
- Sin lógica de negocio en el controller.
## Validación
- Form Requests para toda validación. Nunca validate() en el controller.
## Autorización
- Policies para toda autorización. Nunca can()/authorize() suelto en el controller.
## Respuestas API
- JsonResource para transformar modelos. No devolver el modelo directamente.
- Estructura consistente: { data, meta?, errors? }
- Códigos HTTP semánticos: 201 para creación, 204 para delete, 422 para validación.
## Arquitectura
[por definir — Services, Actions, o patrón propio del equipo]

Tests — .github/instructions/tests.instructions.md

Section titled “Tests — .github/instructions/tests.instructions.md”
---
applyTo: '**/*.spec.ts,**/tests/**/*.php,**/*Test.php'
---
## Tests Angular
- Framework: [por definir — Karma/Jest/Vitest]
- Estructura: Arrange / Act / Assert explícito con comentarios.
- No testear implementación interna. Testear comportamiento observable.
- Un solo assert conceptual por test.
## Tests Laravel
- PHPUnit con factories y Faker para datos.
- RefreshDatabase en tests que tocan base de datos.
- No usar base de datos de desarrollo para tests.
- Naming: test_[nombre_en_snake_case]_[condicion]_[resultado_esperado]

Estado: [borrador — ajustar con el equipo]


Los tres agentes base. Se localizan en .github/agents/ y son compartidos para ambos proyectos.

Planner — .github/agents/planner.agent.md

Section titled “Planner — .github/agents/planner.agent.md”
---
name: Planner
description: Analiza un ticket o requisito y genera un plan de implementación detallado para el stack Angular + Laravel antes de escribir código
tools:
- codebase
- fetch
- search
---
Eres un arquitecto de software senior especializado en Angular y Laravel.
Tu función es PLANIFICAR, nunca implementar.
Cuando recibas un requisito:
1. Analiza los ficheros relevantes del workspace actual con codebase
2. Lista los ficheros que habrá que crear o modificar
3. Describe el cambio en cada fichero (sin código, solo descripción)
4. Identifica dependencias entre cambios y el orden correcto
5. Señala riesgos o ambigüedades que el dev debe resolver antes de implementar
No escribas código. No edites ficheros. Solo el plan.
Al final pregunta: "¿Apruebas este plan para que Coder lo implemente?"
---
name: Coder
description: Implementa el plan generado por Planner siguiendo las convenciones del stack Angular + Laravel
tools:
- codebase
- edit_file
- create_file
- run_command
- fetch
---
Eres un desarrollador senior de Angular y Laravel.
Tu función es IMPLEMENTAR el plan que Planner ha generado y el dev ha aprobado.
Reglas:
- Sigue el plan al pie de la letra. Si necesitas desviarte, para y consulta.
- Aplica todas las instrucciones del workspace (copilot-instructions.md y path-specific).
- Un fichero a la vez. Verifica que compila antes de pasar al siguiente.
- Añade tests al mismo tiempo que el código de producción — no al final.
- Si encuentras un problema no previsto en el plan, para y describe la situación.
Al terminar: resume qué has cambiado y qué debe revisar el dev antes de pasar a Reviewer.

Reviewer — .github/agents/reviewer.agent.md

Section titled “Reviewer — .github/agents/reviewer.agent.md”
---
name: Reviewer
description: Revisa el diff antes del MR — convenciones, seguridad OWASP básica, tests presentes y calidad del código
tools:
- codebase
- fetch
---
Eres un revisor de código senior especializado en Angular y Laravel.
Tu función es REVISAR el diff del trabajo de Coder antes de que llegue a revisión humana.
Checklist obligatorio:
- [ ] Se aplican las convenciones de `copilot-instructions.md`
- [ ] Se aplican las instrucciones por tipo de fichero (Signals en Angular, Form Requests en Laravel)
- [ ] Hay tests para el código nuevo
- [ ] No hay credenciales, tokens ni datos sensibles hardcodeados
- [ ] No hay `console.log` ni `dd()` en código de producción
- [ ] Validación OWASP básica: no SQL injection, no XSS en templates, inputs validados
- [ ] Los nombres son descriptivos y consistentes con el resto del proyecto
Formato de respuesta:
- Lista de problemas encontrados con severidad (bloqueante / sugerencia)
- Lista de cosas que están bien
- Veredicto: APROBADO / APROBADO CON SUGERENCIAS / BLOQUEADO

Estado: [borrador — ajustar con el equipo]



Paso 14 — Configuración VSCode (MCPs, hooks, settings)

Section titled “Paso 14 — Configuración VSCode (MCPs, hooks, settings)”

MCPs a configurar en .vscode/mcp.json. En VS Code la clave raíz es "servers" (no "mcpServers").

MCPPara quéPrioridad
Angular CLI MCPConsultar docs Angular, ejemplos y mejores prácticas desde el agenteAlta
GitLabMRs, issues, logs de pipeline desde el agenteAlta
PlaywrightTests E2E generados y ejecutados por el agenteAlta
PostgreSQL / MySQLExplorar esquema y datos directamenteMedia
FigmaGenerar componentes Angular desde frame de diseñoMedia

Configuración .vscode/mcp.json:

{
"servers": {
"angular-cli": {
"command": "npx",
"args": ["-y", "@angular/cli", "mcp"]
},
"gitlab": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-gitlab"],
"env": {
"GITLAB_PERSONAL_TOKEN": "${env:GITLAB_TOKEN}",
"GITLAB_API_URL": "[URL del GitLab del equipo]"
}
},
"playwright": {
"command": "npx",
"args": ["@playwright/mcp@latest"]
},
"postgres": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres", "[connection_string]"]
}
}
}

Herramientas del Angular CLI MCP:

HerramientaDescripción
ai_tutorTutoría interactiva sobre Angular
find_examplesBusca ejemplos de código en la documentación
get_best_practicesObtiene las mejores prácticas oficiales
search_documentationBusca en la documentación oficial
list_projectsLista los proyectos del workspace
onpush_zoneless_migrationAsiste en migración a OnPush/Zoneless
build (experimental)Ejecuta ng build
test (experimental)Ejecuta ng test
devserver.start/stop (experimental)Controla el servidor de desarrollo

Para habilitar herramientas experimentales: añadir -E <nombre> a los args del MCP.

Estado: [pendiente — rellenar connection strings y URL de GitLab]


Hooks activos durante toda la sesión del agente. Se configuran en .vscode/settings.json del workspace o en .github/ según la versión de Copilot.

PostToolUse — formato automático tras cada edición

Section titled “PostToolUse — formato automático tras cada edición”
{
"github.copilot.chat.agent.hooks": {
"postToolUse": [
{
"tool": "edit_file",
"condition": "file matches 'frontend/**/*.ts'",
"command": "npx prettier --write ${file}"
},
{
"tool": "edit_file",
"condition": "file matches 'backend/**/*.php'",
"command": "php-cs-fixer fix ${file}"
}
]
}
}

PreToolUse — bloquear operaciones destructivas

Section titled “PreToolUse — bloquear operaciones destructivas”
{
"github.copilot.chat.agent.hooks": {
"preToolUse": [
{
"tool": "run_command",
"block": ["php artisan migrate:fresh", "php artisan db:wipe", "DROP TABLE", "TRUNCATE"],
"message": "Operación destructiva bloqueada. Requiere confirmación explícita del dev."
}
]
}
}

Estado: [pendiente — verificar sintaxis exacta con la versión de Copilot instalada]



Checklist para confirmar que el workspace está correctamente configurado:

Estructura y submodules:

  • git submodule status muestra frontend y backend apuntando a los commits correctos
  • git submodule update --init funciona sin errores en una máquina nueva

Instrucciones:

  • /init ejecutado sobre el workspace — copilot-instructions.md generado y ajustado
  • En Ask mode: “¿Qué stack usa este proyecto?” → responde Angular v21 + Laravel 13 correctamente
  • El agente usa signal() al generar un componente Angular (no BehaviorSubject)
  • El agente NO añade standalone: true al generar un componente Angular
  • El agente usa input() en vez de @Input() al generar un componente Angular
  • El agente usa Form Request al generar un controller Laravel (no $request->validate())

Agentes:

  • Los 3 agentes aparecen en el picker de VS Code
  • Planner genera un plan sin escribir código
  • Coder implementa el plan de Planner
  • Reviewer detecta al menos un problema intencionado en un diff de prueba

MCPs:

  • Angular CLI MCP: get_best_practices responde con reglas de Angular v21
  • GitLab MCP: el agente puede listar los MRs abiertos
  • Playwright MCP: el agente puede abrir el navegador y navegar a localhost:4200
  • PostgreSQL MCP: el agente puede describir el esquema de la base de datos

Hooks:

  • Editar un .ts con formato incorrecto → Prettier lo corrige automáticamente
  • El agente edita un .php → PHP CS Fixer se ejecuta automáticamente

Flujo completo:

  • Feature real de prueba: Planner → Coder → Reviewer → MR listo en GitLab

SecciónEstado
Pasos 0–12 — Setup completo del stackDocumentado
Paso 13 — Configuración IA (instrucciones, agentes, PLAN)Borrador — ajustar con el equipo
Paso 14 — VSCode config (MCPs, hooks)Borrador — pendiente connection strings
copilot-instructions.md globalBorrador — ajustar con convenciones reales
Instructions AngularBorrador — pendiente convenciones reales
Instructions LaravelBorrador — pendiente convenciones reales
Instructions TestsBorrador — pendiente framework de tests
AgentesBorrador — pendiente ajuste con el equipo
MCPs (incl. Angular CLI MCP)Borrador — pendiente connection strings
HooksBorrador — pendiente verificar sintaxis exacta
VerificaciónLista — ejecutar al final