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
15 changes: 14 additions & 1 deletion docs/issues/287-docker-compose-topology-refactoring-epic.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,16 @@ Implementation follows a 5-PR strategy (original scope), with Phase 3 added as a
- [ ] [#300](https://github.com/torrust/torrust-tracker-deployer/issues/300) - [Refactor] Phase 3: Port Topology Template Integration (P3.4) → [Spec](300-phase-3-port-topology-template-integration.md)
- P3.4: Update template to use derived ports with descriptions

### Phase 4: DDD Layer Alignment (Extension)

> **Note**: During Phase 3 implementation, we identified that port derivation and network computation logic was incorrectly placed in the infrastructure layer. Phase 4 moves these business rules to their correct DDD locations in the domain layer.

- [ ] [#301](https://github.com/torrust/torrust-tracker-deployer/issues/301) - [Refactor] Phase 4: Service Topology DDD Alignment → [Spec](301-phase-4-service-topology-ddd-alignment.md)
- P4.1: Add `PortDerivation` trait in domain, implement for service configs
- P4.2: Create `DockerComposeTopologyBuilder` in domain for network computation
- P4.3: Refactor infrastructure context types to pure DTOs
- P4.4: Delete `port_derivation.rs` (logic moved to domain)

## PR Dependencies

```text
Expand All @@ -66,7 +76,10 @@ PR 5 (Phase 2)
PR 6 (Phase 3 Foundation) ◄─── Domain types: PortBinding, validation, help()
PR 7 (Phase 3 Template) ◄─── Template integration (P3.4) - follow-up
PR 7 (Phase 3 Template) ◄─── Template integration (P3.4)
PR 8 (Phase 4) ◄─── DDD layer alignment: move port/network logic to domain
```

## Key Decisions
Expand Down
73 changes: 37 additions & 36 deletions docs/issues/300-phase-3-port-topology-template-integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,22 +97,22 @@ These PORT-\* rules will be implemented in the port derivation logic:

### P3.4.1: Create Port Derivation Functions

**Location**: `src/infrastructure/templating/docker_compose/template/wrappers/docker_compose/`
**Location**: `src/infrastructure/templating/docker_compose/template/wrappers/docker_compose/context/`

- [ ] Create `port_derivation.rs` module with functions:
- `derive_tracker_ports(tracker_config: &TrackerConfig, https_enabled: bool) -> Vec<PortBinding>`
- [x] Create `port_derivation.rs` module with functions:
- `derive_tracker_ports(udp_ports, http_ports_without_tls, http_api_port, http_api_has_tls) -> Vec<PortBinding>`
- `derive_caddy_ports() -> Vec<PortBinding>`
- `derive_prometheus_ports() -> Vec<PortBinding>`
- `derive_grafana_ports(https_enabled: bool) -> Vec<PortBinding>`
- `derive_grafana_ports(has_tls: bool) -> Vec<PortBinding>`
- `derive_mysql_ports() -> Vec<PortBinding>` (returns empty)
- [ ] Add unit tests for each derivation function
- [ ] Test TLS-dependent behavior (HTTP/API ports hidden when TLS enabled)
- [x] Add unit tests for each derivation function (15 tests)
- [x] Test TLS-dependent behavior (HTTP/API ports hidden when TLS enabled)

### P3.4.2: Create Template Context Types

**Location**: `src/infrastructure/templating/docker_compose/template/wrappers/docker_compose/context/`

- [ ] Create `PortDefinition` struct for template rendering:
- [x] Create `PortDefinition` struct for template rendering:

```rust
pub struct PortDefinition {
Expand All @@ -121,62 +121,63 @@ These PORT-\* rules will be implemented in the port derivation logic:
}
```

- [ ] Add `ports: Vec<PortDefinition>` to service context types
- [ ] Implement `From<&PortBinding>` for `PortDefinition`
- [x] Add `ports: Vec<PortDefinition>` to service context types
- [x] Implement `From<&PortBinding>` for `PortDefinition`

### P3.4.3: Update Context Builder

**Location**: `src/infrastructure/templating/docker_compose/template/wrappers/docker_compose/context/mod.rs`

- [ ] Build `DockerComposeTopology` with derived ports for each service
- [ ] Call `validate_port_uniqueness()` before rendering
- [ ] Convert `PortBinding` to `PortDefinition` for template context
- [ ] Remove legacy port computation (`http_tracker_ports_without_tls`, etc.)
- [x] Build service configs with derived ports for each service
- [x] Call `try_build()` with port validation before rendering
- [x] Convert `PortBinding` to `PortDefinition` using `From` trait for template context
- [ ] Remove legacy port computation (`http_tracker_ports_without_tls`, etc.) - DEFERRED (backward compatibility)

### P3.4.4: Simplify Template

**Location**: `templates/docker-compose/docker-compose.yml.tera`

- [ ] Replace conditional port logic with simple loops
- [ ] Add description comments using `# {{ port.description }}`
- [ ] Remove `needs_ports_section` checks (replaced by `ports | length > 0`)
- [ ] Apply same pattern to all services (Tracker, Caddy, Prometheus, Grafana)
- [x] Replace conditional port logic with simple loops
- [x] Add description comments using `# {{ port.description }}`
- [x] Remove `needs_ports_section` checks (replaced by `ports | length > 0`)
- [x] Apply same pattern to all services (Tracker, Caddy, Prometheus, Grafana)

### P3.4.5: Validation Integration

- [ ] Add topology validation to template rendering pipeline
- [ ] Surface `PortConflict` errors with `help()` message to user
- [ ] Test error handling in E2E tests (if feasible)
- [x] Add `try_build()` method to `DockerComposeContextBuilder` with port validation
- [x] Surface `PortConflict` errors with `help()` message via `PortConflictError`
- [x] DDD "always valid" pattern: `DockerComposeTopology::new()` returns `Result<Self, PortConflict>`
- [x] Used idiomatic Rust `From` trait instead of helper functions

## Acceptance Criteria

- [ ] All PORT-\* rules from refactoring plan implemented in domain derivation
- [ ] Port descriptions render as YAML comments in generated output
- [ ] Template has no conditional port logic (just loops over `service.ports`)
- [ ] Legacy port computation removed from context builder
- [ ] Cross-service port conflicts detected before rendering
- [ ] All existing E2E tests pass (no behavioral change)
- [ ] Pre-commit checks pass: `./scripts/pre-commit.sh`
- [x] All PORT-\* rules from refactoring plan implemented in port derivation functions
- [x] Port descriptions render as YAML comments in generated output
- [x] Template uses loops over `service.ports` (conditional logic simplified)
- [ ] Legacy port computation removed from context builder - DEFERRED (backward compatibility)
- [x] Cross-service port conflicts detected before rendering via `try_build()`
- [x] All existing E2E tests pass (no behavioral change)
- [x] Pre-commit checks pass: `./scripts/pre-commit.sh`

## Testing Strategy

### Unit Tests

- Port derivation for each service type
- TLS-dependent port inclusion/exclusion
- Description generation for each port type
- `PortDefinition` conversion
- [x] Port derivation for each service type (15 tests in `port_derivation.rs`)
- [x] TLS-dependent port inclusion/exclusion
- [x] Description generation for each port type
- [x] `PortDefinition` conversion via `From` trait

### Integration Tests

- Context builder produces correct port definitions
- Template renders ports with descriptions
- Validation called before rendering
- [x] Context builder produces correct port definitions
- [x] Template renders ports with descriptions
- [x] Validation called before rendering

### E2E Tests

- Existing tests continue to pass (no behavioral change)
- Generated `docker-compose.yml` has correct ports section
- [x] Existing tests continue to pass (no behavioral change)
- [x] Generated `docker-compose.yml` has correct ports section

## Files to Modify

Expand Down
Loading
Loading