Files
sf-sim/docs/superpowers/specs/2026-05-06-base-backend-scaffold-design.md
Jorge 3186b438c0 docs(specs): añadir spec del scaffold base-backend
Diseño aprobado para extraer un scaffold genérico (esqueleto mínimo +
config de Claude Code) a ~/code/ref/base-backend, usado como punto de
partida para futuros backends del mismo perfil arquitectónico.
2026-05-06 09:50:11 +02:00

11 KiB

Diseño — Scaffold base-backend

  • Fecha: 2026-05-06
  • Rama de origen: chore/claude-code-setup (sf-sim)
  • Destino: ~/code/ref/base-backend (repo independiente, git init)
  • Autor: Jorge

Contexto

Sf-sim es un monorepo TypeScript ESM con varios microservicios DDD/Hexagonal sobre RabbitMQ + Postgres. Una vez estabilizada la configuración de Claude Code en la rama chore/claude-code-setup (commits 9a5308c, b67d53c, 5e77619), se quiere extraer un scaffold genérico que sirva de punto de partida para futuros backends del mismo perfil arquitectónico.

El scaffold no debe arrastrar el dominio SIM (ICCID, NOS, Objenious) ni la infraestructura de mensajería/persistencia — solo el esqueleto del monorepo, el tooling y la configuración de agente.

Decisiones de diseño

Ya validadas con el usuario antes de escribir este spec.

# Decisión Elegido Alternativas descartadas
1 Alcance A — Esqueleto mínimo B (con shared genérico), C (stack completo con Docker/RabbitMQ/Postgres)
2 Documentación C — Híbrido A (genericizar todo), B (copiar tal cual)
3 git init + commit inicial
4 amqplib en _template Quitar Dejarla por si se usa después
5 Sección EVENTS-RABBITMQ del auditor Mantener Quitar
6 Carpeta aplication (typo) Pasar a application Mantener typo, dejarlo abierto

Alcance

Lo que incluye base-backend

base-backend/
├── .agents/
│   └── skills/sf-backend-architecture/    # copia íntegra + nota inicial
├── .claude/
│   ├── commands/                          # /audit, /check, /md-lint
│   ├── rules/
│   │   ├── code-style.md                  # genericizado
│   │   └── git-conventions.md             # genericizado
│   ├── skills/                            # symlink clean-ddd-hexagonal y demás
│   └── settings.local.json
├── packages/
│   └── _template/
│       ├── config/env/index.ts
│       ├── index.ts
│       ├── package.json                   # name "template", sin amqplib
│       ├── tsconfig.json
│       └── .env
├── docs/
│   └── superpowers/specs/                 # vacía, lista para nuevos specs
├── .editorconfig
├── .gitattributes
├── .gitignore
├── .yarnrc.yml
├── CLAUDE.md                              # genericizado
├── CONTRIBUTING.md                        # genericizado
├── README.md                              # nuevo
├── package.json                           # name "base-backend", workspaces
├── tsconfig.json
├── tsconfig.vitest.json
└── vitest.config.ts

Lo que NO se copia

  • deployment/ (Docker compose, Dockerfile.dev, migraciones).
  • imgs/ (diagrama diagrama-rabbit.png).
  • rabbitmq_plugins/.
  • Scripts build.local.sh, run.local.sh, stop.local.sh.
  • .understand-anything/ (knowledge graph generado para sf-sim).
  • skills-lock.json (decisión: regenerar al instalar superpowers en el nuevo repo).
  • yarn.lock (se regenera con yarn install al primer uso).
  • Todos los packages de packages/ excepto _template/.
  • docs/sim-api-documentation.html y docs/sim-objenious/* (específicos).

Cambios sobre archivos copiados

1. package.json (raíz)

  • name: "sf-sim""base-backend".
  • description: actualizar a "Monorepo backend TypeScript ESM con DDD/Hexagonal — base para servicios nuevos".
  • scripts: mantener dev, build, start, typecheck, lint, lint:fix, format, format:check, test.
  • Quitar script migrate y dependencia @sf-alvar/db-migrate (no hay migrations en el scaffold).
  • Mantener workspaces: ["packages/*"], packageManager: "yarn@4.x".

2. CLAUDE.md

Reescritura completa. Mantiene la espina dorsal arquitectónica; quita lo específico de SIM.

Mantiene:

  • Sección "Comandos" con yarn dev/build/start/typecheck/lint/format/test/vitest run.
  • ESM puro, imports .js aunque el archivo sea .ts, path aliases por servicio.
  • Arquitectura: monorepo de microservicios DDD/Hexagonal con domain/, application/, infrastructure/, config/.
  • Result<E, D> para fallos esperables, throw para invariantes rotas.
  • DI manual por constructor con objeto args: { dep1, dep2 }. Tipos apuntando al port, no al adapter.
  • Skill sf-backend-architecture y referencias.
  • @.claude/rules/code-style.md y @.claude/rules/git-conventions.md.

Quita:

  • Comandos relativos a Docker (./build.local.sh, ./run.local.sh, ./stop.local.sh).
  • Comando yarn migrate.
  • Bloque RabbitMQ (exchange, routing keys, retries, DLX, correlation_id, diagrama).
  • Listado de packages (sim-shared, sim-entrada-eventos, sim-consumidor-nos, sim-consumidor-objenious, sim-objenious-cron).
  • Mención al typo aplication (en base-backend será application).

Sustituye la lista de packages por:

packages/_template/ — plantilla oficial para servicios nuevos. Cópiala, renómbrala y desarrolla desde ahí.

3. .claude/rules/code-style.md

Quita la sección "Excepciones de este repo" entera. El base no tiene los pasivos legacy de sf-sim:

  • No hay cobertura ~12%: la regla TDD + 70% aplica desde el día 1 (estricta para código nuevo).
  • No existe sim-objenious-cron: no hay excepciones arquitectónicas que documentar.
  • Carpeta aplication: deja de ser excepción porque pasamos a application.

Resto del fichero se mantiene tal cual.

4. .claude/rules/git-conventions.md

Quita el bloque "Pull Requests" entero (Gitea self-hosted, reviewer Alvar San Martin, dominio savefamilygps.com). Sustituye por:

## Pull Requests

Adapta este apartado al hosting y revisor de tu proyecto (GitHub, GitLab, Gitea, etc.).

Mantiene reglas de branches y conventional commits.

5. CONTRIBUTING.md

Barrido para quitar:

  • Referencias a SIM, ICCID, RabbitMQ.
  • Reviewer concreto y dominio de email.
  • Comandos Docker locales.

Mantiene reglas generales de contribución (commits, PRs, code style).

6. README.md (nuevo)

Breve. Explica:

  • Qué es: monorepo backend TypeScript ESM con DDD/Hexagonal, yarn 4 workspaces.
  • Cómo arrancar: yarn install, yarn dev.
  • Cómo crear un servicio nuevo: copiar packages/_template/, renombrar.
  • Dónde mirar: CLAUDE.md, CONTRIBUTING.md, skill sf-backend-architecture.

7. packages/_template/package.json

  • name: "sim-template""template".
  • description: "Template de la estructura de archivos" → "Plantilla base para servicios del monorepo".
  • Quitar dependencias amqplib y @types/amqplib (decisión 4).
  • Path aliases (imports): mantener #adapters/*, #domain/*, #ports/*, #tests/*. Añadir #application/* (no estaba antes; refleja la corrección del typo en decisión 6).
  • Resto se mantiene.

8. .agents/skills/sf-backend-architecture/SKILL.md

Añadir bloque al inicio (tras el frontmatter):

Nota: esta skill describe el estilo arquitectónico originado en el repo sf-sim (RabbitMQ + Postgres + DDD/Hexagonal + EDA). Los ejemplos están escritos contra ese dominio (SIM/ICCID/Objenious). Cuando la apliques en un repo distinto, adapta los ejemplos al dominio e infraestructura concretos — la arquitectura subyacente sigue valiendo.

Las referencias en references/ (HOUSE-STYLE, CODE-STYLE, ANTI-PATTERNS, AUDIT-CHECKLIST, EVENTS-RABBITMQ) se copian sin tocar. La sección EVENTS-RABBITMQ del checklist del auditor se mantiene (decisión 5): si en el futuro se añade RabbitMQ al base-backend, la sección está disponible.

9. .gitignore

Verificar que no arrastra patrones específicos de sf-sim. Si los hay (poco probable; suele ser estándar node_modules/, dist/, .env), eliminarlos.

10. tsconfig.json (raíz)

Limpiar compilerOptions.paths. En sf-sim contiene una entrada hardcoded:

"paths": {
  "sim-consumidor-objenious": ["./packages/sim-consumidor-objenious/*"]
}

En base-backend esa entrada se elimina (deja paths: {} o se quita la clave entera). Resto del fichero se mantiene (composite, module: nodenext, outDir: dist, etc.).

11. tsconfig.vitest.json y vitest.config.ts

Se copian tal cual. Nota: tsconfig.vitest.json extiende ./tsconfig.app.json que no existe en sf-sim (es un bug latente del repo origen). No se corrige aquí — corregirlo es responsabilidad de quien arranque el primer proyecto si llega a usar vitest a nivel raíz; mientras tanto los tests por package siguen funcionando como en sf-sim.

12. application vs aplication

Donde la documentación o el código mencione aplication, sustituir por application. Lugares conocidos:

  • CLAUDE.md — la mención al typo se elimina (no se sustituye, deja de ser relevante).
  • .agents/skills/sf-backend-architecture/SKILL.md y referencias — buscar y sustituir.
  • .agents/skills/sf-backend-architecture/references/HOUSE-STYLE.md.
  • Comandos /audit y /check si lo mencionan.
  • packages/_template/ — añadir entrada #application/* en path aliases.

El plan de implementación cerrará con un grep -ri 'aplication' . en el repo nuevo para garantizar que no queda ninguna mención.

Proceso de implementación (resumen)

El plan detallado lo generará la skill writing-plans después de la aprobación de este spec. A alto nivel:

  1. Crear ~/code/ref/base-backend/ y subdirectorios.
  2. Copiar archivos seleccionados de sf-sim.
  3. Aplicar las modificaciones (puntos 1-10 de la sección anterior).
  4. git init en ~/code/ref/base-backend.
  5. yarn install para regenerar yarn.lock.
  6. Verificar que yarn typecheck y yarn lint pasan en el repo recién creado (típicamente vacío de errores en un scaffold).
  7. Commit inicial: chore: scaffold base-backend monorepo.

Verificación de aceptación

El scaffold se considera completo cuando:

  • ~/code/ref/base-backend existe como repo git con commit inicial.
  • yarn install desde la raíz se ejecuta sin errores.
  • yarn typecheck pasa (puede no haber código en _template/index.ts más allá del placeholder).
  • yarn lint pasa.
  • No quedan referencias literales a "sim", "ICCID", "Objenious", "NOS", "RabbitMQ", "Postgres" en CLAUDE.md, CONTRIBUTING.md, README.md ni en .claude/rules/* (las menciones en las skills/referencias son intencionales por la nota añadida).
  • No queda aplication como typo en ningún fichero del repo nuevo.
  • Ejecutar /audit o /check desde Claude Code en base-backend carga sin errores y aplica al repo limpio.

Fuera de alcance

  • Crear servicios reales en packages/. El scaffold solo trae _template.
  • Configurar CI (GitHub Actions, Gitea Actions, etc.). Lo decide quien arranque el primer proyecto.
  • Migraciones de BBDD, Docker compose, scripts locales. Aplazado a una futura ampliación si se quiere una variante "stack completo".
  • Push del scaffold a un remoto. El usuario lo decide cuando lo use.