3.7 KiB
3.7 KiB
ADR-0002: Singleton Prisma Client Pattern
Status
Accepted
Context
The application was creating multiple PrismaClient instances across different service files. This led to:
- Multiple database connection pools
- Potential connection exhaustion
- Inconsistent connection management
- Difficulties in monitoring and debugging database connections
Decision
Implement a singleton pattern for Prisma Client to ensure:
- Single connection pool across the application
- Proper connection lifecycle management
- Graceful shutdown handling
- Development hot-reload compatibility
The singleton is implemented in src/shared/database/prisma.ts and exported for use across the application.
Consequences
Positive
- Single connection pool reduces resource usage
- Consistent connection management
- Easier to monitor and debug
- Proper cleanup on application shutdown
- Works correctly with development hot-reload
Negative
- Requires refactoring existing code (381 files identified)
- All services must import from shared location
- Potential for circular dependencies if not careful
Risks
- Large refactoring effort required
- Need to ensure all services are updated
- Must maintain backward compatibility during migration
Decision Tree
graph TD
START[Need Database Connection Management]
START --> Q1{Connection Pool<br/>Issues?}
Q1 -->|Yes| Q2{Refactoring<br/>Acceptable?}
Q1 -->|No| ALT1[Keep Multiple Clients]
Q2 -->|Yes| Q3{Need DI<br/>Framework?}
Q2 -->|No| ALT1
Q3 -->|No| DECISION[Singleton Pattern<br/>CHOSEN]
Q3 -->|Yes| ALT2[Dependency Injection]
DECISION --> IMPL[Implement Singleton]
ALT1 --> RISK1[Connection Exhaustion Risk]
ALT2 --> COMPLEX[Increased Complexity]
IMPL --> BENEFIT[Single Connection Pool<br/>Better Management]
Alternatives Considered
-
Multiple Prisma Clients: Keep current approach
- Pros: Simple, no refactoring needed
- Cons: Connection pool issues, resource waste
-
Dependency Injection: Inject Prisma client
- Pros: Testable, flexible
- Cons: More complex, requires DI framework
-
Singleton Pattern: Chosen approach
- Pros: Simple, effective, minimal changes
- Cons: Requires refactoring
Implementation
- Created
src/shared/database/prisma.tswith singleton pattern - Refactored critical services (ledger, fx, accounts, payments, etc.)
- Remaining services to be refactored systematically
Recommendations
Priority: High
-
Systematic Refactoring
- Description: Complete refactoring of remaining services
- Implementation:
- Refactor services incrementally
- Test each refactored service
- Monitor connection pool metrics
- Impact: Ensures consistent connection management across all services
- Dependencies: Test coverage, monitoring infrastructure
-
Connection Pool Monitoring
- Description: Monitor connection pool usage
- Implementation:
- Track active/idle connections
- Alert on pool exhaustion
- Optimize pool size based on load
- Impact: Prevents connection issues and enables optimization
- Dependencies: Monitoring system, metrics collection
-
Documentation Updates
- Description: Document singleton pattern usage
- Implementation:
- Update development guide
- Add code examples
- Document migration process
- Impact: Ensures new code follows pattern
- Dependencies: Documentation system
References
- Prisma Best Practices: https://www.prisma.io/docs/guides/performance-and-optimization/connection-management
- Node.js Connection Pooling: https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/