Initial commit: sap-intercompany-api

Backend NestJS + Prisma, dueno de la configuracion del worker
(databases, scenarios, scenario_destinations, value_mappings) y
lectura de webhook_events / replication_attempts.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
GeorgeandClaude Sonnet 5 committed 2026-09-16 07:51:03 -05:00
commit 2e92523641
25 files changed
+4707

No files matched your search

+71
View File
@@ -0,0 +1,71 @@
# sap-intercompany-api
Backend HTTP (NestJS) dueño de toda la configuración de
[`sap-intercompany-worker`](../sap-intercompany-worker) — bases de datos,
escenarios, destinos, mapeos de valor — y del log de replicación
(`webhook_events` + `replication_attempts`), sobre la misma Postgres.
Reemplaza a las rutas `/replication/*` que tenía `sap-webhook-api`.
`sap-intercompany-worker` no expone HTTP a propósito (sigue siendo un
script plano por cron); esta API es la única superficie HTTP para
administrar su configuración, pensada para ser consumida por
`sap-intercompany-viewer` (frontend, aún no implementado).
## Qué NO hace
- **No corre migraciones.** `prisma/schema.prisma` es una copia de la del
worker (mismo `DATABASE_URL`); acá solo se corre `prisma generate` para
tener un cliente tipado. El worker sigue siendo el dueño del schema.
- **No genera la lógica de `filter`/`transform` de un escenario.**
`POST /scenarios` crea la fila en Postgres y, si no existe, escribe el
scaffold de 3 secciones en
`sap-intercompany-worker/src/scenarios/<slug>.ts` (mismo scaffold que
genera `scenario:add` del CLI del worker) — el cuerpo real de `filter`/
`transform` siempre se edita a mano, en el editor del usuario.
## Endpoints
- `GET/POST /databases`, `GET /databases/:code`, `PATCH /databases/:code`
(incluye desactivar con `{"active": false}`). Las respuestas nunca
incluyen `password`.
- `GET /scenarios`, `GET /scenarios/:code`, `POST /scenarios`,
`PATCH /scenarios/:code`, `POST /scenarios/:code/rename`.
- `GET /scenarios/:code/source` — código fuente crudo del `.ts` (solo
lectura; requiere `WORKER_ROOT_PATH`).
- `GET/POST /scenarios/:code/destinations`,
`DELETE /scenarios/:code/destinations/:databaseCode`.
- `GET/POST /scenarios/:code/mappings` (`GET` acepta `?fieldName=`).
- `GET /events` (filtros `from`, `to`, `businessObject`, `scenarioCode`,
`status`), `GET /events/:id` (incluye `replication_attempts`).
- `POST /events/:id/reprocess` — pone el evento en `status='pending'` de
nuevo; el worker lo va a reprocesar contra **todos** los escenarios y
destinos aplicables en su próximo ciclo, no solo el que falló.
`POST /databases` y `POST /scenarios` fallan con `409` si el `code` ya
existe (a diferencia del CLI del worker, que hace upsert) — para
actualizar un existente se usa `PATCH`.
## Quick start
```bash
npm install
cp .env.example .env # completar DATABASE_URL (la misma del worker) y WORKER_ROOT_PATH
npx prisma generate # cliente tipado propio; NUNCA correr `prisma migrate` acá
npm start # http://localhost:3001
```
## Stack
- NestJS (mismo framework/estilo que `sap-webhook-api`), corrido con `tsx`
en vez de `nest build` — mismo enfoque ESM + TypeScript nativo que ya usa
`sap-intercompany-worker`, para poder importar directo el cliente Prisma
generado (`prisma-client`, salida `.ts`) sin fricción de compilación.
- Prisma 7 + `@prisma/adapter-pg`, contra la Postgres compartida con el
worker.
Nota de implementación: la inyección de dependencias de Nest usa
`@Inject(Token)` explícito en cada constructor (en vez de depender solo del
tipo declarado) porque bajo `tsx`/esbuild la emisión de
`design:paramtypes` (`emitDecoratorMetadata`) no es confiable — sin esto,
Nest instancia los controllers/servicios sin fallar pero con las
dependencias en `undefined`.