Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 17 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,12 @@ captura por una corrida en verde._
- **Credenciales:** secrets del repositorio (`DOCKERHUB_USERNAME`, `DOCKERHUB_TOKEN`, `RENDER_DEPLOY_HOOK_URL`); nunca
en el código.

**Notas sobre Render.** El servicio tiene `autoDeploy` apagado: los deploys salen únicamente por el deploy hook, que
pasa `imgURL` con el tag exacto de la release. Por eso el campo de imagen en Settings puede mostrar un tag viejo
(`v0.1.0`), ya que cada deploy por hook lo sobreescribe; la fuente de verdad es la lista de deploys, donde el activo
es `v0.3.0`. Al ser el plan Free, el servicio se duerme por inactividad y el primer request posterior tarda unos 40 s
(cold start).

### 2. Justificación Técnica y Decisiones de Diseño

#### Gestión de Cambios (Commits, Ramas y PRs)
Expand All @@ -137,6 +143,12 @@ fix(auth): corregir validación de token expirado
ci: add e2e job to pull request checks
```

**Excepciones conocidas.** Tres commits de los inicios del proyecto no cumplen el formato: `9b8bc41`
(`chroe: init nestjs project`, typo de `chore`) y dos commits `Revert "..."` generados por `git revert`
(`066f1db`, que revierte el anterior, y `e0ad9be`, que revierte un `feat(users)`). Pertenecen a `main`, y reescribir
su historial para corregirlos rompería los hashes ya referenciados por PRs y tags, así que se dejaron como están;
todo commit posterior sigue la convención.

Un cambio incompatible hacia atrás se marca con `!` después del tipo/scope (ej.
`feat!: cambiar formato de respuesta de la API`) o con un footer `BREAKING CHANGE:`. Eso es lo que habilita derivar
el incremento SemVer del historial en lugar de decidirlo a mano (ver
Expand Down Expand Up @@ -263,18 +275,18 @@ llegan a la imagen final.
- **Manejo de señales:** Node.js no fue diseñado para correr como proceso PID 1 (no
reacciona correctamente a `SIGTERM`/`SIGINT`), según la misma guía oficial. En vez de
agregar un binario extra (`tini`/`dumb-init`) a la imagen, se usa `init: true` en el
`docker-compose.yml`, que le pide a Docker que envuelva el proceso con su init liviano
`docker-compose.yaml`, que le pide a Docker que envuelva el proceso con su init liviano
incorporado.

**Evidencia:** las imágenes publicadas son `linux/amd64`. `v0.1.0` pesa 61.32 MB, `v0.2.0` 70.12 MB y `v0.3.0` (la que
corre en producción) 79.61 MB comprimida en Docker Hub — el crecimiento viene de las dependencias de OpenTelemetry
**Evidencia:** las imágenes publicadas son `linux/amd64`. `v0.1.0` pesa 61.32 MiB, `v0.2.0` 70.12 MiB y `v0.3.0` (la
que corre en producción) 79.61 MiB comprimida (Docker Hub las muestra en MB decimales: 64.3, 73.5 y 83.5) — el crecimiento viene de las dependencias de OpenTelemetry
agregadas entre releases.

<!-- dockerhub-tag-detalle.png: captura pendiente de agregar (detalle del tag v0.3.0: linux/amd64, tamaño) -->

#### Orquestación Local

`docker-compose.yml` con un único servicio (`api`) que construye la imagen desde el
`docker-compose.yaml` con un único servicio (`api`) que construye la imagen desde el
Dockerfile y expone el puerto 3000. Permite levantar el entorno completo con
`docker compose up --build`.

Expand Down Expand Up @@ -495,5 +507,5 @@ _Borrador — a revisar y completar con la evidencia final._
2. **Defectos detectados tarde.** `ci.yml` corre lint y tests en cada Pull Request, y el mismo CI se vuelve a ejecutar
sobre el tag antes de publicar (`needs: ci`), de modo que un defecto se frena antes de llegar al registro.
3. **Retrabajo por diferencias de entorno.** Un `Dockerfile` multi-stage con base pineada, usado igual en local y en
CI, evita el "en mi máquina funciona"; además la imagen final es liviana (61.32 MB comprimida), lo que reduce la
CI, evita el "en mi máquina funciona"; además la imagen final es liviana (61.32 MiB comprimida en `v0.1.0`), lo que reduce la
transferencia en cada publicación y despliegue.
75 changes: 61 additions & 14 deletions docs/estado-del-proyecto.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ Checklist de seguimiento contra las fases de la consigna. **No es el entregable*

## Fase 2 — Gestión de Cambios y Versionado

- [x] Conventional Commits en todo el historial
- [x] Conventional Commits en todo el historial, salvo 3 commits iniciales (`9b8bc41` con typo `chroe` y dos
`Revert`) → [Excepciones conocidas](../README.md#gestión-de-cambios-commits-ramas-y-prs)
- [x] Branching vía GitHub Flow + protección de `main` + PRs documentados con template
→ [Gestión de Cambios](../README.md#gestión-de-cambios-commits-ramas-y-prs)
- [x] Estrategia de versionado definida (SemVer) → [Estrategia de Versionado](../README.md#estrategia-de-versionado)
Expand Down Expand Up @@ -44,8 +45,8 @@ Checklist de seguimiento contra las fases de la consigna. **No es el entregable*
→ [Observabilidad](../README.md#observabilidad-opentelemetry--grafana-cloud)
- [ ] **Dashboard propio (sin plantillas)** — las vistas de Application Observability vienen prearmadas; sirven para
confirmar que llegan datos, pero el dashboard entregable hay que construirlo desde cero
- [ ] **Golden Signals: tráfico, latencia, errores** — la métrica base ya se emite
(`http.server.request.duration`, histograma con `http.route` y `http.response.status_code`); falta construir los
- [ ] **Golden Signals: tráfico, latencia, errores** — la métrica base ya se emite (`http.server.request.duration`,
histograma con `http.route` y `http.response.status_code`); falta construir los
paneles

## Pendientes del informe
Expand All @@ -54,18 +55,64 @@ Checklist de seguimiento contra las fases de la consigna. **No es el entregable*
variable de entorno faltante) y documentar cómo reaccionó el pipeline o el monitoreo.
- [ ] **Principios Lean** — sección en borrador, falta completar con la evidencia final.

## Plan de trabajo (por prioridad)

Orden pensado por peso en la rúbrica (Observabilidad 25 %, CI/CD 30 %, Docker 25 %, Cambios 20 %) y por dependencias:
las capturas van al final porque dependen de que lo demás exista.

1. [ ] **Dashboard propio + Golden Signals** (Fase 5). Es lo único obligatorio que falta construir. En Grafana Cloud
hoy no hay ningún dashboard propio, solo los de la plataforma.
2. [ ] **Experimento de falla controlada** (Tercera Forma). Genera además la evidencia `falla-controlada-1.png`.
3. [ ] **Principios Lean** y cierre de la Segunda/Tercera Forma con la evidencia real.
4. [ ] **Capturas** de la tabla de abajo.
5. [ ] **Cierre:** commitear y abrir PR de esta documentación, y limpieza de ramas (ver Housekeeping).

## Decisiones tuyas pendientes

Cada una trae una recomendación; ninguna bloquea el plan de arriba.

- [ ] **Alerta sobre 5xx o latencia alta.** La consigna pregunta qué herramienta lo detecta y mediante qué señal. Hoy
hay métrica pero no hay alerta. *Recomendación:* una regla simple de Grafana sobre 5xx, una vez construido el
dashboard; refuerza la Segunda Forma y sirve para el experimento de falla.
- [ ] **Centralizar logs en Grafana (Loki) o dejarlos en stdout.** *Recomendación:* dejarlos en stdout, ya cumple la
consigna y evita complejidad.
- [ ] **Automatizar la creación del tag SemVer.** Hoy es manual (`git tag` + `git push`) y el README lo reconoce.
*Recomendación:* dejarlo manual y declararlo como limitación; la consigna no exige automatizarlo.
- [ ] **Actualizar dependencias antes de entregar.** Hay versiones menores nuevas (NestJS 12.0.1 → 12.2.0, oxlint,
vitest, prettier). *Recomendación:* no tocarlas ahora; cada cambio exige una release nueva y revalidar el pipeline.
- [ ] **Renombrar el workspace de Render** ("My Workspace" es el nombre por defecto). Cosmético; solo importa si
aparece en una captura del informe.

## Antes de la demo y la defensa

- [ ] **Despertar Render unos minutos antes.** El plan Free duerme el servicio; el primer request tardó ~42 s.
- [ ] **Generar tráfico sobre la API** para que el dashboard tenga datos recientes (incluyendo algunos 404 y 400).
- [ ] **Saber explicar el `imagePath` de Render.** En Settings el servicio muestra `v0.1.0`, pero cada deploy por hook
sobreescribe la imagen con el tag exacto de la release. La fuente de verdad es la lista de deploys (Events), donde
el activo es `v0.3.0`.
- [ ] **Saber explicar los 3 commits que no siguen Conventional Commits** (ver README, "Excepciones conocidas").
- [ ] **No citar el tamaño de una imagen construida en local.** Pesa ~449 MB descomprimida y es `arm64`; las publicadas
son `linux/amd64` y pesan ~80 MB comprimidas.

## Housekeeping

- [ ] Actualizar `main` local (está atrás de `origin/main`) y borrar las ramas ya mergeadas, locales y remotas (hay unas
20, incluida `docs/update-readme-status`). No hay PRs ni issues abiertos.
- [ ] Rama `docs/note-commit-convention-exceptions` con cambios sin commitear (README y este archivo): falta
commitear con `docs: ...` y abrir el PR.

## Imágenes pendientes

Van en `docs/images/`; los nombres deben coincidir con las referencias del informe.

| Archivo | Estado | Qué debe mostrar |
|---|---|---|
| `pipeline-release.png` | ⚠️ desactualizada | Muestra la corrida fallida de `v0.1.0` (Deploy to Render en rojo). Reemplazar por una corrida `Release` completa en verde (ideal: la de `v0.3.0`) |
| `dockerhub-tags.png` | ⚠️ desactualizada | Solo muestra `v0.1.0`. Reemplazar por una que incluya `v0.2.0` y `v0.3.0` |
| `pr-checks.png` | ❌ falta | Pull Request con los checks de CI (Lint, Unit tests y E2E tests) en verde |
| `branch-protection.png` | ❌ falta | Settings > Branches: protección de `main` con los status checks requeridos |
| `dockerhub-tag-detalle.png` | ❌ falta | Detalle de `v0.3.0` (linux/amd64, tamaño) |
| `render-servicio.png` | ❌ falta | Servicio en Render corriendo la imagen `v0.3.0` |
| `render-deploy-hook.png` | ❌ falta | Deploy disparado por el hook (eventos / log) |
| `monitoreo-dashboard.png` | ❌ falta | Dashboard propio con las Golden Signals |
| `falla-controlada-1.png` | ❌ falta | Evidencia del experimento de falla controlada |
| Archivo | Estado | Qué debe mostrar |
|-----------------------------|-------------------|---------------------------------------------------------------------------------------------------------------------------------------------------|
| `pipeline-release.png` | ⚠️ desactualizada | Muestra la corrida fallida de `v0.1.0` (Deploy to Render en rojo). Reemplazar por una corrida `Release` completa en verde (ideal: la de `v0.3.0`) |
| `dockerhub-tags.png` | ⚠️ desactualizada | Solo muestra `v0.1.0`. Reemplazar por una que incluya `v0.2.0` y `v0.3.0` |
| `pr-checks.png` | ❌ falta | Pull Request con los checks de CI (Lint, Unit tests y E2E tests) en verde |
| `branch-protection.png` | ❌ falta | Settings > Branches: protección de `main` con los status checks requeridos |
| `dockerhub-tag-detalle.png` | ❌ falta | Detalle de `v0.3.0` (linux/amd64, tamaño) |
| `render-servicio.png` | ❌ falta | Servicio en Render corriendo la imagen `v0.3.0` |
| `render-deploy-hook.png` | ❌ falta | Deploy disparado por el hook (eventos / log) |
| `monitoreo-dashboard.png` | ❌ falta | Dashboard propio con las Golden Signals |
| `falla-controlada-1.png` | ❌ falta | Evidencia del experimento de falla controlada |
Loading