-
Couldn't load subscription status.
- Fork 0
Description
Epic Type: Child Epic #10 (Phase 2 of Task 1.2)
Parent Epic: #8 (epic-destroy-command.md)
Dependencies: Child Epic #9 (epic-app-layer-destroy-command.md) must be completed first
Related Roadmap: Section 1.2
Parent Issue: #2 (Scaffolding for main app)
Roadmap Section: 1.2 - Create command torrust-tracker-deployer destroy
Type: Epic
Priority: High
📋 Epic Overview
Implement the user-facing CLI interface for the destroy command. This epic builds on top of the application layer implementation from Epic #9 to provide a complete, production-ready CLI experience.
This is Phase 2 of the inside-outside approach: after the core application logic is implemented and tested, we add the user-friendly CLI interface.
🎯 Goals
- Fix E2E infrastructure preservation for manual testing workflow
- Rename existing app commands to command handlers for clarity
- Add Clap subcommand configuration for
destroy - Implement user-friendly progress messages and feedback
- Provide comprehensive user documentation
Note: Force flags (--force, --yes) and skip confirmation features are out of scope for MVP. These are easy to implement later and not essential for the initial destroy command functionality.
🚫 Non-Goals
- Application layer logic (completed in Epic EPIC: App Layer Destroy Command #9)
- Core infrastructure teardown (completed in Epic EPIC: App Layer Destroy Command #9)
- E2E testing of destroy logic (completed in Epic EPIC: App Layer Destroy Command #9)
📦 Sub-Issues
Issue #21: Fix E2E Infrastructure Preservation
Description: Restore the --keep flag functionality for E2E tests to enable proper manual testing of the destroy command.
Scope: Fix the E2E infrastructure preservation feature that was lost during recent refactoring.
Acceptance Criteria:
-
--keepflag functionality restored in E2E tests - Manual testing verification using
lxc list | grep e2e-provisionshows preserved infrastructure - Documentation updated with manual testing procedures
- All existing E2E tests continue to pass
GitHub Issue: #21 - 21-fix-e2e-infrastructure-preservation.md
Estimated Effort: 1-2 hours
Issue #22: Rename App Commands to Command Handlers
Description: Refactor existing command terminology for clarity as we introduce UI-level Clap subcommands.
Scope:
- Rename structs/modules in
src/application/commands/for clarity - Update documentation to use "command handler" terminology
- Ensure consistent naming across the codebase
Rationale: As we introduce UI-level commands (Clap subcommands), we need clear terminology:
- UI Command: Clap subcommand (e.g.,
destroy,provision) - Command Handler: DDD Application Layer command (e.g.,
DestroyCommand,ProvisionCommand)
Acceptance Criteria:
- Command handlers renamed consistently
- Documentation updated with new terminology
- No breaking changes to functionality
- All tests pass after refactoring
- Code follows project conventions
GitHub Issue: #22 - 22-rename-app-commands-to-command-handlers.md
Estimated Effort: 2-3 hours
Issue #23: Add Clap Subcommand Configuration
Description: Implement the destroy subcommand in the CLI with basic functionality and UserOutput scaffolding.
Dependencies: Issue #21 must be completed first to enable manual testing workflow.
Scope:
- Add
destroysubcommand tosrc/app.rs - Wire up subcommand to call
DestroyCommandhandler - Add environment name parameter (required)
- Add
UserOutputtype andVerbosityLevelenum (followingdocs/research/UX/user-output-vs-logging-separation.md) - Implement basic progress messages using
UserOutput - Basic command structure without advanced options
UserOutput Integration:
- Add
VerbosityLevelenum (Quiet, Normal, Verbose, VeryVerbose, Debug) - Add
UserOutputstruct with methods for different message types - Note: Only enum definition for now, no Clap verbosity flags yet
- Use
UserOutputfor essential destroy command messages
Example Usage:
torrust-tracker-deployer destroy <ENVIRONMENT_NAME>Example Output (Normal verbosity level):
⏳ Destroying environment 'my-env'...
⏳ Tearing down infrastructure...
⏳ Cleaning up resources...
✅ Environment 'my-env' destroyed successfully
Acceptance Criteria:
-
destroysubcommand added to Clap configuration - Subcommand calls
DestroyCommandfrom Application Layer - Environment name parameter required
-
VerbosityLevelenum implemented (5 levels) -
UserOutputstruct implemented with basic methods (progress,success,warn) - Essential destroy messages implemented using
UserOutput - Help text provides clear usage information
- Basic error handling for missing environment
- Unit tests for CLI argument parsing
- User output separated from internal logging
GitHub Issue: #23 - 23-add-clap-subcommand-configuration.md
Estimated Effort: 3-4 hours
Issue #24: Add User Documentation
Description: Create comprehensive user-facing documentation for the destroy command.
Scope:
- Add section to
docs/user-guide/about destroy command - Document command usage and examples
- Document flags and options
- Add troubleshooting section
- Document safety considerations
Acceptance Criteria:
- User guide created/updated
- Usage examples provided
- Flags and options documented
- Troubleshooting section added
- Safety considerations documented
- All markdown linting passes
GitHub Issue: #24 - 24-add-user-documentation.md
Estimated Effort: 2-3 hours
📊 Epic Summary
Total Estimated Effort: 8-12 hours
Sub-Issues:
- Issue Fix E2E Infrastructure Preservation #21: Fix E2E Infrastructure Preservation (1-2h)
- Issue Rename App Commands to Command Handlers #22: Rename App Commands to Command Handlers (2-3h)
- Issue Add Clap Subcommand Configuration #23: Add Clap Subcommand Configuration with Basic Progress (3-4h)
- Issue Add User Documentation #24: Add User Documentation (2-3h)
Out of Scope for MVP: Force flags (--force, --yes) and skip confirmation features - these can be implemented as separate improvements later.
🔗 Dependencies
- Requires: Epic EPIC: App Layer Destroy Command #9 (App Layer Destroy Command) - must be completed first
- Blocks: None (future improvements can build on this)
📝 Technical Notes
MVP Focus
This epic focuses on the essential functionality for MVP:
- E2E infrastructure preservation for manual testing (prerequisite)
- Basic destroy subcommand with clear interface
- UserOutput type and VerbosityLevel enum (scaffolding for future verbosity flags)
- Essential progress messages using Normal verbosity level
- User-friendly feedback with proper separation from logging
- Basic user documentation
- Clean separation between UI and Application layers
Future Improvements (out of scope for MVP):
- Clap verbosity flags (
-v,-vv,-q) - Force and skip confirmation flags
- Interactive mode with detailed prompts
- Selective resource destruction
- Advanced verbosity level implementations
UI Command vs. Command Handler
After this epic, we'll have clear separation:
// UI Layer (src/app.rs) - Clap subcommands
#[derive(Subcommand)]
enum Commands {
Provision { /* ... */ },
Destroy { environment: String },
Configure { /* ... */ },
}
// Application Layer (src/application/commands/) - DDD command handlers
pub struct DestroyCommandHandler { /* ... */ }
pub struct ProvisionCommandHandler { /* ... */ }
pub struct ConfigureCommandHandler { /* ... */ }User Output vs. Logging
Follow project principles established in docs/research/UX/user-output-vs-logging-separation.md:
- User Output: Directed to stdout via
UserOutputtype, clear and concise - Logging: Directed to files/stderr via tracing, detailed for debugging
- Complete separation between user-facing messages and internal logging
UserOutput Implementation
// Verbosity levels (enum only for MVP, no CLI flags yet)
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum VerbosityLevel {
Quiet, // Minimal output
Normal, // Default: Essential progress (MVP focus)
Verbose, // Detailed progress
VeryVerbose, // Including decisions & retries
Debug, // Maximum detail for troubleshooting
}
// UserOutput type for destroy command
pub struct UserOutput {
verbosity: VerbosityLevel,
}
impl UserOutput {
pub fn progress(&self, message: &str) { /* ... */ }
pub fn success(&self, message: &str) { /* ... */ }
pub fn warn(&self, message: &str) { /* ... */ }
}Example Destroy Output
Normal Verbosity (MVP implementation):
⏳ Destroying environment 'my-env'...
⏳ Tearing down infrastructure...
⏳ Cleaning up resources...
✅ Environment 'my-env' destroyed successfully
Parallel Internal Logging (always present):
2025-10-21T10:15:00.123Z INFO destroy_command: Starting environment destruction
environment="my-env" command_type="destroy"
2025-10-21T10:15:01.456Z INFO opentofu_client: Executing destroy operation
workspace="/path/to/env" operation="destroy"
2025-10-21T10:15:15.789Z INFO destroy_command: Environment destruction completed
environment="my-env" duration=15.666s
🚀 Next Steps After Completion
After completing this epic:
- User testing with real environments
- Gather feedback on UX
- Consider future improvements:
- Interactive confirmation with resource preview
- Selective destruction (only OpenTofu, only Ansible, etc.)
- Batch destruction for multiple environments
- Integration with CI/CD pipelines
📋 Related Documentation
- Roadmap
- Parent Issue #2
- Epic #9: App Layer Destroy Command
- Development Principles
- User Output Research
Epic Document: docs/issues/10-epic-ui-layer-destroy-command.md