Skip to content

Proposal 2: Create Dispatch Layer #156

@josecelano

Description

@josecelano

Overview

Extract command routing logic into an explicit Dispatch Layer with src/presentation/dispatch/router.rs and ExecutionContext. This separates routing from command execution and creates a clean pattern for controllers to access dependencies.

Parent Epic: #154 - Presentation Layer Reorganization
Depends On: #155 (Proposal 1: Create Input Layer)
Related: Refactor Plan | Design Proposal

Impact: 🟢🟢🟢 High - Separates routing from execution, enables clean controller pattern
Effort: 🔵🔵 Medium - Extract routing logic, create ExecutionContext
Estimated Time: 2-3 hours

Goals

  • Create src/presentation/dispatch/ directory with router and context modules
  • Extract routing logic from src/main.rs and commands/mod.rs into route_command()
  • Create ExecutionContext wrapper around Container for command execution
  • Update src/main.rs to use new router
  • Add module documentation explaining dispatch layer's purpose
  • Document as second step in refactor plan
  • Ensure old commands/ directory remains functional

🏗️ Architecture Requirements

DDD Layer: Presentation
Module Path: src/presentation/dispatch/
Pattern: Dispatch Layer (Layer 2 of 4-layer presentation architecture)

Target Structure

After this proposal:

src/presentation/
├── input/                    # Layer 1 - CLI parsing
├── dispatch/                 # ← NEW: Layer 2 - Routing & context
│   ├── mod.rs                #    Re-exports router and context
│   ├── router.rs             #    route_command() function
│   └── context.rs            #    ExecutionContext wrapper
├── commands/                 # ← UNCHANGED (for now)
├── user_output/              # ← UNCHANGED (for now)
├── progress.rs               # ← UNCHANGED (for now)
└── errors.rs                 # ← UNCHANGED

Implementation Plan

Phase 1: Create Directory Structure (30 minutes)

  • Create src/presentation/dispatch/ directory
  • Create src/presentation/dispatch/mod.rs with module documentation
  • Create empty src/presentation/dispatch/router.rs
  • Create empty src/presentation/dispatch/context.rs
  • Update src/presentation/mod.rs to include pub mod dispatch;

Phase 2: Implement ExecutionContext (45 minutes)

  • Implement ExecutionContext struct in context.rs
  • Add new() constructor accepting Arc<Container>
  • Add container() accessor method
  • Add service accessor methods:
    • opentofu_client()
    • ansible_client()
    • environment_repository()
    • clock()
  • Add module documentation
  • Verify compilation: cargo check

Phase 3: Implement Router (60 minutes)

  • Analyze current routing logic in src/main.rs and commands/mod.rs
  • Implement route_command() function in router.rs:
    • Match on Commands enum
    • Route each command to existing handler functions
    • Pass ExecutionContext to handlers
    • Handle errors and propagate to caller
  • Add function documentation with examples
  • Update command handlers to accept &ExecutionContext parameter
  • Verify compilation: cargo check

Phase 4: Update Main Entry Point (30 minutes)

  • Update src/main.rs to use new router
  • Remove old routing logic from main.rs
  • Verify compilation: cargo check

Phase 5: Documentation Updates (30 minutes)

  • Add completion note to refactor plan
  • Update README.md if it references routing logic
  • Verify all documentation links work

Phase 6: Testing & Verification (30 minutes)

  • Run pre-commit checks: ./scripts/pre-commit.sh
  • Verify all commands work
  • Test actual command execution
  • Verify no compilation warnings

Acceptance Criteria

Note for Contributors: These criteria define what the PR reviewer will check. Use this as your pre-review checklist before submitting the PR.

Quality Checks:

  • Pre-commit checks pass: ./scripts/pre-commit.sh

Structure:

  • src/presentation/dispatch/ directory exists
  • src/presentation/dispatch/mod.rs contains module documentation
  • src/presentation/dispatch/router.rs contains route_command() function
  • src/presentation/dispatch/context.rs contains ExecutionContext struct

Routing:

  • route_command() handles all CLI commands
  • All commands route to correct handlers
  • Routing logic extracted from main.rs
  • src/main.rs uses new router

ExecutionContext:

  • ExecutionContext wraps Container
  • Provides service accessor methods
  • Command handlers accept &ExecutionContext parameter
  • Thread-safe (Send + Sync)

Functionality:

  • All CLI commands work as before
  • Command execution unchanged
  • Error handling works correctly
  • Old commands/ directory still functional

Documentation:

  • dispatch/mod.rs explains dispatch layer purpose
  • router.rs has comprehensive function documentation
  • context.rs documents ExecutionContext usage
  • References refactor plan for context
  • Refactor plan updated with completion status

Mergeable State:

  • Code compiles without warnings
  • All tests pass
  • Documentation accurate
  • Ready to merge to main
  • No intermediate or broken state

📚 Related Documentation


Created: November 6, 2025
Status: Ready for Implementation (after Proposal 1 completes)
Next Action: Wait for Proposal 1 completion, then begin Phase 1

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions