Skip to main content

torrust_tracker_deployer_lib/presentation/cli/controllers/
mod.rs

1//! Controllers Layer - Presentation Layer Component
2//!
3//! The Controllers Layer handles command execution and business logic coordination.
4//! This is the third layer in the presentation layer's four-layer architecture:
5//! Input โ†’ Dispatch โ†’ **Controllers** โ†’ Views.
6//!
7//! ## ๐Ÿšง Current Status: Proposal #3 In Progress
8//!
9//! This layer is being refactored to establish consistent controller patterns.
10//! The goal is to align all command controllers with the clean architecture
11//! established by the destroy command controller.
12//!
13//! ## Command Architecture Types
14//!
15//! There are two types of commands in the system, each with different internal structure:
16//!
17//! ### 1. Single Commands (Direct Execution)
18//!
19//! Commands that execute directly without subcommands (e.g., `destroy`).
20//! These follow the clean handler pattern with direct execution.
21//!
22//! ### 2. Commands with Subcommands (Router + Subcontrollers)
23//!
24//! Commands that route to multiple subcommands (e.g., `create environment`, `create template`).
25//! These have an **extra routing layer** but subcommands maintain the same internal
26//! structure as single commands.
27//!
28//! **Key Principle**: Subcommands should have internally the same structure as normal
29//! commands, but with an additional routing layer to dispatch between subcommands.
30//!
31//! ## Controller Maturity Levels
32//!
33//! ### โœ… Reference Implementation: Destroy Controller (Single Command)
34//!
35//! The `destroy` controller demonstrates the target architecture for single commands:
36//! - **Clean Handler Pattern**: Single `handler.rs` with focused responsibility
37//! - **Dedicated Error Types**: Command-specific errors with help methods
38//! - **Minimal Dependencies**: Takes `ExecutionContext`, delegates to application layer
39//! - **Comprehensive Tests**: Full test coverage with clear test organization
40//!
41//! ```text
42//! destroy/
43//! โ”œโ”€โ”€ handler.rs      # Main command handler function
44//! โ”œโ”€โ”€ errors.rs       # DestroySubcommandError with help methods
45//! โ”œโ”€โ”€ tests/          # Command-specific tests
46//! โ””โ”€โ”€ mod.rs          # Module exports
47//! ```
48//!
49//! ### ๐Ÿšง Needs Refactoring: Create Controller (Command with Subcommands)
50//!
51//! The `create` controller needs refactoring to match the target pattern for commands
52//! with subcommands. It demonstrates the **router + subcontroller** pattern but needs
53//! architectural cleanup.
54//!
55//! **Current Structure (Transitional)**:
56//! ```text
57//! create/
58//! โ”œโ”€โ”€ router.rs       # Routes between environment and template subcommands
59//! โ”œโ”€โ”€ errors.rs       # Unified CreateCommandError wrapper
60//! โ”œโ”€โ”€ subcommands/    # Temporary: should become separate controllers
61//! โ”‚   โ”œโ”€โ”€ environment/ # Environment creation logic
62//! โ”‚   โ””โ”€โ”€ template/    # Template generation logic
63//! โ”œโ”€โ”€ tests/          # Tests organized by function
64//! โ”‚   โ”œโ”€โ”€ environment.rs # Environment creation tests
65//! โ”‚   โ””โ”€โ”€ template.rs    # Template generation tests
66//! โ””โ”€โ”€ mod.rs          # Module exports
67//! ```
68//!
69//! **Target Structure (After Refactoring)**:
70//!
71//! The refactoring will split this into separate controllers for each subcommand,
72//! each following the same clean structure as single commands:
73//!
74//! ```text
75//! create_environment/  # NEW: Dedicated environment controller
76//! โ”œโ”€โ”€ handler.rs      # Environment creation handler (same structure as destroy)
77//! โ”œโ”€โ”€ errors.rs       # Environment-specific errors
78//! โ”œโ”€โ”€ tests/          # Environment tests
79//! โ””โ”€โ”€ mod.rs          # Module exports
80//!
81//! create_template/     # NEW: Dedicated template controller
82//! โ”œโ”€โ”€ handler.rs      # Template generation handler (same structure as destroy)
83//! โ”œโ”€โ”€ errors.rs       # Template-specific errors
84//! โ”œโ”€โ”€ tests/          # Template tests
85//! โ””โ”€โ”€ mod.rs          # Module exports
86//! ```
87//!
88//! **Key Insight**: Each subcommand becomes a separate controller with the same
89//! internal structure as single commands. The routing is handled at the dispatch
90//! layer, not within controllers.
91//!
92//! ## ๐ŸŽฏ Controller Design Principles
93//!
94//! Based on the destroy controller reference implementation:
95//!
96//! ### 1. Single Responsibility
97//! - Each controller handles **one specific command** (destroy, create environment, create template)
98//! - No routing logic within controllers - routing handled by dispatch layer for subcommands
99//! - No presentation logic - controllers coordinate, views handle output
100//!
101//! ### 2. Clean Handler Pattern (Universal for All Controllers)
102//! - Main logic in `handler.rs` with descriptive function name (`handle_destroy_command`)
103//! - Take `ExecutionContext` for dependencies
104//! - Return command-specific error types
105//! - Focus on orchestrating application layer services
106//!
107//! **Note**: This pattern applies to both single commands and subcommand controllers.
108//! Subcommand controllers have the same internal structure, just different routing.
109//!
110//! ### 3. Dedicated Error Types
111//! - Command-specific error enums (e.g., `DestroySubcommandError`)
112//! - Use thiserror for structured errors
113//! - Implement `.help()` method for detailed troubleshooting
114//! - Include context and actionable guidance
115//!
116//! ### 4. Application Layer Integration
117//! - Controllers call application layer command handlers
118//! - Pass through domain entities and value objects
119//! - Handle application errors and convert to presentation errors
120//! - Don't contain business logic - delegate to application layer
121//!
122//! ## ๐Ÿ”€ Subcommand Routing Architecture
123//!
124//! For commands with subcommands (like `create`), the current architecture uses:
125//!
126//! 1. **Dispatch Layer**: Receives full command (e.g., `create environment`)
127//! 2. **Router**: Routes to appropriate subcommand handler based on action type
128//! 3. **Subcommand Handler**: Executes specific logic (environment creation or template generation)
129//!
130//! **Current Implementation Example** (from `create/router.rs`):
131//! ```ignore
132//! use std::path::Path;
133//! use torrust_tracker_deployer_lib::domain::provider::Provider;
134//! use torrust_tracker_deployer_lib::presentation::cli::input::cli::commands::CreateAction;
135//! use torrust_tracker_deployer_lib::presentation::cli::dispatch::context::ExecutionContext;
136//! use torrust_tracker_deployer_lib::presentation::cli::controllers::create::errors::CreateCommandError;
137//! use torrust_tracker_deployer_lib::presentation::cli::controllers::create::subcommands;
138//!
139//! # #[tokio::main]
140//! # async fn main() {
141//! # let action = todo!();
142//! # let working_dir = todo!();
143//! # let context = todo!();
144//! pub async fn route_command(
145//!     action: CreateAction,
146//!     working_dir: &Path,
147//!     context: &ExecutionContext,
148//! ) -> Result<(), CreateCommandError> {
149//!     match action {
150//!         CreateAction::Environment { env_file } => {
151//!             context
152//!                 .container()
153//!                 .create_environment_controller()
154//!                 .execute(&env_file, working_dir)
155//!                 .await
156//!                 .map(|_| ()) // Convert Environment<Created> to ()
157//!                 .map_err(CreateCommandError::Environment)
158//!         }
159//!         CreateAction::Template { output_path, provider } => {
160//!             let template_path = output_path.unwrap_or_else(CreateAction::default_template_path);
161//!             context
162//!                 .container()
163//!                 .create_template_controller()
164//!                 .execute(&template_path, provider)
165//!                 .await
166//!                 .map_err(CreateCommandError::Template)
167//!         }
168//!         CreateAction::Schema { output_path } => {
169//!             context
170//!                 .container()
171//!                 .create_schema_controller()
172//!                 .execute(output_path.as_ref())
173//!                 .map_err(CreateCommandError::Schema)
174//!         }
175//!     }
176//! }
177//! # }
178//! ```
179//!
180//! **Target Architecture**: Move routing to dispatch layer, make each subcommand
181//! a separate controller with the same structure as single commands.
182//!
183//! ## ๐Ÿ“‹ Refactoring Plan for Create Controller
184//!
185//! To complete Proposal #3, the create controller needs to be split into separate
186//! controllers that each follow the same clean structure as single commands:
187//!
188//! ### Current Challenge
189//! The `create` command currently uses internal routing with subcommands. This needs
190//! to be refactored so each subcommand becomes a separate controller with the same
191//! internal structure as single commands.
192//!
193//! ### Step 1: Create Environment Controller
194//! 1. Create `src/presentation/controllers/create_environment/`
195//! 2. Move environment logic from `create/subcommands/environment/`
196//! 3. Create clean handler following destroy pattern (same structure)
197//! 4. Move environment tests to new controller
198//!
199//! ### Step 2: Create Template Controller  
200//! 1. Create `src/presentation/controllers/create_template/`
201//! 2. Move template logic from `create/subcommands/template/`
202//! 3. Create clean handler following destroy pattern (same structure)
203//! 4. Move template tests to new controller
204//!
205//! ### Step 3: Update Dispatch Router
206//! 1. Remove create controller router (no more internal subcommand routing)
207//! 2. Update dispatch layer to route directly to separate controllers
208//! 3. Update error handling for separate error types
209//! 4. Each subcommand treated as independent controller
210//!
211//! ### Step 4: Remove Old Create Structure
212//! 1. Remove `create/` directory entirely
213//! 2. Update imports throughout codebase
214//! 3. Update documentation and tests
215//!
216//! **Result**: Both `create environment` and `create template` will be handled by
217//! separate controllers with identical structure to `destroy` - just different routing
218//! at the dispatch level.
219//!
220//! ## ๐Ÿงช Testing Strategy
221//!
222//! Each controller should have comprehensive test coverage:
223//! - **Unit Tests**: Handler function behavior with various inputs
224//! - **Error Tests**: All error variants and help text validation
225//! - **Integration Tests**: End-to-end command execution with `ExecutionContext`
226//!
227//! Tests should be **isolated** - each controller's tests run independently
228//! without depending on other controllers or external state.
229//!
230//! ## ๐Ÿ”„ Future Controllers
231//!
232//! After establishing the controller pattern, additional commands will follow
233//! the same structure:
234//!
235//! ```text
236//! controllers/
237//! โ”œโ”€โ”€ create_environment/  # Environment creation
238//! โ”œโ”€โ”€ create_template/     # Template generation
239//! โ”œโ”€โ”€ destroy/            # Environment destruction โœ…
240//! โ”œโ”€โ”€ provision/          # Future: Infrastructure provisioning
241//! โ”œโ”€โ”€ configure/          # Future: Software configuration
242//! โ”œโ”€โ”€ release/            # Future: Application deployment
243//! โ””โ”€โ”€ run/               # Future: Service management
244//! ```
245//!
246//! Each controller will:
247//! - Follow the established handler pattern
248//! - Have dedicated error types
249//! - Integrate cleanly with the dispatch layer
250//! - Maintain comprehensive test coverage
251
252// Re-export command modules
253pub mod configure;
254pub mod constants;
255pub mod create;
256pub mod destroy;
257pub mod docs;
258pub mod exists;
259pub mod list;
260pub mod provision;
261pub mod purge;
262pub mod register;
263pub mod release;
264pub mod render;
265pub mod run;
266pub mod show;
267pub mod test;
268pub mod validate;
269
270// Shared test utilities
271#[cfg(test)]
272pub mod tests;