Saltar a contenido

Contribuir

Esta página explica cómo se trabaja en el repositorio camarero-ia: la estructura de monorepo con submódulos, las dos fuentes de conocimiento tribal (AGENTS.md), el proceso obligatorio de findings, los gates de CI y el criterio de cierre de tarea "0 findings nuevos vs baseline".

Está pensada tanto para personas como para agentes LLM que vayan a tocar el código. Lee primero esta página y luego la how-to concreta de tu tarea (tests, migraciones, módulo nuevo o contrato).


El repositorio: monorepo con submódulos

El repo raíz es un monorepo que organiza el código mediante Git submodules. Los dos componentes principales viven cada uno en su propio submódulo:

Directorio Qué es Stack
backend/ API FastAPI (submódulo) FastAPI · Python 3.12 · SQLAlchemy 2.0 async · PostgreSQL · NVIDIA NIM
frontend/ App web (submódulo) Next.js 16 · React 19 · TypeScript · Tailwind CSS 4
docs/ Documentación del sistema —
scripts/ Scripts de deploy y seeding —
nginx/ Configuración de nginx —

Clonado

Como backend/ y frontend/ son submódulos, hay que inicializarlos explícitamente:

# Opción A: clonar con submódulos en un paso
git clone --recurse-submodules https://github.com/user/camarero-ia.git
cd camarero-ia

# Opción B: clonar y luego inicializar
git clone https://github.com/user/camarero-ia.git
cd camarero-ia
git submodule init
git submodule update

Arranque local:

cp .env.example .env
make setup
make dev

Backend y frontend viajan juntos

Cualquier cambio en el contrato (OpenAPI / SSE) que el backend expone debe llevar, en el mismo cambio, el cableado en el frontend que consume lo nuevo. Nunca un campo de contrato nuevo sin su consumo en el front. Ver Contrato.


Conocimiento tribal: los dos AGENTS.md

El repo mantiene dos ficheros AGENTS.md (uno por submódulo) que capturan conocimiento tribal: los matices no obvios que marcan la diferencia entre un arreglo rápido y horas de depuración.

  • backend/AGENTS.md — patrones reales del backend (hexagonal, multitenancy, precios en céntimos, i18n, state machine de comanda, arquitectura híbrida del chat, convenciones de naming/type-safety/complejidad…).
  • frontend/AGENTS.md — particularidades del frontend.

backend/CLAUDE.md referencia a AGENTS.md

backend/CLAUDE.md simplemente incluye @AGENTS.md (más unas reglas de docstrings). La fuente de verdad del backend es backend/AGENTS.md; léelo antes de tocar código.

Cuándo añadir a AGENTS.md

Añade una entrada cuando ocurra algo de alta señal:

  • El usuario tuvo que intervenir, corregir o llevarte de la mano.
  • Hicieron falta varios intentos de ida y vuelta para que algo funcionara.
  • Descubriste algo que requirió leer muchos ficheros para entenderlo.
  • Un cambio tocó ficheros que no habrías adivinado.
  • Algo se comportó de forma distinta a lo esperado.
  • El usuario lo pide explícitamente.

Propón la adición de forma proactiva cuando pase cualquiera de las anteriores; no esperes a que te lo pidan.

Qué NO añadir

Cosas que se deducen leyendo unos pocos ficheros, patrones obvios o prácticas estándar. AGENTS.md debe ser de alta señal, no exhaustivo.


Proceso de findings

Ante cualquier bug, lógica rara o deuda técnica detectada durante una tarea, se documenta un finding:

docs/findings/{YYYY-MM-DD}-{task}-{slug}.md

Ejemplos reales en el repo: docs/findings/2026-06-03-reg02-session-timeout.md, docs/findings/2026-06-07-ci-arch01-baseline-red.md.

Si no hubo nada, déjalo explícito

Al cerrar una tarea, si no se detectó ninguna deuda, escribe de forma explícita "Findings: ninguno." en el cierre. La ausencia de findings es una afirmación, no un olvido.

Un finding no es solo un bug a arreglar ahora: también sirve para dejar constancia de comportamientos que parecen un error pero son intencionados (p. ej. SESSION_TIMEOUT_MINUTES = 600 es la ventana de jornada completa del restaurante, no un timeout de inactividad), de modo que la siguiente persona no los "arregle" por error.


Gates de CI

El workflow .github/workflows/ci.yml corre en push/PR a feature/new-arch y main. Hay tres gates duros y un job e2e no bloqueante:

Gate Comando ¿Bloquea el merge?
Arquitectura (ADR-004) make lint-arch Sí
Type-safety make typecheck No (no-bloqueante mientras el baseline tenga errores pre-existentes)
Contrato pytest tests/contract/ Sí
e2e testcontainers No (baseline rojo GAP-2)

make lint-arch — arquitectura (ADR-004)

Usa import-linter para hacer cumplir ADR-004: sin imports cross-module directos; la comunicación entre módulos va solo vía puertos o eventos de dominio. HTTPException solo en interface/. Código compartido en app/shared.

Hay un hook local equivalente en .pre-commit-config.yaml; instálalo:

pre-commit install

make typecheck — type-safety (no bloqueante)

mypy está cableado (mypy.ini + make typecheck), pero el gate no bloquea en la práctica mientras el baseline arrastre errores pre-existentes (ver docs/findings/2026-06-07-ci-arch01-baseline-red.md). Aun así, la convención es normativa para código nuevo: X | None en vez de Optional[X], colecciones parametrizadas, sin Any en la API pública de use cases y repos.

pytest tests/contract/ — contrato (intocable salvo adiciones)

Bloquea el merge ante cualquier cambio no aditivo del contrato hacia el frontend. La regla dura: tests/contract/openapi_snapshot.json solo puede CRECER en paths nuevos; cualquier removal, rename o type-change de campos existentes requiere sign-off explícito del owner (rompe clientes desplegados). Las adiciones aditivas sí se permiten —editar el contrato, regenerar el snapshot y cablear el frontend en el mismo cambio—. Detalle en Contrato.


Criterio de cierre: "0 findings nuevos vs baseline"

El indicador de que una tarea está lista para mergear no es que uvicorn main:app levante (durante la migración hexagonal la app puede estar rota a propósito), sino:

  1. Los gates duros de CI pasan: make lint-arch + pytest tests/contract/.
  2. Los tests del módulo afectado pasan: pytest tests/{modulo}/e2e/.
  3. 0 findings nuevos vs baseline: el cambio no introduce findings nuevos de arquitectura/contrato respecto al estado base. Si aparece deuda nueva, se documenta como finding (o se arregla); si no apareció nada, se cierra con "Findings: ninguno."

Baseline rojo aceptado

Algunos gates parten de un baseline rojo conocido (typecheck, e2e). "0 findings nuevos" significa no empeorar ese baseline, no exigir que esté en verde.


How-to relacionadas