10. NestJS Modular Architecture
Status: Accepted Date: 2025-07-06
Context
The Arcana Backend is a complex application with several distinct domains: Telegram bot interaction, tarot reading logic, AI interpretations, data persistence, and a REST API. Without a clear architectural pattern, the codebase could become tightly coupled and difficult to maintain or extend.
Decision
We decided to adopt a modular architecture using the NestJS framework. Each core feature (e.g., deck, reading, telegram, ai) is encapsulated within its own NestJS module. This promotes a clear separation of concerns, where each module has a distinct responsibility and a well-defined public API for interacting with other modules.
Consequences
Positive:
- Improved maintainability and scalability. New features can be added as new modules with minimal impact on existing code.
- Enhanced team collaboration, as different developers can work on separate modules concurrently.
- Clear boundaries enforce a clean architecture, preventing business logic from leaking into transport layers (like API controllers or Telegram handlers).
- NestJS's dependency injection system simplifies testing and mocking.
Negative:
- Can introduce some boilerplate code for module definitions.
- Requires a deeper understanding of NestJS conventions and module system for new developers.
- Care must be taken to define clear contracts between modules to avoid creating implicit, tight coupling.
Mitigation:
- Boilerplate: Develop internal schematics or code generation tools to automate the creation of new modules and their associated files.
- Learning Curve: Maintain clear documentation on our architectural patterns and provide onboarding sessions for new developers on NestJS and our module structure.
- Coupling: Enforce strict module boundaries using tools like
depcheckor custom linting rules. Conduct regular architecture reviews to identify and refactor any emerging coupling issues.