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
20 changes: 14 additions & 6 deletions docs/issues/287-docker-compose-topology-refactoring-epic.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,14 @@ Implementation follows a 5-PR strategy (original scope), with Phase 3 added as a
### Phase 3: Port Topology (Added Extension)

> **Note**: Phase 3 was part of the original refactoring plan analysis (see PORT-01 through PORT-11 rules in [docker-compose-topology-domain-model.md](../refactors/plans/docker-compose-topology-domain-model.md#port-exposure-rules)) but was not included in the initial 5-PR strategy. It follows the same pattern as networks and completes the topology domain model.

- [ ] [#298](https://github.com/torrust/torrust-tracker-deployer/issues/298) - [Refactor] Phase 3: Create Port Topology Domain Model (P3.1, P3.2, P3.3, P3.4) → [Spec](298-phase-3-port-topology-domain-model.md)
- P3.1: Create Port domain types (`PortBinding`, `Protocol`)
- P3.2: Extend `ServiceTopology` with port derivation
- P3.3: Add cross-service port conflict validation
>
> **Implementation Note**: Phase 3 is split into two PRs for better reviewability. PR #298 delivers the domain layer foundation (P3.1-P3.3), while a follow-up PR will integrate ports into the template (P3.4).

- [ ] [#298](https://github.com/torrust/torrust-tracker-deployer/issues/298) - [Refactor] Phase 3: Port Topology Domain Model - Foundation (P3.1, P3.2, P3.3) → [Spec](298-phase-3-port-topology-domain-model.md)
- P3.1: Create Port domain types (`PortBinding`, reuse `Protocol`)
- P3.2: Extend `ServiceTopology` with ports field
- P3.3: Add cross-service port conflict validation with `help()` method
- [ ] TBD - [Refactor] Phase 3: Port Topology Template Integration (P3.4)
- P3.4: Update template to use derived ports with descriptions

## PR Dependencies
Expand All @@ -60,7 +63,10 @@ PR 4 (Phase 1)
PR 5 (Phase 2)
PR 6 (Phase 3) ◄─── Extension: Port topology (added post-completion)
PR 6 (Phase 3 Foundation) ◄─── Domain types: PortBinding, validation, help()
PR 7 (Phase 3 Template) ◄─── Template integration (P3.4) - follow-up
```

## Key Decisions
Expand All @@ -71,6 +77,8 @@ PR 6 (Phase 3) ◄─── Extension: Port topology (added post-completion)
- ~47 domain rules identified with test specifications
- Network descriptions rendered as YAML comments for sysadmin documentation
- Port topology follows same pattern as networks (Phase 3)
- Phase 3 split into foundation (domain) and integration (template) PRs for reviewability
- `PortConflict` error includes `help()` method per DDD error handling conventions

## Related

Expand Down
71 changes: 47 additions & 24 deletions docs/issues/298-phase-3-port-topology-domain-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,16 @@

**Epic**: [#287](https://github.com/torrust/torrust-tracker-deployer/issues/287) - Docker Compose Topology Domain Model Refactoring
**Related Plan**: [docs/refactors/plans/docker-compose-topology-domain-model.md](../../refactors/plans/docker-compose-topology-domain-model.md)
**Status**: Draft
**Status**: In Progress (P3.1-P3.3 Complete)

## Implementation Notes

> **PR Strategy**: This phase is split into two PRs for better reviewability:
>
> - **PR #298 (this PR)**: Domain layer foundation - P3.1, P3.2, P3.3
> - **Follow-up PR**: Template integration - P3.4
>
> The domain types are stable and well-tested. Template integration is a larger change that benefits from being a separate, focused PR.

## Overview

Expand Down Expand Up @@ -177,46 +186,60 @@ services:

## Tasks

### P3.1: Create Port Domain Types
### P3.1: Create Port Domain Types

- [ ] Create `Protocol` enum (or reuse from `domain/tracker`)
- [ ] Create `PortBinding` struct with description support
- [ ] Add `PortDefinition` context type for template rendering
- [ ] Add unit tests for port binding creation
- [x] Reuse `Protocol` enum from `domain/tracker/protocol.rs`
- [x] Create `PortBinding` struct with description support
- [x] Add convenience constructors: `tcp()`, `udp()`, `localhost_tcp()`
- [x] Add `docker_compose_binding()` method for YAML rendering
- [x] Add unit tests for port binding creation (10 tests)

### P3.2: Extend ServiceTopology with Ports
### P3.2: Extend ServiceTopology with Ports

- [ ] Add `ports: Vec<PortBinding>` to `ServiceTopology`
- [ ] Implement port derivation for each service type:
- Tracker: UDP ports, HTTP ports (TLS-dependent), API (TLS-dependent)
- Caddy: 80, 443, 443/udp (fixed)
- Prometheus: 9090 (localhost)
- Grafana: 3000 (TLS-dependent)
- MySQL: none
- [ ] Add unit tests for each service's port derivation
- [x] Add `ports: Vec<PortBinding>` to `ServiceTopology`
- [x] Add `new()` constructor with ports parameter
- [x] Add `with_networks()` for backward compatibility
- [x] Add `ports()` and `has_ports()` getters with `#[must_use]`
- [x] Make all fields private with getters (DDD compliance)
- [x] Add unit tests for port field (4 tests)

### P3.3: Add Cross-Service Port Validation
### P3.3: Add Cross-Service Port Validation

- [ ] Implement `DockerComposeTopology::validate_port_uniqueness()`
- [ ] Create `TopologyError::PortConflict` variant
- [ ] Add tests for conflict detection scenarios
- [x] Implement `DockerComposeTopology::validate_port_uniqueness()`
- [x] Create `PortConflict` error type with full context
- [x] Create `TopologyError` enum with `help()` method (DDD error conventions)
- [x] Add tests for conflict detection scenarios (6 tests)

### P3.4: Update Template and Context
### P3.4: Update Template and Context (Follow-up PR)

- [ ] Create `PortDefinition` with `binding()` and `description()` for template
- [ ] Update `DockerComposeContext` to use derived ports
- [ ] Simplify `docker-compose.yml.tera` port sections
- [ ] Remove conditional port logic from template
- [ ] Implement port derivation for each service type:
- Tracker: UDP ports, HTTP ports (TLS-dependent), API (TLS-dependent)
- Caddy: 80, 443, 443/udp (fixed)
- Prometheus: 9090 (localhost)
- Grafana: 3000 (TLS-dependent)
- MySQL: none

## Acceptance Criteria

### PR #298 (Domain Foundation) ✅

- [x] `PortBinding` type with description support created
- [x] `ServiceTopology` extended with ports field
- [x] Cross-service port conflicts detected with actionable `help()` message
- [x] All fields private with getters (DDD compliance)
- [x] No duplication with `TrackerConfig` validation (different scopes)
- [x] All existing E2E tests pass
- [x] Pre-commit checks pass

### Follow-up PR (Template Integration)

- [ ] All PORT-\* rules from refactoring plan are implemented in domain
- [ ] Port descriptions render as YAML comments in output
- [ ] Cross-service port conflicts are detected and reported with actionable error
- [ ] Template has no conditional port logic (just loops)
- [ ] No duplication with `TrackerConfig` validation (different scopes)
- [ ] All existing E2E tests pass
- [ ] Pre-commit checks pass

## Testing Strategy

Expand Down
Loading
Loading