2 KiB
2 KiB
Backend Node.js Transition Decision
Date: 2026-06-28
Decision
Vignette keeps the current Python/FastAPI backend for the near-term delivery path, but the replacement target for new replaceable backend infrastructure is Node.js.
This is not a full rewrite approval. The migration path is contract-first and strangler-style:
- Keep the FastAPI core while delivery-critical behavior is still being closed.
- Move cross-runtime boundaries into explicit contracts before extracting services.
- Prefer Node.js for new replaceable services or gateway implementations once the contract is stable.
- Do not weaken existing fail-closed security, persona catalog, DB/RLS, audit, or PII masking behavior to make migration easier.
Rationale
The project proposal and team capability point toward Node.js, but a direct Python-to-Node rewrite during the current schedule would add delivery and staffing risk. The safer path is to make Python replaceable by pinning the wire contracts first.
First Boundary
The first implementation boundary is the engine gateway contract:
POST /v1/generatePOST /v1/stream- SSE events:
token,done,error - request/response models owned by
apps/api/app/contracts/engine_gateway.py
Both the FastAPI engine client and the current Python engine gateway import this same contract. A future Node.js gateway must preserve these shapes.
Invariants
/personasnormal state remainssource:"database", degraded:false;seed_fallbackis not normal.- Browser credentials and BFF session behavior stay unchanged.
- RBAC, RLS, audit logging, and PII masking stay fail-closed.
- OpenAPI generated frontend contracts stay current.
- Existing ports and local/prod startup paths stay compatible until a service is deliberately replaced.
Next Refactor Candidates
- Split persona HTTP DTOs and mappers from
routes/personas.pywhile preserving OpenAPI schema names. - Split learner/review session read-model assembly from
routes/sessions.py. - Leave
admin.pymapper cleanup for later because RBAC, audit, and RLS blast radius is larger.