fix: domain inconsistencies — raw String in event VO and ImportSession constructor pattern #6

Closed
opened 2026-06-10 09:33:52 +00:00 by GKaszewski · 0 comments
Owner

Issues

1. MovieEnrichmentRequested uses String instead of ExternalMetadataId

crates/domain/src/events.rs:

MovieEnrichmentRequested {
    movie_id: MovieId,
    external_metadata_id: String,  // should be ExternalMetadataId
}

Every other event carrying an external ID uses the VO. ExternalMetadataId validates non-empty and trims whitespace — using a raw String here means a malformed ID can slip through the event bus and fail silently later at the enrichment handler.

Fix: change to ExternalMetadataId, update all construction sites in review_logger.rs and request_enrichment.rs, and update the event-payload serialization adapter accordingly.

2. ImportSession::new() takes an externally-provided ImportSessionId

All core models (Movie, Goal, Review, User, UserSettings) follow the pattern:

  • new() — domain generates the identity (XxxId::generate())
  • from_persistence() — accepts an existing ID from the DB

ImportSession::new(id: ImportSessionId, ...) breaks this by requiring the caller to supply the ID, blurring the creation/reconstitution boundary.

Fix: make ImportSession::new() generate its own ID internally, add ImportSession::from_persistence(id, ...) for the DB-load path.

Affected files

  • crates/domain/src/events.rs
  • crates/domain/src/models/import_session.rs
  • crates/adapters/event-payload/src/lib.rs
  • crates/application/src/diary/review_logger.rs
  • crates/application/src/movies/request_enrichment.rs
  • crates/adapters/sqlite/src/import_session.rs
  • crates/adapters/postgres/src/ (import session reconstitution)
## Issues ### 1. `MovieEnrichmentRequested` uses `String` instead of `ExternalMetadataId` `crates/domain/src/events.rs`: ```rust MovieEnrichmentRequested { movie_id: MovieId, external_metadata_id: String, // should be ExternalMetadataId } ``` Every other event carrying an external ID uses the VO. `ExternalMetadataId` validates non-empty and trims whitespace — using a raw `String` here means a malformed ID can slip through the event bus and fail silently later at the enrichment handler. **Fix**: change to `ExternalMetadataId`, update all construction sites in `review_logger.rs` and `request_enrichment.rs`, and update the `event-payload` serialization adapter accordingly. ### 2. `ImportSession::new()` takes an externally-provided `ImportSessionId` All core models (`Movie`, `Goal`, `Review`, `User`, `UserSettings`) follow the pattern: - `new()` — domain generates the identity (`XxxId::generate()`) - `from_persistence()` — accepts an existing ID from the DB `ImportSession::new(id: ImportSessionId, ...)` breaks this by requiring the caller to supply the ID, blurring the creation/reconstitution boundary. **Fix**: make `ImportSession::new()` generate its own ID internally, add `ImportSession::from_persistence(id, ...)` for the DB-load path. ## Affected files - `crates/domain/src/events.rs` - `crates/domain/src/models/import_session.rs` - `crates/adapters/event-payload/src/lib.rs` - `crates/application/src/diary/review_logger.rs` - `crates/application/src/movies/request_enrichment.rs` - `crates/adapters/sqlite/src/import_session.rs` - `crates/adapters/postgres/src/` (import session reconstitution)
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: GKaszewski/movies-diary#6