22. NestJS for CLI Application
Status: Accepted Date: 2025-07-06
Context
The Mercury trading system requires a command-line interface (CLI) for administrative tasks, debugging, and direct operational control. A typical CLI would be a separate, lightweight application. However, this would require duplicating significant amounts of business logic, database connection setup, and service initializations that already exist within the main NestJS application. This would lead to code rot and inconsistencies between the main application and the CLI.
Decision
We will build the CLI by bootstrapping the entire NestJS application environment. Instead of creating a separate application, the CLI entry point will initialize the main AppModule of the mercury-backend. This gives the CLI commands direct, type-safe access to the application's dependency injection container. Commands can then retrieve and execute any registered service (e.g., DikeService, AtlasService) from the application context, ensuring that the CLI operates with the exact same logic and configuration as the running application.
Consequences
Positive:
- Code Re-use & DRY: Eliminates the need to duplicate business logic, configuration, and service initializations. The CLI re-uses the exact same components as the main application.
- Consistency: Guarantees that operations performed via the CLI are identical to those performed by the application, as they run the same code.
- Type Safety: Commands have full, type-safe access to the application's services and repositories.
- Maintainability: When a service's logic is updated, the change is automatically reflected in the CLI without any extra work.
Negative:
- Startup Overhead: Bootstrapping the entire NestJS application can make the CLI slower to start compared to a simple, standalone script.
- Increased Complexity: The CLI's setup is more complex than a standard
commander.jsoryargsapplication. - Resource Intensive: It consumes more memory during execution as it loads the full application context.
Mitigation:
- Targeted Module Loading: For performance-critical CLI tasks, we can explore creating a separate, lightweight application module that only imports the specific services needed for that command group.
- Pragmatic Use: This pattern is intended for administrative and debugging tasks where startup time is not a critical factor, not for high-frequency, lightweight operations.
- Clear Separation: The CLI-specific code (command definitions) will be kept in a dedicated
climodule, separate from the core application logic.