Skip to content
Merged
160 changes: 82 additions & 78 deletions docs/refactors/plans/separate-view-data-from-views.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,20 @@ Establish clear separation between view data structures (DTOs) and view renderin

**Total Active Proposals**: 5
**Total Postponed**: 0
**Total Discarded**: 0
**Completed**: 0
**Total Discarded**: 1
**Completed**: 4
**In Progress**: 0
**Not Started**: 5
**Not Started**: 0

### Phase Summary

- **Phase 0 - Foundation Commands**: ⏳ 0/2 completed (0%)
- **Phase 1 - Mixed Commands**: ⏳ 0/2 completed (0%)
- **Phase 2 - Documentation**: 0/1 completed (0%)
- **Phase 0 - Foundation Commands**: ✅ 2/2 completed (100%)
- **Phase 1 - Mixed Commands**: ✅ 2/2 completed (100%)
- **Phase 2 - Documentation**: 0/1 discarded (not needed)

### Discarded Proposals

None.
- **Proposal #4**: Update Shared Components (Not Needed - current structure is optimal)

### Postponed Proposals

Expand Down Expand Up @@ -79,13 +79,13 @@ These commands already follow the DTO + Views pattern and just need reorganizati

### Proposal #0: Refactor Create Command Structure

**Status**: ⏳ Not Started
**Status**: ✅ Completed
**Impact**: 🟢🟢🟢 High
**Effort**: 🔵 Low
**Priority**: P0
**Depends On**: None
**Completed**: -
**Commit**: -
**Completed**: 2026-02-16
**Commit**: 9a52ddc2

#### Problem

Expand Down Expand Up @@ -144,14 +144,14 @@ pub mod views {

#### Implementation Checklist

- [ ] Create `view_data/` and `views/` subdirectories
- [ ] Move `environment_details.rs` → `view_data/`
- [ ] Move `text_view.rs` and `json_view.rs` → `views/`
- [ ] Update `mod.rs` with new module structure
- [ ] Update imports in controller (`src/presentation/controllers/create/handler.rs`)
- [ ] Update imports in tests
- [ ] Verify all tests pass
- [ ] Run linter and fix any issues
- [x] Create `view_data/` and `views/` subdirectories
- [x] Move `environment_details.rs` → `view_data/`
- [x] Move `text_view.rs` and `json_view.rs` → `views/`
- [x] Update `mod.rs` with new module structure
- [x] Update imports in controller (`src/presentation/controllers/create/handler.rs`)
- [x] Update imports in tests
- [x] Verify all tests pass
- [x] Run linter and fix any issues

#### Testing Strategy

Expand All @@ -170,11 +170,13 @@ cargo run --bin linter all

### Proposal #1: Refactor Provision Command Structure

**Status**: ⏳ Not Started
**Status**: ✅ Completed
**Impact**: 🟢🟢🟢 High
**Effort**: 🔵 Low
**Priority**: P0
**Depends On**: None
**Completed**: 2026-02-16
**Commit**: 6539e787

#### Problem

Expand Down Expand Up @@ -226,14 +228,14 @@ Same rationale as Proposal #0 - establish consistent pattern.

#### Implementation Checklist

- [ ] Create `view_data/` and `views/` subdirectories
- [ ] Move `provision_details.rs`, `connection_details.rs`, `dns_reminder.rs` → `view_data/`
- [ ] Move `text_view.rs` and `json_view.rs` → `views/`
- [ ] Update `mod.rs` with new module structure
- [ ] Update imports in controller (`src/presentation/controllers/provision/handler.rs`)
- [ ] Update imports in tests
- [ ] Verify all tests pass
- [ ] Run linter and fix any issues
- [x] Create `view_data/` and `views/` subdirectories
- [x] Move `provision_details.rs`, `connection_details.rs`, `dns_reminder.rs` → `view_data/`
- [x] Move `text_view.rs` and `json_view.rs` → `views/`
- [x] Update `mod.rs` with new module structure
- [x] Update imports in controller (`src/presentation/controllers/provision/handler.rs`)
- [x] Update imports in tests
- [x] Verify all tests pass
- [x] Run linter and fix any issues

#### Testing Strategy

Expand All @@ -250,11 +252,13 @@ These commands need analysis and extraction before reorganization.

### Proposal #2: Refactor List Command Structure

**Status**: ⏳ Not Started
**Status**: ✅ Completed
**Impact**: 🟢🟢 Medium
**Effort**: 🔵🔵 Medium
**Priority**: P1
**Depends On**: Proposals #0, #1 (establishes pattern)
**Completed**: 2026-02-16
**Commit**: 6cf29662

#### Problem

Expand Down Expand Up @@ -327,14 +331,14 @@ Preparing for JSON output (task 12.5) requires DTO + Views pattern.

#### Implementation Checklist

- [ ] Analyze current `environment_list.rs` structure
- [ ] Extract data structures → `view_data/environment_list.rs`
- [ ] Extract table rendering → `views/text_view.rs`
- [ ] Update `mod.rs` with new module structure
- [ ] Update imports in controller
- [ ] Update imports in tests
- [ ] Verify all tests pass
- [ ] Run linter and fix any issues
- [x] Analyze current `environment_list.rs` structure
- [x] Extract data structures → `view_data/environment_list.rs` (N/A - data already in application layer)
- [x] Extract table rendering → `views/text_view.rs`
- [x] Update `mod.rs` with new module structure
- [x] Update imports in controller
- [x] Update imports in tests
- [x] Verify all tests pass
- [x] Run linter and fix any issues

#### Testing Strategy

Expand All @@ -350,11 +354,13 @@ cargo test && cargo run --bin linter all

### Proposal #3: Refactor Show Command Structure

**Status**: ⏳ Not Started
**Status**: ✅ Completed
**Impact**: 🟢🟢 Medium
**Effort**: 🔵🔵 Medium
**Priority**: P1
**Depends On**: Proposals #0, #1
**Completed**: 2026-02-16
**Commit**: 68676e16

#### Problem

Expand Down Expand Up @@ -416,15 +422,15 @@ Show command will need JSON output (task 12.3), requiring DTO + Views pattern.

#### Implementation Checklist

- [ ] Analyze controller for rendering logic
- [ ] Create `view_data/` and `views/` subdirectories
- [ ] Move `environment_info/` → `view_data/environment_info/`
- [ ] Extract rendering logic → `views/text_view.rs`
- [ ] Update `mod.rs` with new module structure
- [ ] Update imports in controller
- [ ] Update imports in tests
- [ ] Verify all tests pass
- [ ] Run linter and fix any issues
- [x] Analyze controller for rendering logic (views already separated)
- [x] Create `view_data/` and `views/` subdirectories (only views/ needed)
- [x] Move `environment_info/` → `views/` (renamed directory with existing structure)
- [x] Rename `EnvironmentInfoView` to `TextView`
- [x] Update `mod.rs` with new module structure
- [x] Update imports in controller
- [x] Update imports in tests
- [x] Verify all tests pass
- [x] Run linter and fix any issues

#### Testing Strategy

Expand All @@ -439,11 +445,12 @@ cargo test && cargo run --bin linter all

### Proposal #4: Update Shared Components

**Status**: Not Started
**Status**: Not Needed
**Impact**: 🟢 Low
**Effort**: 🔵 Low
**Priority**: P2
**Depends On**: Proposals #0-#3
**Decision Date**: 2026-02-16

#### Problem

Expand All @@ -459,38 +466,35 @@ src/presentation/views/commands/shared/

These are reusable view components but the naming could be clearer.

#### Proposed Solution
#### Analysis

Rename to better reflect purpose:
After reviewing the code, the current structure is already well-organized:

```rust
src/presentation/views/commands/shared/
└── view_components/
├── service_urls.rs
├── dns_hints.rs
└── mod.rs
```
1. **Clear Naming**: `service_urls/` is semantically meaningful - these helpers render service URLs
2. **Pure View Helpers**: Both components (`compact.rs`, `dns_hint.rs`) are pure view helpers with no need for data/view separation
3. **Minimal Usage**: Only used by `run` command controller - minimal churn from changes
4. **No Real Benefit**: Proposed `view_components/` is more generic and actually less clear than current name

Analyze each file to determine if data/view separation is needed.
#### Decision Rationale

#### Rationale
**Current structure is optimal** because:

Shared components should have clear naming and organization.
- ✅ Namespace `service_urls/` clearly conveys purpose
- ✅ Files `compact.rs` and `dns_hint.rs` are descriptive
- ✅ Pure view helpers - no DTOs to separate
- ✅ Proposed rename would add churn without meaningful improvement

#### Benefits
**Proposed structure drawbacks**:

- ✅ Clearer purpose of shared directory
- ✅ Consistent with overall structure
- ✅ Easier to find reusable components
- ❌ `view_components/` is too generic (loses semantic meaning)
- ❌ Would break imports in `run` controller unnecessarily
- ❌ No architectural benefit gained

#### Implementation Checklist

- [ ] Analyze current shared components
- [ ] Rename directory if appropriate
- [ ] Separate data/view if needed
- [ ] Update all imports across codebase
- [ ] Verify all tests pass
- [ ] Run linter and fix any issues
- [x] Analyze current shared components
- [x] Conclude no changes needed
- [x] Update refactor plan with rationale

#### Testing Strategy

Expand All @@ -506,7 +510,7 @@ cargo run --bin linter all
- **Start Date**: 2026-02-16
- **Estimated Duration**: 2-3 hours
- **Target Completion**: 2026-02-16 (same day)
- **Actual Completion**: TBD
- **Actual Completion**: 2026-02-16

## 🔍 Review Process

Expand All @@ -520,13 +524,13 @@ cargo run --bin linter all

### Completion Criteria

- [ ] All 5 proposals implemented
- [ ] All 2200+ tests passing
- [ ] All linters passing (markdown, yaml, toml, cspell, clippy, rustfmt, shellcheck)
- [ ] No unused dependencies (cargo machete)
- [ ] Module-level documentation updated
- [ ] Architecture documentation updated (`docs/codebase-architecture.md`)
- [ ] Contributing guide updated (`docs/contributing/ddd-layer-placement.md`)
- [x] All 5 proposals reviewed (4 implemented, 1 discarded as not needed)
- [x] All 396 tests passing
- [x] All linters passing (markdown, yaml, toml, cspell, clippy, rustfmt, shellcheck)
- [x] No unused dependencies (cargo machete)
- [x] Module-level documentation updated
- [ ] Architecture documentation updated (`docs/codebase-architecture.md`) - if needed
- [ ] Contributing guide updated (`docs/contributing/ddd-layer-placement.md`) - if needed
- [ ] Changes reviewed and approved
- [ ] Changes merged to main branch

Expand Down Expand Up @@ -563,4 +567,4 @@ Future state: DTOs with presentation logic (rename to: `view_models/`)

**Created**: 2026-02-16
**Last Updated**: 2026-02-16
**Status**: 📋 Planning
**Status**: ✅ Complete
5 changes: 2 additions & 3 deletions src/presentation/controllers/list/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use parking_lot::ReentrantMutex;
use crate::application::command_handlers::list::info::EnvironmentList;
use crate::application::command_handlers::list::{ListCommandHandler, ListCommandHandlerError};
use crate::infrastructure::persistence::repository_factory::RepositoryFactory;
use crate::presentation::views::commands::list::EnvironmentListView;
use crate::presentation::views::commands::list::TextView;
use crate::presentation::views::progress::ProgressReporter;
use crate::presentation::views::UserOutput;

Expand Down Expand Up @@ -144,8 +144,7 @@ impl ListCommandController {
.start_step(ListStep::DisplayResults.description())?;

// Pipeline: EnvironmentList → render → output to stdout
self.progress
.result(&EnvironmentListView::render(env_list))?;
self.progress.result(&TextView::render(env_list))?;

self.progress.complete_step(Some("Results displayed"))?;

Expand Down
7 changes: 3 additions & 4 deletions src/presentation/controllers/show/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use crate::application::command_handlers::show::info::EnvironmentInfo;
use crate::application::command_handlers::show::{ShowCommandHandler, ShowCommandHandlerError};
use crate::domain::environment::name::EnvironmentName;
use crate::domain::environment::repository::EnvironmentRepository;
use crate::presentation::views::commands::show::EnvironmentInfoView;
use crate::presentation::views::commands::show::TextView;
use crate::presentation::views::progress::ProgressReporter;
use crate::presentation::views::UserOutput;

Expand Down Expand Up @@ -185,7 +185,7 @@ impl ShowCommandController {
///
/// Following the MVC pattern with functional composition:
/// - Model: `EnvironmentInfo` (application layer DTO)
/// - View: `EnvironmentInfoView::render()` (formatting)
/// - View: `TextView::render()` (formatting)
/// - Controller (this method): Orchestrates the pipeline
/// - Output: `ProgressReporter::result()` (routing to stdout)
fn display_information(
Expand All @@ -196,8 +196,7 @@ impl ShowCommandController {
.start_step(ShowStep::DisplayInformation.description())?;

// Pipeline: EnvironmentInfo → render → output to stdout
self.progress
.result(&EnvironmentInfoView::render(env_info))?;
self.progress.result(&TextView::render(env_info))?;

self.progress.complete_step(Some("Information displayed"))?;

Expand Down
28 changes: 20 additions & 8 deletions src/presentation/views/commands/create/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@
//! - `TextView`: Renders human-readable text output
//! - `JsonView`: Renders machine-readable JSON output
//!
//! # Structure
//!
//! - `view_data/`: Data structures (DTOs) prepared for view rendering
//! - `views/`: View implementations (text, JSON, etc.)
//!
//! # SOLID Principles
//!
//! - **Single Responsibility**: Each view has one job - render in its format
Expand All @@ -19,16 +24,23 @@
//! # Adding New Formats
//!
//! To add a new output format (e.g., XML, YAML, CSV):
//! 1. Create a new file: `xml_view.rs`, `yaml_view.rs`, etc.
//! 1. Create a new file in `views/`: `xml_view.rs`, `yaml_view.rs`, etc.
//! 2. Implement the view with `render(data: &EnvironmentDetailsData) -> Result<String, Error>`
//! 3. Export it from this module
//! 3. Export it from the `views` module
//! 4. No need to modify existing views or the DTO

pub mod environment_details;
pub mod json_view;
pub mod text_view;
pub mod view_data {
pub mod environment_details;
pub use environment_details::EnvironmentDetailsData;
}

pub mod views {
pub mod json_view;
pub mod text_view;
pub use json_view::JsonView;
pub use text_view::TextView;
}

// Re-export main types for convenience
pub use environment_details::EnvironmentDetailsData;
pub use json_view::JsonView;
pub use text_view::TextView;
pub use view_data::EnvironmentDetailsData;
pub use views::{JsonView, TextView};
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
//! It follows the Strategy Pattern, providing one specific rendering strategy
//! (machine-readable JSON) for environment details.

use super::environment_details::EnvironmentDetailsData;
use super::super::EnvironmentDetailsData;

/// JSON view for rendering environment creation details
///
Expand Down
Loading
Loading