From 1338f6bace5b71c0e4b9bc6f671fc3b2f97fa903 Mon Sep 17 00:00:00 2001 From: Gabriel Kaszewski Date: Tue, 17 Mar 2026 14:25:51 +0100 Subject: [PATCH] feat(domain): extend ChannelRepository and ScheduleRepository ports for history --- k-tv-backend/domain/src/repositories.rs | 51 ++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/k-tv-backend/domain/src/repositories.rs b/k-tv-backend/domain/src/repositories.rs index ce81387..804ecf0 100644 --- a/k-tv-backend/domain/src/repositories.rs +++ b/k-tv-backend/domain/src/repositories.rs @@ -10,7 +10,7 @@ use chrono::DateTime; use chrono::Utc; use uuid::Uuid; -use crate::entities::{Channel, GeneratedSchedule, PlaybackRecord, User}; +use crate::entities::{Channel, ChannelConfigSnapshot, GeneratedSchedule, PlaybackRecord, ScheduleConfig, User}; use crate::errors::DomainResult; use crate::value_objects::{BlockId, ChannelId, MediaItemId, UserId}; @@ -71,6 +71,33 @@ pub trait ChannelRepository: Send + Sync { /// Insert or update a channel. async fn save(&self, channel: &Channel) -> DomainResult<()>; async fn delete(&self, id: ChannelId) -> DomainResult<()>; + + /// Snapshot the current config before saving a new one. + /// version_num is computed by the infra layer as MAX(version_num)+1 inside a transaction. + async fn save_config_snapshot( + &self, + channel_id: ChannelId, + config: &ScheduleConfig, + label: Option, + ) -> DomainResult; + + async fn list_config_snapshots( + &self, + channel_id: ChannelId, + ) -> DomainResult>; + + async fn get_config_snapshot( + &self, + channel_id: ChannelId, + snapshot_id: Uuid, + ) -> DomainResult>; + + async fn patch_config_snapshot_label( + &self, + channel_id: Uuid, + snapshot_id: Uuid, + label: Option, + ) -> DomainResult>; } /// Repository port for `GeneratedSchedule` and `PlaybackRecord` persistence. @@ -107,6 +134,28 @@ pub trait ScheduleRepository: Send + Sync { &self, channel_id: ChannelId, ) -> DomainResult>; + + /// List all generated schedule headers for a channel, newest first. + async fn list_schedule_history( + &self, + channel_id: ChannelId, + ) -> DomainResult>; + + /// Fetch a specific schedule with its slots, verifying channel ownership. + async fn get_schedule_by_id( + &self, + channel_id: ChannelId, + schedule_id: Uuid, + ) -> DomainResult>; + + /// Delete all schedules with generation > target_generation for this channel. + /// Also deletes matching playback_records (no DB cascade between those tables). + /// scheduled_slots cascade via FK from generated_schedules. + async fn delete_schedules_after( + &self, + channel_id: ChannelId, + target_generation: u32, + ) -> DomainResult<()>; } /// Repository port for activity log persistence.