Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 86 additions & 5 deletions docs/codebase-architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@ The project follows **Domain-Driven Design** principles with a layered architect

```text
┌─────────────────────────────────────┐
│ Presentation Layer │
│ (CLI, User Output, Command │
│ Dispatch, Error Display) │
│ src/presentation/ │
└────────────┬────────────────────────┘
│ depends on
┌─────────────────────────────────────┐
│ Application Layer │
│ (Commands, Use Cases, Steps) │
│ src/application/ │
Expand All @@ -35,6 +43,18 @@ The project follows **Domain-Driven Design** principles with a layered architect

### Layer Responsibilities

**Presentation Layer** (`src/presentation/`):

- **Purpose**: User interface and interaction handling
- **Contains**: CLI parsing, command dispatch, user output, error presentation, help systems
- **Rules**: Depends on application layer, handles all user-facing concerns
- **Example**: CLI subcommands calling application command handlers with user-friendly error messages
- **Module Structure**:
- `cli/` - Command-line argument parsing and validation
- `commands/` - Command execution handlers and dispatch logic
- `errors.rs` - Unified error types with tiered help system
- `user_output.rs` - User-facing output management and verbosity control

**Domain Layer** (`src/domain/`):

- **Purpose**: Core business logic and domain entities
Expand All @@ -58,14 +78,16 @@ The project follows **Domain-Driven Design** principles with a layered architect

### Dependency Rule

The fundamental rule is that **dependencies flow inward**:
The fundamental rule is that **dependencies flow inward toward the domain**:

- Presentation → Application → Domain (✅ Correct)
- Infrastructure → Domain (✅ Correct)
- Application → Domain (✅ Correct)
- Domain → Infrastructure (❌ Forbidden)
- Domain → Application (❌ Forbidden)
- Domain → Infrastructure (❌ Forbidden)
- Domain → Presentation (❌ Forbidden)
- Application → Presentation (❌ Forbidden)

This ensures the domain layer remains pure business logic, free from technical implementation details.
This ensures the domain layer remains pure business logic, free from technical implementation details and user interface concerns. The presentation layer orchestrates the application layer but never contains business logic.

## 🏗️ Three-Level Architecture Pattern

Expand Down Expand Up @@ -181,6 +203,21 @@ All modules include comprehensive `//!` documentation with:
- ✅ `src/bin/e2e-provision-and-destroy-tests.rs` - E2E provisioning and destruction tests
- ✅ `src/bin/e2e-tests-full.rs` - Full E2E test suite

### Presentation Layer

**CLI Interface and User Interaction:**

- ✅ `src/presentation/mod.rs` - Presentation layer root module with exports
- ✅ `src/presentation/cli/` - Command-line interface parsing and structure
- `cli/mod.rs` - Main Cli struct and global argument definitions
- `cli/args.rs` - Global CLI arguments (logging configuration)
- `cli/commands.rs` - Subcommand definitions (destroy, future commands)
- ✅ `src/presentation/commands/` - Command execution handlers
- `commands/mod.rs` - Unified command dispatch and error handling
- `commands/destroy.rs` - Destroy command handler with error management
- ✅ `src/presentation/errors.rs` - Unified error types with tiered help system
- ✅ `src/presentation/user_output.rs` - User-facing output management and verbosity control

### Domain Layer

**Core Domain Entities:**
Expand Down Expand Up @@ -381,11 +418,55 @@ The typical deployment flow follows this pattern:
## 📊 Module Statistics

- **Total Modules**: ~100+ Rust files
- **Architecture Layers**: 3 (Domain, Application, Infrastructure) + Shared
- **Architecture Layers**: 4 (Presentation, Application, Domain, Infrastructure) + Shared
- **External Tool Integrations**: 3 (OpenTofu, Ansible, LXD)
- **Step Categories**: 7 (Infrastructure, System, Software, Validation, Connectivity, Application, Rendering)
- **State Types**: 13+ environment states with type-state pattern

## 🏗️ Architectural Guidance for Development

When working on this codebase, follow these guidelines to maintain architectural integrity:

### Layer Selection Guide

**When creating new functionality, choose the appropriate layer:**

- **Presentation Layer** (`src/presentation/`): CLI commands, user output, error display, input validation
- **Application Layer** (`src/application/`): Use cases, command orchestration, workflow coordination
- **Domain Layer** (`src/domain/`): Business entities, value objects, domain rules, state machines
- **Infrastructure Layer** (`src/infrastructure/`): External tool integration, file operations, remote actions

### Module Placement Rules

1. **CLI and User Interface**: Always in `src/presentation/`
2. **Business Logic**: Always in `src/domain/`
3. **Use Case Orchestration**: Always in `src/application/`
4. **External Integration**: Always in `src/infrastructure/`
5. **Cross-Layer Utilities**: Only in `src/shared/` (use sparingly)

### Dependency Guidelines

- ✅ **Allowed**: Presentation → Application → Domain ← Infrastructure
- ❌ **Forbidden**: Domain depending on any other layer
- ❌ **Forbidden**: Application depending on Presentation or Infrastructure
- ❌ **Forbidden**: Circular dependencies between any layers

### Implementation Patterns

- **Error Handling**: Use structured enums with `thiserror`, implement tiered help systems
- **Module Organization**: Follow [docs/contributing/module-organization.md](../docs/contributing/module-organization.md)
- **Testing**: Layer-appropriate testing (unit tests per layer, integration tests across layers)

### Quality Assurance

Before implementing new features:

1. **Identify the correct layer** based on the functionality's purpose
2. **Check architectural constraints** - ensure no forbidden dependencies
3. **Follow module organization** - public before private, important before secondary
4. **Implement proper error handling** - structured errors with actionable messages
5. **Add comprehensive tests** - appropriate for the layer and functionality

## 💡 Key Design Principles

- **Domain-Driven Design**: Pure domain logic independent of infrastructure
Expand Down
20 changes: 16 additions & 4 deletions docs/contributing/roadmap-issues.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,15 @@ Create a detailed specification in `docs/issues/` with temporary name:

```bash
# Copy the template to create your specification document
cp docs/issues/TEMPLATE.md docs/issues/setup-logging-for-production-cli.md
cp docs/issues/SPECIFICATION-TEMPLATE.md docs/issues/setup-logging-for-production-cli.md

# Edit the document to fill in all sections
vim docs/issues/setup-logging-for-production-cli.md
```

#### Document Structure

Use the template at [`docs/issues/TEMPLATE.md`](../issues/TEMPLATE.md) as your starting point. The template includes:
Use the template at [`docs/issues/SPECIFICATION-TEMPLATE.md`](../issues/SPECIFICATION-TEMPLATE.md) as your starting point. The template includes:

- **Header**: Issue number, parent epic, and related links
- **Overview**: Clear description of what the task accomplishes
Expand All @@ -71,6 +71,18 @@ Use the template at [`docs/issues/TEMPLATE.md`](../issues/TEMPLATE.md) as your s
- **Provide Context**: Link to related documentation, ADRs, and examples
- **Estimate Time**: Help others understand scope
- **Define Success**: Clear acceptance criteria
- **Specify Architecture**: Include DDD layer, module path, and architectural constraints (see template guidance below)

#### Architectural Requirements

When creating issues that involve code changes, always specify:

- **DDD Layer**: Which layer the change belongs to (Presentation, Application, Domain, Infrastructure)
- **Module Path**: Exact location in the codebase (`src/{layer}/{module}/`)
- **Architectural Constraints**: Dependencies, patterns, and anti-patterns to follow
- **Related Documentation**: Link to [docs/codebase-architecture.md](../docs/codebase-architecture.md) and other relevant architectural guidance

This ensures AI assistants and contributors understand not just **what** to implement, but **where** and **how** to implement it within the project's architectural patterns.

### Step 2: Create GitHub Epic Issue (if needed)

Expand Down Expand Up @@ -100,7 +112,7 @@ If this is the first task in a roadmap section, create an epic issue first:

2. **Click "New Issue"**

3. **Fill in Task Details**: Use the template at [`docs/issues/TASK-TEMPLATE.md`](../issues/TASK-TEMPLATE.md) and fill in:
3. **Fill in Task Details**: Use the template at [`docs/issues/GITHUB-ISSUE-TEMPLATE.md`](../issues/GITHUB-ISSUE-TEMPLATE.md) and fill in:

- Title with the task name from roadmap
- Overview with brief description
Expand Down Expand Up @@ -223,7 +235,7 @@ Implementing roadmap task **1.1 Setup logging**

```bash
# 1. Create initial specification document from template
cp docs/issues/TEMPLATE.md docs/issues/setup-logging-for-production-cli.md
cp docs/issues/SPECIFICATION-TEMPLATE.md docs/issues/setup-logging-for-production-cli.md
vim docs/issues/setup-logging-for-production-cli.md
# ... fill in all sections: overview, goals, specs, implementation plan ...

Expand Down
18 changes: 9 additions & 9 deletions docs/issues/23-add-clap-subcommand-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ pub enum Commands {

### VerbosityLevel Implementation

Create `src/shared/user_output.rs`:
Create `src/presentation/user_output.rs`:

```rust
/// Verbosity levels for user output
Expand Down Expand Up @@ -303,7 +303,7 @@ Update command execution in `src/app.rs`:
```rust
async fn handle_destroy_command(environment: String) -> anyhow::Result<()> {
use crate::application::command_handlers::destroy::DestroyCommandHandler;
use crate::shared::user_output::{UserOutput, VerbosityLevel};
use crate::presentation::user_output::{UserOutput, VerbosityLevel};

// Create UserOutput with default stdout/stderr channels
let mut output = UserOutput::new(VerbosityLevel::Normal);
Expand Down Expand Up @@ -405,13 +405,13 @@ output.error("Failed to destroy environment 'my-env': OpenTofu destroy operation

### Subtask 1: Implement VerbosityLevel and UserOutput (1.5 hours)

- [ ] Create `src/shared/user_output.rs`
- [ ] Implement `VerbosityLevel` enum with 5 levels
- [ ] Implement `UserOutput` struct with dual writers (stdout/stderr)
- [ ] Add methods: `progress`, `success`, `warn`, `error` (stderr), `result`, `data` (stdout)
- [ ] Add constructor for default channels and testing with custom writers
- [ ] Document channel usage strategy based on console patterns research
- [ ] Update `src/shared/mod.rs` to export new module
- [x] Create `src/presentation/user_output.rs` (moved from shared to presentation layer)
- [x] Implement `VerbosityLevel` enum with 5 levels
- [x] Implement `UserOutput` struct with dual writers (stdout/stderr)
- [x] Add methods: `progress`, `success`, `warn`, `error` (stderr), `result`, `data` (stdout)
- [x] Add constructor for default channels and testing with custom writers
- [x] Document channel usage strategy based on console patterns research
- [x] Update `src/presentation/mod.rs` to export new module

### Subtask 2: Add Destroy Subcommand to Clap (45 minutes)

Expand Down
57 changes: 57 additions & 0 deletions docs/issues/GITHUB-ISSUE-TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
Title: [Task Name from Roadmap]

## Overview

[Brief description of what this task accomplishes]

## Specification

See detailed specification: [docs/issues/{number}-{name}.md](../docs/issues/{number}-{name}.md)

(Link will be updated after file rename)

## 🏗️ Architecture Requirements

**DDD Layer**: [Domain | Application | Infrastructure | Presentation]
**Module Path**: `src/{layer}/{module}/`
**Pattern**: [Command | Step | Action | CLI Subcommand | Entity | Value Object | Repository]

### Module Structure Requirements

- [ ] Follow DDD layer separation (see [docs/codebase-architecture.md](../docs/codebase-architecture.md))
- [ ] Respect dependency flow rules (dependencies flow toward domain)
- [ ] Use appropriate module organization (see [docs/contributing/module-organization.md](../docs/contributing/module-organization.md))

### Architectural Constraints

- [ ] No business logic in presentation layer
- [ ] Error handling follows project conventions (see [docs/contributing/error-handling.md](../docs/contributing/error-handling.md))
- [ ] Testing strategy aligns with layer responsibilities

### Anti-Patterns to Avoid

- ❌ Mixing concerns across layers
- ❌ Domain layer depending on infrastructure
- ❌ Monolithic modules with multiple responsibilities

## Implementation Plan

### Phase 1: [Phase Name]

- [ ] Task 1.1
- [ ] Task 1.2

### Phase 2: [Phase Name]

- [ ] Task 2.1

## Acceptance Criteria

- [ ] Criterion 1
- [ ] Criterion 2

## Related

- Parent: #X (Epic: [Epic Name])
- Roadmap: #1 (Project Roadmap)
- Specification: docs/issues/{number}-{name}.md
24 changes: 24 additions & 0 deletions docs/issues/TEMPLATE.md → docs/issues/SPECIFICATION-TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,30 @@
- [ ] Goal 2
- [ ] Goal 3

## 🏗️ Architecture Requirements

**DDD Layer**: [Domain | Application | Infrastructure | Presentation]
**Module Path**: `src/{layer}/{module}/`
**Pattern**: [Command | Step | Action | CLI Subcommand | Entity | Value Object | Repository]

### Module Structure Requirements

- [ ] Follow DDD layer separation (see [docs/codebase-architecture.md](../docs/codebase-architecture.md))
- [ ] Respect dependency flow rules (dependencies flow toward domain)
- [ ] Use appropriate module organization (see [docs/contributing/module-organization.md](../docs/contributing/module-organization.md))

### Architectural Constraints

- [ ] No business logic in presentation layer
- [ ] Error handling follows project conventions (see [docs/contributing/error-handling.md](../docs/contributing/error-handling.md))
- [ ] Testing strategy aligns with layer responsibilities

### Anti-Patterns to Avoid

- ❌ Mixing concerns across layers
- ❌ Domain layer depending on infrastructure
- ❌ Monolithic modules with multiple responsibilities

## Specifications

### [Specification Section 1]
Expand Down
33 changes: 0 additions & 33 deletions docs/issues/TASK-TEMPLATE.md

This file was deleted.

1 change: 1 addition & 0 deletions project-words.txt
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ Pulumi
pytest
RAII
Repomix
reprovisioning
reqwest
resolv
rgba
Expand Down
Loading