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.
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 |
Sí | — |
| 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/(diagramadiagrama-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 conyarn installal primer uso).- Todos los packages de
packages/excepto_template/. docs/sim-api-documentation.htmlydocs/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: mantenerdev,build,start,typecheck,lint,lint:fix,format,format:check,test.- Quitar script
migratey 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
.jsaunque 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,throwpara invariantes rotas.- DI manual por constructor con objeto
args: { dep1, dep2 }. Tipos apuntando al port, no al adapter. - Skill
sf-backend-architecturey referencias. @.claude/rules/code-style.mdy@.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(enbase-backendserá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 aapplication.
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, skillsf-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
amqpliby@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.mdy referencias — buscar y sustituir..agents/skills/sf-backend-architecture/references/HOUSE-STYLE.md.- Comandos
/audity/checksi 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:
- Crear
~/code/ref/base-backend/y subdirectorios. - Copiar archivos seleccionados de sf-sim.
- Aplicar las modificaciones (puntos 1-10 de la sección anterior).
git initen~/code/ref/base-backend.yarn installpara regeneraryarn.lock.- Verificar que
yarn typecheckyyarn lintpasan en el repo recién creado (típicamente vacío de errores en un scaffold). - Commit inicial:
chore: scaffold base-backend monorepo.
Verificación de aceptación
El scaffold se considera completo cuando:
~/code/ref/base-backendexiste como repo git con commit inicial.yarn installdesde la raíz se ejecuta sin errores.yarn typecheckpasa (puede no haber código en_template/index.tsmás allá del placeholder).yarn lintpasa.- 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
aplicationcomo typo en ningún fichero del repo nuevo. - Ejecutar
/audito/checkdesde Claude Code enbase-backendcarga 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.