Skip to content

Commit 90bc914

Browse files
committed
refactor: [#281] move EnvironmentParams to domain layer
- Create EnvironmentParams as domain value object (Factory Input Pattern) - Update Environment::create() to accept single params argument - Keep TryFrom<EnvironmentCreationConfig> in application layer - Cleaner API: Environment::create(params, working_dir, timestamp) This follows DDD principles - the params struct contains only domain types so it belongs in the domain layer, not application layer.
1 parent f7e342a commit 90bc914

8 files changed

Lines changed: 328 additions & 206 deletions

File tree

src/application/command_handlers/create/config/environment_config.rs

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -91,20 +91,20 @@ pub struct EnvironmentCreationConfig {
9191
/// Provider-specific configuration (LXD, Hetzner, etc.)
9292
///
9393
/// Uses `ProviderSection` for JSON parsing with raw primitives.
94-
/// Converted to domain `ProviderConfig` via `TryInto<ValidatedEnvironmentParams>`.
94+
/// Converted to domain `ProviderConfig` via `TryInto<EnvironmentParams>`.
9595
pub provider: ProviderSection,
9696

9797
/// Tracker deployment configuration
9898
///
9999
/// Uses `TrackerSection` for JSON parsing with String primitives.
100-
/// Converted to domain `TrackerConfig` via `TryInto<ValidatedEnvironmentParams>`.
100+
/// Converted to domain `TrackerConfig` via `TryInto<EnvironmentParams>`.
101101
pub tracker: TrackerSection,
102102

103103
/// Prometheus monitoring configuration (optional)
104104
///
105105
/// When present, Prometheus will be deployed to monitor the tracker.
106106
/// Uses `PrometheusSection` for JSON parsing with String primitives.
107-
/// Converted to domain `PrometheusConfig` via `TryInto<ValidatedEnvironmentParams>`.
107+
/// Converted to domain `PrometheusConfig` via `TryInto<EnvironmentParams>`.
108108
#[serde(default)]
109109
pub prometheus: Option<PrometheusSection>,
110110

@@ -115,7 +115,7 @@ pub struct EnvironmentCreationConfig {
115115
/// Prometheus as its data source.
116116
///
117117
/// Uses `GrafanaSection` for JSON parsing with String primitives.
118-
/// Converted to domain `GrafanaConfig` via `TryInto<ValidatedEnvironmentParams>`.
118+
/// Converted to domain `GrafanaConfig` via `TryInto<EnvironmentParams>`.
119119
#[serde(default)]
120120
pub grafana: Option<GrafanaSection>,
121121

@@ -404,7 +404,7 @@ mod tests {
404404
use super::*;
405405
use crate::application::command_handlers::create::config::provider::LxdProviderSection;
406406
use crate::application::command_handlers::create::config::tracker::TrackerSection;
407-
use crate::application::command_handlers::create::config::ValidatedEnvironmentParams;
407+
use crate::domain::environment::EnvironmentParams;
408408
use crate::domain::provider::Provider;
409409

410410
/// Helper to create a default LXD provider section for tests
@@ -611,7 +611,7 @@ mod tests {
611611
None,
612612
);
613613

614-
let result: Result<ValidatedEnvironmentParams, _> = config.try_into();
614+
let result: Result<EnvironmentParams, _> = config.try_into();
615615
assert!(result.is_ok(), "Expected successful conversion");
616616

617617
let params = result.unwrap();
@@ -644,7 +644,7 @@ mod tests {
644644
None,
645645
);
646646

647-
let result: Result<ValidatedEnvironmentParams, _> = config.try_into();
647+
let result: Result<EnvironmentParams, _> = config.try_into();
648648
assert!(result.is_ok(), "Expected successful conversion");
649649

650650
let params = result.unwrap();
@@ -674,7 +674,7 @@ mod tests {
674674
None,
675675
);
676676

677-
let result: Result<ValidatedEnvironmentParams, _> = config.try_into();
677+
let result: Result<EnvironmentParams, _> = config.try_into();
678678
assert!(result.is_err());
679679

680680
match result.unwrap_err() {
@@ -706,7 +706,7 @@ mod tests {
706706
None,
707707
);
708708

709-
let result: Result<ValidatedEnvironmentParams, _> = config.try_into();
709+
let result: Result<EnvironmentParams, _> = config.try_into();
710710
assert!(result.is_err());
711711

712712
match result.unwrap_err() {
@@ -741,7 +741,7 @@ mod tests {
741741
None,
742742
);
743743

744-
let result: Result<ValidatedEnvironmentParams, _> = config.try_into();
744+
let result: Result<EnvironmentParams, _> = config.try_into();
745745
assert!(result.is_err());
746746

747747
match result.unwrap_err() {
@@ -778,7 +778,7 @@ mod tests {
778778
None,
779779
);
780780

781-
let result: Result<ValidatedEnvironmentParams, _> = config.try_into();
781+
let result: Result<EnvironmentParams, _> = config.try_into();
782782
assert!(result.is_err());
783783

784784
match result.unwrap_err() {
@@ -814,7 +814,7 @@ mod tests {
814814
None,
815815
);
816816

817-
let result: Result<ValidatedEnvironmentParams, _> = config.try_into();
817+
let result: Result<EnvironmentParams, _> = config.try_into();
818818
assert!(result.is_err());
819819

820820
match result.unwrap_err() {
@@ -850,7 +850,7 @@ mod tests {
850850
None,
851851
);
852852

853-
let result: Result<ValidatedEnvironmentParams, _> = config.try_into();
853+
let result: Result<EnvironmentParams, _> = config.try_into();
854854
assert!(result.is_err());
855855

856856
match result.unwrap_err() {
@@ -884,14 +884,11 @@ mod tests {
884884
None,
885885
);
886886

887-
let params: ValidatedEnvironmentParams = config.try_into().unwrap();
888-
let environment = Environment::new(
889-
params.environment_name.clone(),
890-
params.provider_config,
891-
params.ssh_credentials,
892-
params.ssh_port,
893-
chrono::Utc::now(),
894-
);
887+
let params: EnvironmentParams = config.try_into().unwrap();
888+
889+
// Create environment using the factory pattern with all required parameters
890+
let working_dir = std::path::Path::new("/tmp/test-env");
891+
let environment = Environment::create(params, working_dir, chrono::Utc::now()).unwrap();
895892

896893
assert_eq!(environment.name().as_str(), "test-env");
897894
assert_eq!(environment.ssh_username().as_str(), "torrust");
@@ -1241,7 +1238,7 @@ mod tests {
12411238
);
12421239

12431240
// Config with no HTTPS section should convert successfully
1244-
let result: Result<ValidatedEnvironmentParams, _> = config.try_into();
1241+
let result: Result<EnvironmentParams, _> = config.try_into();
12451242
assert!(result.is_ok(), "Expected Ok but got: {:?}", result.err());
12461243
}
12471244

@@ -1260,7 +1257,7 @@ mod tests {
12601257
let public_key_path = format!("{project_root}/fixtures/testing_rsa.pub");
12611258

12621259
// Email validation now happens in domain layer (HttpsConfig::new())
1263-
// This test verifies that valid emails pass through TryInto<ValidatedEnvironmentParams>
1260+
// This test verifies that valid emails pass through TryInto<EnvironmentParams>
12641261
let config = EnvironmentCreationConfig::new(
12651262
EnvironmentSection {
12661263
name: "dev".to_string(),
@@ -1279,7 +1276,7 @@ mod tests {
12791276

12801277
// HTTPS section with valid email should convert successfully
12811278
// (actual cross-service TLS validation happens in domain layer)
1282-
let result: Result<ValidatedEnvironmentParams, _> = config.try_into();
1279+
let result: Result<EnvironmentParams, _> = config.try_into();
12831280
assert!(result.is_ok(), "Expected Ok but got: {:?}", result.err());
12841281
}
12851282

@@ -1309,7 +1306,7 @@ mod tests {
13091306
}),
13101307
);
13111308

1312-
let result: Result<ValidatedEnvironmentParams, _> = config.try_into();
1309+
let result: Result<EnvironmentParams, _> = config.try_into();
13131310
assert!(result.is_err());
13141311
assert!(matches!(
13151312
result.unwrap_err(),
@@ -1374,7 +1371,7 @@ mod tests {
13741371
// Note: Email validation now happens in domain layer (HttpsConfig::new())
13751372
// Cross-service TLS/HTTPS validation happens in domain layer (UserInputs)
13761373
// This test verifies the DTO can convert to environment params
1377-
let result: Result<ValidatedEnvironmentParams, _> = config.try_into();
1374+
let result: Result<EnvironmentParams, _> = config.try_into();
13781375
assert!(result.is_ok(), "Expected Ok but got: {:?}", result.err());
13791376
}
13801377
}

src/application/command_handlers/create/config/mod.rs

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,9 @@
5353
//! ```no_run
5454
//! use torrust_tracker_deployer_lib::application::command_handlers::create::config::{
5555
//! EnvironmentCreationConfig, EnvironmentSection, SshCredentialsConfig,
56-
//! ProviderSection, LxdProviderSection, ValidatedEnvironmentParams
56+
//! ProviderSection, LxdProviderSection
5757
//! };
58+
//! use torrust_tracker_deployer_lib::domain::environment::EnvironmentParams;
5859
//! use torrust_tracker_deployer_lib::domain::Environment;
5960
//! use chrono::{TimeZone, Utc};
6061
//!
@@ -99,17 +100,12 @@
99100
//! let config: EnvironmentCreationConfig = serde_json::from_str(json)?;
100101
//!
101102
//! // Convert to validated domain parameters using TryInto
102-
//! let params: ValidatedEnvironmentParams = config.try_into()?;
103+
//! let params: EnvironmentParams = config.try_into()?;
103104
//!
104-
//! // Create domain entity using named fields from params
105+
//! // Create domain entity using the factory pattern
105106
//! let created_at = Utc.with_ymd_and_hms(2025, 1, 1, 0, 0, 0).unwrap();
106-
//! let environment = Environment::new(
107-
//! params.environment_name,
108-
//! params.provider_config,
109-
//! params.ssh_credentials,
110-
//! params.ssh_port,
111-
//! created_at
112-
//! );
107+
//! let working_dir = std::path::Path::new("/tmp/my-env");
108+
//! let environment = Environment::create(params, working_dir, created_at)?;
113109
//!
114110
//! # Ok::<(), Box<dyn std::error::Error>>(())
115111
//! ```
@@ -154,4 +150,6 @@ pub use https::HttpsSection;
154150
pub use prometheus::PrometheusSection;
155151
pub use provider::{HetznerProviderSection, LxdProviderSection, ProviderSection};
156152
pub use ssh_credentials_config::SshCredentialsConfig;
157-
pub use validated_params::ValidatedEnvironmentParams;
153+
154+
// Note: EnvironmentParams is now in domain layer (crate::domain::environment::EnvironmentParams)
155+
// The validated_params module provides TryFrom<EnvironmentCreationConfig> for EnvironmentParams

0 commit comments

Comments
 (0)