Part of the demo-quality refactor tracked in docs/plans/refactor/. Branches phase-2-foundations then phase-2-server-hexagonal. Depends on Phase 1.
Objective
Make the server fully hexagonal. Every external dependency sits behind a named port with an in-memory fake and a contract test, services are unit tested against the fakes, and routes shrink to parse, call a service, reply. The 2,244 line server/routes/books.ts disappears.
Contents
- An early foundations PR consolidating provider constants into
shared/domain/provider.ts and adding response contract types plus SSE event unions
- Ports with fakes and contract tests written before the adapters that satisfy them
- Adapters for text generation, book repository, speech synthesis, image generation, key vault, diagram rendering, EPUB import and export, and background tasks
- A composition root that wires ports into
buildServer() and accepts overrides for tests
- Mechanical route split, then five service slices extracted in parallel
- Dead code removal
Gate
- Grep gates pass, meaning no
ai SDK imports, no fs access, and no repeated Zod error blocks inside server/routes/
- Contract tests green for every port and every adapter
server/routes/books.ts no longer exists
- Characterization tests from Phase 0 still green, apart from the one sanctioned assertion change for the MCP authoring routes returning 400 rather than 500 on invalid input
- Manual end to end pass
Part of the demo-quality refactor tracked in
docs/plans/refactor/. Branchesphase-2-foundationsthenphase-2-server-hexagonal. Depends on Phase 1.Objective
Make the server fully hexagonal. Every external dependency sits behind a named port with an in-memory fake and a contract test, services are unit tested against the fakes, and routes shrink to parse, call a service, reply. The 2,244 line
server/routes/books.tsdisappears.Contents
shared/domain/provider.tsand adding response contract types plus SSE event unionsbuildServer()and accepts overrides for testsGate
aiSDK imports, nofsaccess, and no repeated Zod error blocks insideserver/routes/server/routes/books.tsno longer exists