What We DON'T Use
Technologies and patterns explicitly avoided
What We DON'T Use
We avoid complexity that doesn't add value. Simple, boring solutions over clever ones.
Avoid These Patterns
| Pattern | Why Not | Use Instead |
|---|---|---|
| Custom pub/sub event systems | Debugging complexity, event ordering issues, hidden dependencies | Direct function calls for sync, BullMQ for async background jobs |
| Message queues between services | Overkill for 2 services | Direct REST calls with JWT |
| GraphQL | Adds schema/resolver complexity | REST API |
| Microservices (mesh, gateway, discovery) | Only have 2 services | Simple monolith + AI service |
| Complex state management (Redux, Zustand) | Server components cover most needs | React Server Components, useState |
| NoSQL for primary data | HRMS data is relational | PostgreSQL (MongoDB only for AI vectors) |
| CQRS, Saga, Hexagonal architecture | Unnecessary abstractions | Simple 3-layer: Controllers → Services → Repositories |
| Multiple caching layers | Cache invalidation nightmare | Single Redis cache with TTL |
| Shared code libraries between services | Creates tight coupling | Copy-paste, shared types only |
Version Policy
- Use current stable/LTS versions
- Avoid beta, RC, canary, or experimental versions in production
- Avoid versions past End-of-Life
Key Principles
- Start Simple - Boring technology beats clever solutions
- Independence Over DRY - Services should be fully independent
- Optimize When Needed - Profile first, then optimize
Specifics to be defined during implementation