Generar Reporte de PR / MR desde Diff a Develop
Esta skill define los pasos que debe seguir el agente para analizar los cambios de código realizados en la rama de funcionalidad actual contra la rama base (develop), y estructurar una descripción detallada para el Pull Request (GitHub) o Merge Request / Issue (GitLab) siguiendo la plantilla oficial.
Cuándo usar esta skill
- El usuario solicita reportar, documentar o generar la descripción del issue para GitLab sobre los cambios implementados en la rama.
- Se requiere comparar la rama actual de funcionalidad contra la rama base
develop.
Cuándo NO usar esta skill
- Generar checklist de pruebas para QA →
generate-qa-checklist
- Generar o actualizar CHANGELOG.md →
generate-changelog
- Code review técnico exhaustivo de la implementación →
nextjs-code-review
Metodología
Paso 1: Analizar cambios con Git
Obtén el nombre de la rama actual:
git branch --show-current
Resuelve la rama base y el merge-base (punto de divergencia). Usa develop; si no existe localmente, cae a origin/develop:
BASE="develop"
[ -z "$(git rev-parse --verify -q "$BASE")" ] && BASE="origin/develop"
MB="$(git merge-base "$BASE" HEAD)"
echo "BASE=$BASE MB=$MB"
Opcional: si querés que develop esté actualizado, corré git fetch origin develop antes de resolver el merge-base.
Compara la rama actual contra el merge-base, NO contra el puntero actual de develop (diff three-dot). Esto es crítico: si tu rama está desactualizada y otras ramas ya se mergearon a develop, git diff develop (two-dot) incluye cambios ajenos y el reporte parece decir que agregaste cosas que no agregaste.
git diff --stat "$BASE"...HEAD
git diff "$BASE"...HEAD
git diff "$BASE"...HEAD -M # con detección de renames (mover archivos)
El diff three-dot (A...B) compara B contra el merge-base de A y B: muestra SOLO los cambios propios de la rama.
Si el diff queda vacío, la rama no tiene cambios propios contra develop (ya fue mergeada o es ancestro): avisá al usuario en lugar de generar un reporte vacío.
Extrae los commits propios de la rama para informar el título y la descripción:
git log --oneline "$MB"..HEAD
A partir del diff (three-dot), identifica y clasifica:
- Archivos nuevos (creaciones): presta atención a utilities, tipos, interfaces, providers, modales nuevos.
- Archivos modificados: qué lógica cambió, qué tipos se corrigieron, qué bugs se resolvieron.
- Archivos eliminados o renombrados (usá el diff con
-M para distinguir renames de borrados+creados).
- Capas arquitectónicas tocadas: dominio, servicios, controladores, hooks, componentes UI, pages, providers, modelos, configuración.
- Bugs implícitos resueltos: busca cambios en comparaciones (
===), tipos (string vs objeto), guards, condicionales o lógica de negocio que sugieran un fix.
- Gaps o inconsistencias detectadas: código que no rompe pero queda incompleto, parsers que no leen todos los campos, métodos que no cubren casos nuevos, TODOs implícitos.
- Variables de entorno nuevas: claves que el diff introduce y que no existían en el merge-base (detalle en el Paso 1b).
Agrupa mentalmente los archivos por capa antes de escribir el reporte. Ejemplos de capas:
- Core — modelo de dominio / tipos / utilities
- Data layer — servicios, repositorios, hooks de data fetching
- Bug fixes en UI — componentes que corregían comportamiento incorrecto
- Consumidores actualizados — componentes que adoptan la nueva API interna
- Controllers / Services (backend)
- Configuración / Constants
Paso 1b: Detectar variables de entorno nuevas (stack-aware)
Las variables de entorno nuevas son la alerta de máxima prioridad del reporte: si no se crean en los ambientes, los servicios no arrancan o los builds rompen. Detectalas sobre el diff three-dot del Paso 1.
1b-0. Extracción automatizada con scripts/detect_env_vars.py (Recomendado)
Para automatizar por completo el escaneo stack-aware, la clasificación de criticidad, la detección de renames y el formateo de la tabla Markdown oficial, ejecutá el script de detección:
python scripts/detect_env_vars.py
(O si la skill está instalada en tu harness o entorno global: python ~/.gemini/config/skills/generate-pr-report/scripts/detect_env_vars.py)
Opciones útiles del script:
--base <rama>: Define la rama base de comparación (por defecto develop, con fallback automático a origin/develop o main).
--format json: Emite los resultados como JSON estructurado en caso de ser consumido por herramientas o subagentes.
--output <archivo>: Guarda la sección Markdown generada directamente en un archivo.
--diff-file <archivo>: Permite pasar un diff previo o usar - para procesar diffs desde stdin (git diff ... | python scripts/detect_env_vars.py --diff-file -).
El script entrega directamente la tabla Markdown lista para ser incluida en la sección 🚨 ACCIÓN REQUERIDA.
Si no cuentas con intérprete de Python en el entorno o necesitas validar manualmente los hallazgos, utiliza las siguientes pautas detalladas en los Pasos 1b-1 a 1b-3:
1b-1. Detecta el stack del repo (cómo se leen y configuran las env vars aquí)
Identifica la convención según package.json, estructura de carpetas o lenguaje:
| Stack |
Cómo se detecta |
Convención de env vars |
| Next.js |
dep next en package.json |
process.env.X (server) / NEXT_PUBLIC_X (client). Centralizado en config/envServer.ts / config/envClient.ts (schemas zod). .env/.env.example, ecosystem.config.js (PM2), docker-compose*.yml. |
| LoopBack 4 (backend, turner, cronjob, files…) |
deps @loopback/* en package.json |
process.env.MXM_* leídos en src/config/keys.ts y validados por src/config/env.ts (EnvLoader). Cada servicio en un subdirectorio con .env propio. |
| NestJS |
dep @nestjs/config en package.json |
process.env.* leídos vía ConfigModule.forRoot / configService.get. .env, docker-compose*.yml. |
| Go |
.go en la raíz / go.mod |
os.Getenv("X"). Configuración vía docker-compose*.yml, .gitlab-ci.yml o archivos config/*. |
| Vite |
dep vite en package.json |
import.meta.env.VITE_X (solo prefijo VITE_ se expone al client). |
Repo multi-servicio: si la raíz no tiene package.json propio sino subdirectorios con servicios (backend/, turner/, cronjob/, files/…), cada servicio tiene sus propias env vars y su .env. Anotá a qué servicio pertenece cada variable.
1b-2. Fuentes a escanear (sobre el diff three-dot)
- Archivos de entorno trackeados que cambiaron en el diff:
git diff "$BASE"...HEAD -- .env.example .env* docker-compose*.yml ecosystem.config.js .gitlab-ci.yml src/config
- En
docker-compose*.yml y ecosystem.config.js (PM2): fijate en bloques environment:, env_file:, env:.
- En
.gitlab-ci.yml: sección variables:.
- Referencias de código nuevas en el diff: escaneá la salida del diff three-dot en busca de
process.env.X, NEXT_PUBLIC_X, import.meta.env.VITE_X, os.Getenv("X").git diff "$BASE"...HEAD | grep -E "process\.env\.|NEXT_PUBLIC_|VITE_|os\.Getenv"
- LoopBack / config centralizada: compará
src/config/keys.ts y src/config/env.ts entre el merge-base y HEAD. Toda clave nueva que entre a keys.ts es validada por EnvLoader al boot (ver 1b-3).
- Detectá renames de claves: si el diff (o un commit del
git log "$MB"..HEAD) renombra una variable, compará las claves presentes en el merge-base vs HEAD. Patrón típico: una clave desaparece y aparece otra con el mismo prefijo/base (MXM_KEYCLOAK_FRONTEND_CLIENT_ID → MXM_KEYCLOAK_PUBLIC_CLIENT_ID). Un rename NO se descarta: requiere actualizar el nombre en el .env de todos los ambientes (el valor se reutiliza), y si la clave entra a keys.ts el servicio falla al boot mientras el .env tenga el nombre viejo.
- Descartá falsos positivos reales: variables de entorno comunes (
NODE_ENV, PWD, HOST, PORT), claves que se movieron entre archivos sin cambio de nombre (verificable comparando merge-base vs HEAD), y comentarios/strings que contengan el patrón sin ser uso real.
1b-3. Clasificá cada variable detectada
- Servicio / Archivo: subdirectorio del servicio (en repos multi-servicio) y el archivo donde se define o se lee (
turner/src/config/keys.ts, config/envClient.ts, docker-compose.yml, etc.).
- Tipo:
Server: process.env.*.
Client: NEXT_PUBLIC_* (Next.js) o VITE_* (Vite). Nota: NEXT_PUBLIC_* se inyecta en tiempo de build → requiere rebuild del frontend, no alcanza con recargar.
Renombrada: clave que ya existía en el merge-base y cambió de nombre (ej MXM_KEYCLOAK_FRONTEND_CLIENT_ID → MXM_KEYCLOAK_PUBLIC_CLIENT_ID). No se crea valor nuevo: se renombra la clave en el .env de todos los ambientes. Sigue siendo crítica si entra a keys.ts (el servicio no arranca con el nombre viejo).
- ¿Obligatoria?:
Sí — falla arranque: LoopBack, clave nueva en keys.ts → EnvLoader lanza excepción y el servicio no inicia. También cuando el código hace throw si la variable falta.
Sí — sin fallback: se usa process.env.X sin ?? valor ni default.
No — tiene default: hay ?? fallback, default en schema (zod .default(...)) o solo activa/desactiva una feature.
- Impacto si falta: qué rompe concretamente (servicio X no arranca, login roto, feature deshabilitada, build falla).
⚠️ .env suele estar en .gitignore y no aparece en el diff. El reporte debe recordar que la variable hay que crearla manualmente en el .env de cada servicio (dev / test / prod) además de cualquier .env.example, docker-compose*.yml o ecosystem.config.js (PM2) que se haya tocado en la rama.
Paso 2: Leer la Plantilla de GitLab
- Localiza y lee el archivo de plantilla del proyecto:
.gitlab/issue_templates/reporteTemplate.md
- Respeta la estructura y emojis de sección tal como están en la plantilla. Si la plantilla tiene secciones extra (ej: "Request de prueba", "Impacto funcional"), completalas también.
Paso 3: Completar las Secciones del Reporte
🚨 ACCIÓN REQUERIDA — Variables de entorno nuevas (si aplica)
Sección de máxima prioridad: va SIEMPRE primero, inmediatamente después del título. Si el Paso 1b detectó variables nuevas, esta sección es lo primero que debe leer quien despliega. Si las variables no se crean, los servicios no arrancan o los builds rompen (rompe todo el ecosistema).
⚠️ ACCIÓN REQUERIDA: crear las siguientes variables de entorno en los ambientes antes del deploy. Se detectaron como nuevas contra el merge-base de develop.
| Variable |
Servicio / Archivo |
Tipo |
¿Obligatoria? |
Impacto si falta |
MXM_KEY_TURNER |
turner/ — src/config/keys.ts |
Server |
Sí — falla arranque |
turner no inicia (EnvLoader lanza excepción) |
NEXT_PUBLIC_IFRAME_ANP |
config/envClient.ts |
Client |
Sí — sin fallback |
Home de ANP rompe; requiere rebuild del frontend |
- Variable: nombre exacto de la variable con backticks.
- Servicio / Archivo: subdirectorio del servicio en repos multi-servicio y el archivo donde se define o se lee.
- Tipo:
Server / Client (NEXT_PUBLIC_ / VITE_) / Renombrada.
- ¿Obligatoria?:
Sí — falla arranque (LoopBack: clave nueva en keys.ts validada por EnvLoader) / Sí — sin fallback / No — tiene default. Para Renombrada: Sí — renombrar en .env (el valor se reutiliza).
- Impacto si falta: qué rompe concretamente (servicio que no arranca, login roto, feature deshabilitada, build falla). Para
Renombrada: si el .env queda con el nombre viejo, el servicio lee undefined y falla.
- Si hay variables renombradas, agregá debajo de la tabla una línea que aclare: "la clave
Vieja se renombró a Nueva: actualizar el nombre en el .env de todos los ambientes (el valor se reutiliza)".
- Agregá una línea recordando que
.env suele estar gitignoreado: la variable hay que crearla a mano en el .env de cada servicio (dev/test/prod), además de actualizar .env.example, docker-compose*.yml o ecosystem.config.js si corresponde.
- Si no hay variables nuevas, omití la sección completa.
📌 Título del Issue
- Formato:
Tipo: Descripción concisa (ej: Feat:, Fix:, Refactor:, Chore:).
- Debe identificar la funcionalidad o corrección principal, no listar todos los archivos.
- Ejemplos buenos:
Refactor: representación de personas (children / entidad legal), Fix: protección de rutas por nivel y edad.
📝 Descripción
- Párrafo(s) de alto nivel explicando qué cambia y por qué (el motivo técnico o el problema que resolvía el estado anterior).
- Si había un problema de tipos, menciona el tipo incorrecto y el correcto.
- Si había un bug de comportamiento, menciona brevemente cuál era el síntoma.
- No listar archivos aquí.
🔎 Contexto adicional
- Lista los módulos afectados (no archivos individuales), por ejemplo:
associates, core, home, turns.
- Si hay un issue relacionado, menciona el número o indica N/A.
- Si hay documentación o una utility nueva que sirve de referencia central, mencionala con su path.
- Si aplica, el endpoint y método HTTP.
- Si el cambio tiene un frontend y un backend relacionados, mencionarlos con su rama.
🪜 Pasos para reproducir (si aplica)
- Si el diff resuelve uno o más bugs, describe los pasos exactos para reproducir el comportamiento previo al fix. Sé específico: qué pantalla, qué acción, qué ocurría.
- Si hay múltiples bugs, puedes numerarlos en bloques separados.
- Si no aplica (solo nueva funcionalidad): indica
N/A (nueva funcionalidad/refactorización).
✅ Resultado esperado
- Bullets técnicos y precisos de qué debe ocurrir tras aplicar los cambios.
- Menciona tipos, nombres de funciones, campos o comportamientos concretos cuando sea relevante.
- Ejemplos:
`user.owner` es un string consistente con la respuesta del API, `getOwnerInfo()` retorna `OwnerInfo | null` (no string vacío).
❌ Resultado actual (antes del fix)
- Si aplica: describe el estado roto antes del cambio. Menciona errores de tipo concretos, comportamientos incorrectos, casts forzados, comparaciones fallidas.
- Si no aplica: indica
N/A.
📎 Cambios realizados
Esta sección reemplaza y enriquece la sección "Evidencia" de la plantilla base cuando los cambios son de código.
- Organiza los cambios en tablas por capa arquitectónica, con el encabezado de la capa como subtítulo H3 (
### Nombre — descripción de capa).
- Cada tabla tiene dos columnas:
| Archivo | Cambio |.
- En
Archivo: solo el nombre relativo desde src/ o desde el módulo (sin path completo).
- En
Cambio: descripción concisa del cambio específico en ese archivo. Usa backticks para nombres de tipos, funciones o campos. Usa **Nuevo** si el archivo es creado desde cero.
- Si un cambio introduce un nuevo formato de string, protocolo o estructura de datos, agrégalo como bloque de código separado debajo de la tabla correspondiente.
- REGLA CRÍTICA: No incluyas el diff del código fuente en bruto. Las tablas describen conceptualmente qué cambió, no muestran el código.
Ejemplo de estructura de esta sección:
### Core — modelo de dominio
| Archivo | Cambio |
|---|---|
| `domain/UserInit.ts` | `owner: AssociatedPerson` → `owner: string` |
| `utils/parseOwnerString.ts` | **Nuevo**: `parseOwnerString`, `getOwnerInfo`, `buildOwnerString` |
### Data layer
| Archivo | Cambio |
|---|---|
| `services/updateRepresentAccount.ts` | Response type `{ status: boolean }` → `{ owner: string }` |
### Bug fixes en UI
| Archivo | Cambio |
|---|---|
| `RepresentSelectField.tsx` | Usa `child_id` (no `id`) para selección de hijos |
⚠️ Notas / Gaps detectados (si aplica)
Esta sección es opcional pero debe incluirse cuando el análisis del diff revela inconsistencias, deuda técnica o trabajo incompleto.
- Describe el gap de forma técnica: qué método, archivo o índice no fue actualizado y por qué importa.
- Aclara si rompe o no rompe algo actualmente.
- Indica si es algo a resolver en un issue futuro.
- Ejemplo:
renderOwner() en util.service.ts parsea el owner string pero solo lee hasta el índice 5. No extrae name/lastname (índices 6 y 7) que ahora escribe resolveChildOwner(). No rompe nada actualmente, pero es un gap si algún consumidor necesita esos campos.
🖥️ Entorno (si aplica)
- Stack: menciona el framework/lenguaje principal (ej:
Next.js (TypeScript), Node.js / TypeScript / LoopBack 4 / PostgreSQL / Redis).
- Rama: nombre de la rama obtenido en el Paso 1.
- Endpoint (si aplica): método + ruta.
- Base de datos / Migraciones: si hay cambios de esquema, colecciones o seeds.
- Servicios afectados (si es repo multi-servicio): subdirectorios tocados (ej:
backend/, turner/, cronjob/).
Paso 4: Generar el archivo del Reporte (Direct-to-Disk)
- Plantilla oficial: Utilizar la estructura definida en
templates/pr-report.template.md.
- Destino del reporte: Escribir el reporte completo en
.agents/reports/pr_<branch>.md (o en la raíz como reporte_issue.md) usando write_to_file.
- Markdown válido: Asegurarse de que el Markdown sea válido y renderice correctamente en GitLab/GitHub (las tablas deben tener la fila de separación
|---|---|).
- Prohibido el diff en bruto: No incluyas el diff en bruto en ninguna sección del archivo ni en la conversación.
- Reporte Sintético en Chat:
- Enlace/ruta al archivo generado (
.agents/reports/pr_<branch>.md).
- Título propuesto del PR y resumen de alto nivel.
- Alerta destacada si se detectaron variables de entorno nuevas.
Referencia: Estructura completa del reporte
# 📌 Tipo: Título descriptivo
> ⚠️ **ACCIÓN REQUERIDA:** variables de entorno nuevas — crear antes del deploy (si aplica).
## 🚨 ACCIÓN REQUERIDA — Variables de entorno nuevas (si aplica)
| Variable | Servicio / Archivo | Tipo | ¿Obligatoria? | Impacto si falta |
|---|---|---|---|---|
| `VAR` | servicio — archivo | Server/Client | Sí — falla arranque | qué rompe |
---
## 📝 Descripción
...
---
## 🔎 Contexto adicional
- **Módulos afectados**: ...
- **Rama**: ...
- **Issue relacionado**: ...
- **Documentación asociada**: ...
---
## 🪜 Pasos para reproducir (si aplica)
1. ...
---
## ✅ Resultado esperado
- ...
---
## ❌ Resultado actual (antes del fix)
- ...
---
## 📎 Cambios realizados
### Capa — descripción
| Archivo | Cambio |
|---|---|
| `archivo.ts` | Descripción del cambio |
---
## ⚠️ Notas / Gaps detectados (si aplica)
...
---
## 🖥️ Entorno
- **Stack**: ...
Reglas de lo que SÍ debe hacer
- Comparar la rama siempre usando diff three-dot (
"$BASE"...HEAD) contra el merge-base.
- Seguir estrictamente la plantilla de reporte de issue o PR sin omitir secciones obligatorias.
- Detectar y alertar con máxima prioridad cualquier variable de entorno nueva en la cabecera (usando
scripts/detect_env_vars.py).
- Agrupar los cambios lógicamente por capas arquitectónicas en tablas concisas.
- Escribir el reporte directamente a disco por defecto en
.agents/reports/pr_<branch>.md (o reporte_issue.md) con write_to_file.
- Reportar en el chat únicamente un resumen de 5 líneas con el enlace al archivo generado y variables de entorno bloqueantes.
Reglas de lo que NO debe hacer
- NO usar two-dot diff (
git diff <branch>) sin justificación para evitar contaminar con cambios de otras ramas.
- NO volcar código fuente en bruto ni diffs crudos dentro del reporte ni en el chat.
- NO omitir variables de entorno requeridas para el arranque o deploy de servicios.
- NO inventar justificaciones para cambios no sustentados en el diff.
Verificación
- Comprobar que el archivo se persistió correctamente en
.agents/reports/pr_<branch>.md (o reporte_issue.md).
- Validar que las variables de entorno nuevas identificadas estén debidamente documentadas al tope como alerta de bloqueo.
- Asegurar que no se haya filtrado código fuente en crudo dentro del reporte.
Al terminar
Confirmar la persistencia del reporte en .agents/reports/pr_<branch>.md. Sugerir al usuario: generate-qa-checklist para generar la checklist de casos de prueba correspondiente a los flujos modificados en la rama.
1---2name: generate-pr-report3description: Genera la descripción de PR/MR desde el diff contra develop usando three-dot diff y merge-base. Detecta env vars nuevas (Next.js, LoopBack, Nest, Go, Vite) con alertas críticas, agrupa cambios por capa arquitectónica y escribe a disco. Usar con "generar reporte de PR", "reporte de issue", "describir MR".4---56# Generar Reporte de PR / MR desde Diff a Develop78Esta skill define los pasos que debe seguir el agente para analizar los cambios de código realizados en la rama de funcionalidad actual contra la rama base (`develop`), y estructurar una descripción detallada para el Pull Request (GitHub) o Merge Request / Issue (GitLab) siguiendo la plantilla oficial.910## Cuándo usar esta skill11- El usuario solicita reportar, documentar o generar la descripción del issue para GitLab sobre los cambios implementados en la rama.12- Se requiere comparar la rama actual de funcionalidad contra la rama base `develop`.1314## Cuándo NO usar esta skill15- **Generar checklist de pruebas para QA** → `generate-qa-checklist`16- **Generar o actualizar CHANGELOG.md** → `generate-changelog`17- **Code review técnico exhaustivo de la implementación** → `nextjs-code-review`1819---2021## Metodología2223### Paso 1: Analizar cambios con Git24251. Obtén el nombre de la rama actual:26 ```bash27 git branch --show-current28 ```29302. Resuelve la rama base y el **merge-base** (punto de divergencia). Usa `develop`; si no existe localmente, cae a `origin/develop`:31 ```bash32 BASE="develop"33 [ -z "$(git rev-parse --verify -q "$BASE")" ] && BASE="origin/develop"34 MB="$(git merge-base "$BASE" HEAD)"35 echo "BASE=$BASE MB=$MB"36 ```37 *Opcional: si querés que `develop` esté actualizado, corré `git fetch origin develop` antes de resolver el merge-base.*38393. Compara la rama actual contra el **merge-base**, NO contra el puntero actual de `develop` (**diff three-dot**). Esto es crítico: si tu rama está desactualizada y otras ramas ya se mergearon a `develop`, `git diff develop` (two-dot) incluye cambios **ajenos** y el reporte parece decir que agregaste cosas que no agregaste.40 ```bash41 git diff --stat "$BASE"...HEAD42 git diff "$BASE"...HEAD43 git diff "$BASE"...HEAD -M # con detección de renames (mover archivos)44 ```45 *El diff three-dot (`A...B`) compara B contra el merge-base de A y B: muestra SOLO los cambios propios de la rama.*46 *Si el diff queda vacío, la rama no tiene cambios propios contra `develop` (ya fue mergeada o es ancestro): avisá al usuario en lugar de generar un reporte vacío.*47484. Extrae los commits propios de la rama para informar el título y la descripción:49 ```bash50 git log --oneline "$MB"..HEAD51 ```52535. A partir del diff (three-dot), identifica y clasifica:54 - **Archivos nuevos** (creaciones): presta atención a utilities, tipos, interfaces, providers, modales nuevos.55 - **Archivos modificados**: qué lógica cambió, qué tipos se corrigieron, qué bugs se resolvieron.56 - **Archivos eliminados o renombrados** (usá el diff con `-M` para distinguir renames de borrados+creados).57 - **Capas arquitectónicas tocadas**: dominio, servicios, controladores, hooks, componentes UI, pages, providers, modelos, configuración.58 - **Bugs implícitos resueltos**: busca cambios en comparaciones (`===`), tipos (`string` vs objeto), guards, condicionales o lógica de negocio que sugieran un fix.59 - **Gaps o inconsistencias detectadas**: código que no rompe pero queda incompleto, parsers que no leen todos los campos, métodos que no cubren casos nuevos, TODOs implícitos.60 - **Variables de entorno nuevas**: claves que el diff introduce y que no existían en el merge-base (detalle en el Paso 1b).61626. Agrupa mentalmente los archivos por capa antes de escribir el reporte. Ejemplos de capas:63 - Core — modelo de dominio / tipos / utilities64 - Data layer — servicios, repositorios, hooks de data fetching65 - Bug fixes en UI — componentes que corregían comportamiento incorrecto66 - Consumidores actualizados — componentes que adoptan la nueva API interna67 - Controllers / Services (backend)68 - Configuración / Constants6970---7172### Paso 1b: Detectar variables de entorno nuevas (stack-aware)7374Las variables de entorno nuevas son la alerta de máxima prioridad del reporte: si no se crean en los ambientes, los servicios no arrancan o los builds rompen. Detectalas sobre el **diff three-dot** del Paso 1.7576#### 1b-0. Extracción automatizada con `scripts/detect_env_vars.py` (Recomendado)7778Para automatizar por completo el escaneo stack-aware, la clasificación de criticidad, la detección de renames y el formateo de la tabla Markdown oficial, ejecutá el script de detección:7980```bash81python scripts/detect_env_vars.py82```83*(O si la skill está instalada en tu harness o entorno global: `python ~/.gemini/config/skills/generate-pr-report/scripts/detect_env_vars.py`)*8485Opciones útiles del script:86- `--base <rama>`: Define la rama base de comparación (por defecto `develop`, con fallback automático a `origin/develop` o `main`).87- `--format json`: Emite los resultados como JSON estructurado en caso de ser consumido por herramientas o subagentes.88- `--output <archivo>`: Guarda la sección Markdown generada directamente en un archivo.89- `--diff-file <archivo>`: Permite pasar un diff previo o usar `-` para procesar diffs desde stdin (`git diff ... | python scripts/detect_env_vars.py --diff-file -`).9091El script entrega directamente la tabla Markdown lista para ser incluida en la sección **🚨 ACCIÓN REQUERIDA**.9293Si no cuentas con intérprete de Python en el entorno o necesitas validar manualmente los hallazgos, utiliza las siguientes pautas detalladas en los Pasos 1b-1 a 1b-3:9495#### 1b-1. Detecta el stack del repo (cómo se leen y configuran las env vars aquí)9697Identifica la convención según `package.json`, estructura de carpetas o lenguaje:9899| Stack | Cómo se detecta | Convención de env vars |100|---|---|---|101| **Next.js** | dep `next` en `package.json` | `process.env.X` (server) / `NEXT_PUBLIC_X` (client). Centralizado en `config/envServer.ts` / `config/envClient.ts` (schemas zod). `.env`/`.env.example`, `ecosystem.config.js` (PM2), `docker-compose*.yml`. |102| **LoopBack 4** (backend, turner, cronjob, files…) | deps `@loopback/*` en `package.json` | `process.env.MXM_*` leídos en `src/config/keys.ts` y validados por `src/config/env.ts` (`EnvLoader`). Cada servicio en un subdirectorio con `.env` propio. |103| **NestJS** | dep `@nestjs/config` en `package.json` | `process.env.*` leídos vía `ConfigModule.forRoot` / `configService.get`. `.env`, `docker-compose*.yml`. |104| **Go** | `.go` en la raíz / `go.mod` | `os.Getenv("X")`. Configuración vía `docker-compose*.yml`, `.gitlab-ci.yml` o archivos `config/*`. |105| **Vite** | dep `vite` en `package.json` | `import.meta.env.VITE_X` (solo prefijo `VITE_` se expone al client). |106107**Repo multi-servicio**: si la raíz no tiene `package.json` propio sino subdirectorios con servicios (`backend/`, `turner/`, `cronjob/`, `files/`…), cada servicio tiene sus propias env vars y su `.env`. Anotá a qué servicio pertenece cada variable.108109#### 1b-2. Fuentes a escanear (sobre el diff three-dot)1101111. **Archivos de entorno trackeados** que cambiaron en el diff:112 ```bash113 git diff "$BASE"...HEAD -- .env.example .env* docker-compose*.yml ecosystem.config.js .gitlab-ci.yml src/config114 ```115 - En `docker-compose*.yml` y `ecosystem.config.js` (PM2): fijate en bloques `environment:`, `env_file:`, `env:`.116 - En `.gitlab-ci.yml`: sección `variables:`.1172. **Referencias de código nuevas** en el diff: escaneá la salida del diff three-dot en busca de `process.env.X`, `NEXT_PUBLIC_X`, `import.meta.env.VITE_X`, `os.Getenv("X")`.118 ```bash119 git diff "$BASE"...HEAD | grep -E "process\.env\.|NEXT_PUBLIC_|VITE_|os\.Getenv"120 ```1213. **LoopBack / config centralizada**: compará `src/config/keys.ts` y `src/config/env.ts` entre el merge-base y HEAD. Toda clave nueva que entre a `keys.ts` es validada por `EnvLoader` al boot (ver 1b-3).1224. **Detectá renames de claves**: si el diff (o un commit del `git log "$MB"..HEAD`) renombra una variable, compará las claves presentes en el merge-base vs HEAD. Patrón típico: una clave desaparece y aparece otra con el mismo prefijo/base (`MXM_KEYCLOAK_FRONTEND_CLIENT_ID` → `MXM_KEYCLOAK_PUBLIC_CLIENT_ID`). Un rename **NO se descarta**: requiere actualizar el nombre en el `.env` de todos los ambientes (el valor se reutiliza), y si la clave entra a `keys.ts` el servicio falla al boot mientras el `.env` tenga el nombre viejo.1235. **Descartá falsos positivos reales**: variables de entorno comunes (`NODE_ENV`, `PWD`, `HOST`, `PORT`), claves que se **movieron entre archivos sin cambio de nombre** (verificable comparando merge-base vs HEAD), y comentarios/strings que contengan el patrón sin ser uso real.124125#### 1b-3. Clasificá cada variable detectada126127- **Servicio / Archivo**: subdirectorio del servicio (en repos multi-servicio) y el archivo donde se define o se lee (`turner/src/config/keys.ts`, `config/envClient.ts`, `docker-compose.yml`, etc.).128- **Tipo**:129 - `Server`: `process.env.*`.130 - `Client`: `NEXT_PUBLIC_*` (Next.js) o `VITE_*` (Vite). *Nota: `NEXT_PUBLIC_*` se inyecta en tiempo de build → requiere rebuild del frontend, no alcanza con recargar.*131 - `Renombrada`: clave que ya existía en el merge-base y cambió de nombre (ej `MXM_KEYCLOAK_FRONTEND_CLIENT_ID` → `MXM_KEYCLOAK_PUBLIC_CLIENT_ID`). **No se crea valor nuevo: se renombra la clave en el `.env` de todos los ambientes.** Sigue siendo crítica si entra a `keys.ts` (el servicio no arranca con el nombre viejo).132- **¿Obligatoria?**:133 - `Sí — falla arranque`: LoopBack, clave nueva en `keys.ts` → `EnvLoader` lanza excepción y el servicio **no inicia**. También cuando el código hace `throw` si la variable falta.134 - `Sí — sin fallback`: se usa `process.env.X` sin `?? valor` ni default.135 - `No — tiene default`: hay `?? fallback`, default en schema (zod `.default(...)`) o solo activa/desactiva una feature.136- **Impacto si falta**: qué rompe concretamente (servicio X no arranca, login roto, feature deshabilitada, build falla).137138> ⚠️ **`.env` suele estar en `.gitignore`** y no aparece en el diff. El reporte debe recordar que la variable hay que crearla **manualmente** en el `.env` de cada servicio (dev / test / prod) además de cualquier `.env.example`, `docker-compose*.yml` o `ecosystem.config.js` (PM2) que se haya tocado en la rama.139140---141142### Paso 2: Leer la Plantilla de GitLab1431441. Localiza y lee el archivo de plantilla del proyecto:145 `.gitlab/issue_templates/reporteTemplate.md`1462. Respeta la estructura y emojis de sección tal como están en la plantilla. Si la plantilla tiene secciones extra (ej: "Request de prueba", "Impacto funcional"), completalas también.147148---149150### Paso 3: Completar las Secciones del Reporte151152#### 🚨 ACCIÓN REQUERIDA — Variables de entorno nuevas (si aplica)153**Sección de máxima prioridad: va SIEMPRE primero, inmediatamente después del título.** Si el Paso 1b detectó variables nuevas, esta sección es lo primero que debe leer quien despliega. Si las variables no se crean, los servicios no arrancan o los builds rompen (rompe todo el ecosistema).154155> ⚠️ **ACCIÓN REQUERIDA:** crear las siguientes variables de entorno en los ambientes antes del deploy. Se detectaron como nuevas contra el merge-base de `develop`.156157| Variable | Servicio / Archivo | Tipo | ¿Obligatoria? | Impacto si falta |158|---|---|---|---|---|159| `MXM_KEY_TURNER` | `turner/` — `src/config/keys.ts` | Server | Sí — falla arranque | `turner` no inicia (`EnvLoader` lanza excepción) |160| `NEXT_PUBLIC_IFRAME_ANP` | `config/envClient.ts` | Client | Sí — sin fallback | Home de ANP rompe; requiere rebuild del frontend |161162- **Variable**: nombre exacto de la variable con backticks.163- **Servicio / Archivo**: subdirectorio del servicio en repos multi-servicio y el archivo donde se define o se lee.164- **Tipo**: `Server` / `Client` (`NEXT_PUBLIC_` / `VITE_`) / `Renombrada`.165- **¿Obligatoria?**: `Sí — falla arranque` (LoopBack: clave nueva en `keys.ts` validada por `EnvLoader`) / `Sí — sin fallback` / `No — tiene default`. Para `Renombrada`: `Sí — renombrar en .env` (el valor se reutiliza).166- **Impacto si falta**: qué rompe concretamente (servicio que no arranca, login roto, feature deshabilitada, build falla). Para `Renombrada`: si el `.env` queda con el nombre viejo, el servicio lee `undefined` y falla.167- Si hay variables **renombradas**, agregá debajo de la tabla una línea que aclare: "la clave `Vieja` se renombró a `Nueva`: actualizar el nombre en el `.env` de todos los ambientes (el valor se reutiliza)".168- Agregá una línea recordando que `.env` suele estar gitignoreado: la variable hay que crearla a mano en el `.env` de cada servicio (dev/test/prod), además de actualizar `.env.example`, `docker-compose*.yml` o `ecosystem.config.js` si corresponde.169- Si no hay variables nuevas, omití la sección completa.170171#### 📌 Título del Issue172- Formato: `Tipo: Descripción concisa` (ej: `Feat:`, `Fix:`, `Refactor:`, `Chore:`).173- Debe identificar la funcionalidad o corrección principal, no listar todos los archivos.174- Ejemplos buenos: `Refactor: representación de personas (children / entidad legal)`, `Fix: protección de rutas por nivel y edad`.175176#### 📝 Descripción177- Párrafo(s) de alto nivel explicando **qué cambia** y **por qué** (el motivo técnico o el problema que resolvía el estado anterior).178- Si había un problema de tipos, menciona el tipo incorrecto y el correcto.179- Si había un bug de comportamiento, menciona brevemente cuál era el síntoma.180- No listar archivos aquí.181182#### 🔎 Contexto adicional183- Lista los **módulos** afectados (no archivos individuales), por ejemplo: `associates`, `core`, `home`, `turns`.184- Si hay un issue relacionado, menciona el número o indica N/A.185- Si hay documentación o una utility nueva que sirve de referencia central, mencionala con su path.186- Si aplica, el endpoint y método HTTP.187- Si el cambio tiene un frontend y un backend relacionados, mencionarlos con su rama.188189#### 🪜 Pasos para reproducir (si aplica)190- Si el diff resuelve uno o más bugs, describe los pasos exactos para reproducir el comportamiento **previo** al fix. Sé específico: qué pantalla, qué acción, qué ocurría.191- Si hay múltiples bugs, puedes numerarlos en bloques separados.192- Si no aplica (solo nueva funcionalidad): indica `N/A (nueva funcionalidad/refactorización)`.193194#### ✅ Resultado esperado195- Bullets técnicos y precisos de qué debe ocurrir tras aplicar los cambios.196- Menciona tipos, nombres de funciones, campos o comportamientos concretos cuando sea relevante.197- Ejemplos: `` `user.owner` es un string consistente con la respuesta del API ``, `` `getOwnerInfo()` retorna `OwnerInfo | null` (no string vacío) ``.198199#### ❌ Resultado actual (antes del fix)200- Si aplica: describe el estado roto **antes** del cambio. Menciona errores de tipo concretos, comportamientos incorrectos, casts forzados, comparaciones fallidas.201- Si no aplica: indica `N/A`.202203#### 📎 Cambios realizados204**Esta sección reemplaza y enriquece la sección "Evidencia" de la plantilla base cuando los cambios son de código.**205206- Organiza los cambios en **tablas por capa arquitectónica**, con el encabezado de la capa como subtítulo H3 (`### Nombre — descripción de capa`).207- Cada tabla tiene dos columnas: `| Archivo | Cambio |`.208 - En `Archivo`: solo el nombre relativo desde `src/` o desde el módulo (sin path completo).209 - En `Cambio`: descripción concisa del cambio específico en ese archivo. Usa backticks para nombres de tipos, funciones o campos. Usa `**Nuevo**` si el archivo es creado desde cero.210- Si un cambio introduce un nuevo formato de string, protocolo o estructura de datos, agrégalo como bloque de código separado debajo de la tabla correspondiente.211- **REGLA CRÍTICA:** No incluyas el diff del código fuente en bruto. Las tablas describen conceptualmente qué cambió, no muestran el código.212213Ejemplo de estructura de esta sección:214215```markdown216### Core — modelo de dominio217| Archivo | Cambio |218|---|---|219| `domain/UserInit.ts` | `owner: AssociatedPerson` → `owner: string` |220| `utils/parseOwnerString.ts` | **Nuevo**: `parseOwnerString`, `getOwnerInfo`, `buildOwnerString` |221222### Data layer223| Archivo | Cambio |224|---|---|225| `services/updateRepresentAccount.ts` | Response type `{ status: boolean }` → `{ owner: string }` |226227### Bug fixes en UI228| Archivo | Cambio |229|---|---|230| `RepresentSelectField.tsx` | Usa `child_id` (no `id`) para selección de hijos |231```232233#### ⚠️ Notas / Gaps detectados (si aplica)234**Esta sección es opcional pero debe incluirse cuando el análisis del diff revela inconsistencias, deuda técnica o trabajo incompleto.**235236- Describe el gap de forma técnica: qué método, archivo o índice no fue actualizado y por qué importa.237- Aclara si rompe o no rompe algo actualmente.238- Indica si es algo a resolver en un issue futuro.239- Ejemplo: `renderOwner() en util.service.ts parsea el owner string pero solo lee hasta el índice 5. No extrae name/lastname (índices 6 y 7) que ahora escribe resolveChildOwner(). No rompe nada actualmente, pero es un gap si algún consumidor necesita esos campos.`240241#### 🖥️ Entorno (si aplica)242- **Stack**: menciona el framework/lenguaje principal (ej: `Next.js (TypeScript)`, `Node.js / TypeScript / LoopBack 4 / PostgreSQL / Redis`).243- **Rama**: nombre de la rama obtenido en el Paso 1.244- **Endpoint** (si aplica): método + ruta.245- **Base de datos / Migraciones**: si hay cambios de esquema, colecciones o seeds.246- **Servicios afectados** (si es repo multi-servicio): subdirectorios tocados (ej: `backend/`, `turner/`, `cronjob/`).247248---249250### Paso 4: Generar el archivo del Reporte (Direct-to-Disk)2512521. **Plantilla oficial**: Utilizar la estructura definida en [`templates/pr-report.template.md`](./templates/pr-report.template.md).2532. **Destino del reporte**: Escribir el reporte completo en `.agents/reports/pr_<branch>.md` (o en la raíz como `reporte_issue.md`) usando `write_to_file`.2543. **Markdown válido**: Asegurarse de que el Markdown sea válido y renderice correctamente en GitLab/GitHub (las tablas deben tener la fila de separación `|---|---|`).2554. **Prohibido el diff en bruto**: No incluyas el diff en bruto en ninguna sección del archivo ni en la conversación.2565. **Reporte Sintético en Chat**:257 - Enlace/ruta al archivo generado (`.agents/reports/pr_<branch>.md`).258 - Título propuesto del PR y resumen de alto nivel.259 - Alerta destacada si se detectaron variables de entorno nuevas.260261---262263## Referencia: Estructura completa del reporte264265```markdown266# 📌 Tipo: Título descriptivo267268> ⚠️ **ACCIÓN REQUERIDA:** variables de entorno nuevas — crear antes del deploy (si aplica).269270## 🚨 ACCIÓN REQUERIDA — Variables de entorno nuevas (si aplica)271| Variable | Servicio / Archivo | Tipo | ¿Obligatoria? | Impacto si falta |272|---|---|---|---|---|273| `VAR` | servicio — archivo | Server/Client | Sí — falla arranque | qué rompe |274275---276277## 📝 Descripción278...279280---281282## 🔎 Contexto adicional283- **Módulos afectados**: ...284- **Rama**: ...285- **Issue relacionado**: ...286- **Documentación asociada**: ...287288---289290## 🪜 Pasos para reproducir (si aplica)2911. ...292293---294295## ✅ Resultado esperado296- ...297298---299300## ❌ Resultado actual (antes del fix)301- ...302303---304305## 📎 Cambios realizados306307### Capa — descripción308| Archivo | Cambio |309|---|---|310| `archivo.ts` | Descripción del cambio |311312---313314## ⚠️ Notas / Gaps detectados (si aplica)315...316317---318319## 🖥️ Entorno320- **Stack**: ...321```322323---324325## Reglas de lo que SÍ debe hacer326327- Comparar la rama siempre usando diff three-dot (`"$BASE"...HEAD`) contra el merge-base.328- Seguir estrictamente la plantilla de reporte de issue o PR sin omitir secciones obligatorias.329- Detectar y alertar con máxima prioridad cualquier variable de entorno nueva en la cabecera (usando `scripts/detect_env_vars.py`).330- Agrupar los cambios lógicamente por capas arquitectónicas en tablas concisas.331- Escribir el reporte directamente a disco por defecto en `.agents/reports/pr_<branch>.md` (o `reporte_issue.md`) con `write_to_file`.332- Reportar en el chat únicamente un resumen de 5 líneas con el enlace al archivo generado y variables de entorno bloqueantes.333334## Reglas de lo que NO debe hacer335336- NO usar two-dot diff (`git diff <branch>`) sin justificación para evitar contaminar con cambios de otras ramas.337- NO volcar código fuente en bruto ni diffs crudos dentro del reporte ni en el chat.338- NO omitir variables de entorno requeridas para el arranque o deploy de servicios.339- NO inventar justificaciones para cambios no sustentados en el diff.340341## Verificación342343- Comprobar que el archivo se persistió correctamente en `.agents/reports/pr_<branch>.md` (o `reporte_issue.md`).344- Validar que las variables de entorno nuevas identificadas estén debidamente documentadas al tope como alerta de bloqueo.345- Asegurar que no se haya filtrado código fuente en crudo dentro del reporte.346347## Al terminar348349Confirmar la persistencia del reporte en `.agents/reports/pr_<branch>.md`. Sugerir al usuario: **generate-qa-checklist** para generar la checklist de casos de prueba correspondiente a los flujos modificados en la rama.