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:
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:
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:
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:
- Los gates duros de CI pasan:
make lint-arch+pytest tests/contract/. - Los tests del módulo afectado pasan:
pytest tests/{modulo}/e2e/. - 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.