Skip to content

Conversation

@josecelano
Copy link
Member

Summary

Integrates the PortBinding domain types (created in #298) into the Docker Compose template rendering, completing Phase 3 of the topology refactoring.

Changes

Port Derivation (port_derivation.rs)

  • Implements PORT-01 through PORT-11 rules from the refactoring plan
  • derive_tracker_ports() - UDP always exposed, HTTP/API only when no TLS
  • derive_caddy_ports() - Always exposes 80, 443, 443/udp
  • derive_prometheus_ports() - 9090 on localhost only
  • derive_grafana_ports() - 3000 only when no TLS
  • derive_mysql_ports() - No exposed ports

Port Definition DTO (port_definition.rs)

  • PortDefinition struct with binding and description fields
  • From<&PortBinding> trait for idiomatic conversion
  • Serializable for Tera template context

Service Context Updates

  • Added ports: Vec<PortDefinition> to all service configs
  • Tracker, Caddy, Prometheus, Grafana, MySQL all derive their ports

Template Simplification (docker-compose.yml.tera)

  • Replaced conditional port logic with simple loops
  • Added description comments using # {{ port.description }}
  • Removed needs_ports_section checks (replaced by ports | length > 0)

Validation

  • try_build() method on DockerComposeContextBuilder validates port uniqueness
  • PortConflictError with help() method for actionable error messages
  • DDD "always valid" pattern: DockerComposeTopology::new() returns Result

Documentation

Testing

  • 15 unit tests for port derivation functions
  • Unit tests for PortDefinition conversion
  • Tests for try_build() validation
  • All E2E tests pass

Rendered Output Example

services:
  tracker:
    ports:
      # BitTorrent UDP announce
      - "6969:6969/udp"
      # HTTP tracker announce
      - "7070:7070"
      # HTTP API (stats/whitelist)
      - "1212:1212"

Checklist

  • Pre-commit checks pass: ./scripts/pre-commit.sh
  • All PORT-* rules implemented in port derivation functions
  • Port descriptions render as YAML comments in generated output
  • Template uses loops over service.ports
  • Cross-service port conflicts detected before rendering via try_build()
  • All existing E2E tests pass

Related

- Create port_derivation.rs with PORT-01 through PORT-11 rules
- Create port_definition.rs with PortDefinition DTO and From<&PortBinding>
- Add ports: Vec<PortDefinition> to all service context types
- Simplify docker-compose.yml.tera to use loops over service.ports
- Add port descriptions as YAML comments in rendered output
- Add try_build() with port conflict validation to DockerComposeContextBuilder
- Apply DDD 'always valid' pattern: DockerComposeTopology::new() returns Result
- Use idiomatic From trait instead of helper functions

Also adds:
- Issue #301 spec for Phase 4 DDD Layer Alignment (future work)
- Updated epic #287 with Phase 4 tasks
@josecelano josecelano self-assigned this Jan 25, 2026
@josecelano josecelano force-pushed the 300-phase-3-port-topology-template-integration branch from aeb981d to 8dcbbc9 Compare January 25, 2026 21:04
@josecelano
Copy link
Member Author

ACK 8dcbbc9

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants