Category: Architecture & Refactoring
Difficulty: High
Description:
Graceful shutdown logic is manually implemented in every service:
- API Gateway: lines 949–968 (inline
shutdown function with fastify.close() + prisma.$disconnect())
- FX Engine: lines 467–497 (inline
shutdown function with fastify.close() + redis.quit())
- Settlement Engine: lines 638–702 (comprehensive shutdown with timeout, worker.close(), queue.close(), redis.quit(), prisma.$disconnect())
- Indexer: lines 547–553 (inline SIGTERM handler with
prisma.$disconnect(), webhookQueue.close(), webhookWorker.close(), fastify.close())
Each implementation has subtle differences: the settlement engine has a 30-second force-exit timeout, the indexer doesn't, the gateway doesn't close Redis or BullMQ resources. This duplication means bug fixes to shutdown handling must be applied in 4 places. A shared gracefulShutdown(fastify, options) function should be extracted.
Location:
services/api-gateway/src/index.ts:949–968, services/fx-engine/src/index.ts:467–497, services/settlement-engine/src/index.ts:638–702, services/indexer/src/index.ts:547–553
Acceptance Criteria:
Technical Notes:
- Resource close order: server → accept new connections (fastify.close) → workers → queues → redis → prisma.
- Use
Promise.allSettled to ensure all resources attempt close even if one fails.
Category: Architecture & Refactoring
Difficulty: High
Description:
Graceful shutdown logic is manually implemented in every service:
shutdownfunction withfastify.close()+prisma.$disconnect())shutdownfunction withfastify.close()+redis.quit())prisma.$disconnect(),webhookQueue.close(),webhookWorker.close(),fastify.close())Each implementation has subtle differences: the settlement engine has a 30-second force-exit timeout, the indexer doesn't, the gateway doesn't close Redis or BullMQ resources. This duplication means bug fixes to shutdown handling must be applied in 4 places. A shared
gracefulShutdown(fastify, options)function should be extracted.Location:
services/api-gateway/src/index.ts:949–968,services/fx-engine/src/index.ts:467–497,services/settlement-engine/src/index.ts:638–702,services/indexer/src/index.ts:547–553Acceptance Criteria:
gracefulShutdownfunction into@bettapay/validation/shutdown.ts{ fastify, prisma?, redis?, bullmq?: { worker?, queues? } }process.exit(0)is called after successful shutdown,process.exit(1)on failureTechnical Notes:
Promise.allSettledto ensure all resources attempt close even if one fails.