fix(mcp): update block mutations for ScheduleConfig V2 day_blocks

This commit is contained in:
2026-03-17 14:32:02 +01:00
parent 05d2d77515
commit 8b8e8a8d8c
2 changed files with 25 additions and 16 deletions

View File

@@ -59,14 +59,16 @@ pub struct DeleteChannelParams {
pub struct SetScheduleConfigParams { pub struct SetScheduleConfigParams {
/// Channel UUID /// Channel UUID
pub channel_id: String, pub channel_id: String,
/// JSON array of ProgrammingBlock objects /// JSON object of the full ScheduleConfig shape: {"monday": [...], "tuesday": [...], ...}
pub blocks_json: String, pub day_blocks_json: String,
} }
#[derive(Debug, Deserialize, JsonSchema)] #[derive(Debug, Deserialize, JsonSchema)]
pub struct AddBlockParams { pub struct AddBlockParams {
/// Channel UUID /// Channel UUID
pub channel_id: String, pub channel_id: String,
/// Day of week: "monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"
pub day: String,
/// ProgrammingBlock serialized as JSON /// ProgrammingBlock serialized as JSON
pub block_json: String, pub block_json: String,
} }
@@ -163,43 +165,44 @@ impl KTvMcpServer {
} }
#[tool( #[tool(
description = "Replace a channel's entire schedule config. blocks_json is a JSON array of ProgrammingBlock objects." description = "Replace a channel's entire schedule config. day_blocks_json is a JSON object of the ScheduleConfig shape: {\"monday\": [...], ...}"
)] )]
async fn set_schedule_config(&self, #[tool(aggr)] p: SetScheduleConfigParams) -> String { async fn set_schedule_config(&self, #[tool(aggr)] p: SetScheduleConfigParams) -> String {
let channel_id = match parse_uuid(&p.channel_id) { let channel_id = match parse_uuid(&p.channel_id) {
Ok(id) => id, Ok(id) => id,
Err(e) => return e, Err(e) => return e,
}; };
let blocks: Vec<ProgrammingBlock> = match serde_json::from_str(&p.blocks_json) { let config: ScheduleConfig = match serde_json::from_str(&p.day_blocks_json) {
Ok(b) => b, Ok(c) => c,
Err(e) => { Err(e) => {
return serde_json::json!({"error": format!("invalid blocks_json: {e}")}) return serde_json::json!({"error": format!("invalid day_blocks_json: {e}")})
.to_string() .to_string()
} }
}; };
channels::set_schedule_config( channels::set_schedule_config(&self.channel_service, channel_id, config).await
&self.channel_service,
channel_id,
ScheduleConfig { blocks },
)
.await
} }
#[tool( #[tool(
description = "Append a ProgrammingBlock to a channel's schedule. block_json is a serialized ProgrammingBlock." description = "Append a ProgrammingBlock to a channel's schedule for a specific day. day: monday|tuesday|wednesday|thursday|friday|saturday|sunday. block_json is a serialized ProgrammingBlock."
)] )]
async fn add_programming_block(&self, #[tool(aggr)] p: AddBlockParams) -> String { async fn add_programming_block(&self, #[tool(aggr)] p: AddBlockParams) -> String {
let channel_id = match parse_uuid(&p.channel_id) { let channel_id = match parse_uuid(&p.channel_id) {
Ok(id) => id, Ok(id) => id,
Err(e) => return e, Err(e) => return e,
}; };
let day: domain::Weekday = match serde_json::from_str(&format!("\"{}\"", p.day)) {
Ok(d) => d,
Err(e) => {
return serde_json::json!({"error": format!("invalid day: {e}")}).to_string()
}
};
let block: ProgrammingBlock = match serde_json::from_str(&p.block_json) { let block: ProgrammingBlock = match serde_json::from_str(&p.block_json) {
Ok(b) => b, Ok(b) => b,
Err(e) => { Err(e) => {
return serde_json::json!({"error": format!("invalid block_json: {e}")}).to_string() return serde_json::json!({"error": format!("invalid block_json: {e}")}).to_string()
} }
}; };
channels::add_programming_block(&self.channel_service, channel_id, block).await channels::add_programming_block(&self.channel_service, channel_id, day, block).await
} }
#[tool(description = "Remove a programming block from a channel's schedule by block UUID")] #[tool(description = "Remove a programming block from a channel's schedule by block UUID")]

View File

@@ -95,13 +95,17 @@ pub async fn set_schedule_config(
pub async fn add_programming_block( pub async fn add_programming_block(
svc: &Arc<ChannelService>, svc: &Arc<ChannelService>,
channel_id: Uuid, channel_id: Uuid,
day: domain::Weekday,
block: domain::ProgrammingBlock, block: domain::ProgrammingBlock,
) -> String { ) -> String {
let mut channel: Channel = match svc.find_by_id(channel_id).await { let mut channel: Channel = match svc.find_by_id(channel_id).await {
Ok(c) => c, Ok(c) => c,
Err(e) => return domain_err(e), Err(e) => return domain_err(e),
}; };
channel.schedule_config.blocks.push(block); channel.schedule_config.day_blocks
.entry(day)
.or_default()
.push(block);
channel.updated_at = chrono::Utc::now(); channel.updated_at = chrono::Utc::now();
match svc.update(channel).await { match svc.update(channel).await {
Ok(c) => ok_json(&c), Ok(c) => ok_json(&c),
@@ -118,7 +122,9 @@ pub async fn remove_programming_block(
Ok(c) => c, Ok(c) => c,
Err(e) => return domain_err(e), Err(e) => return domain_err(e),
}; };
channel.schedule_config.blocks.retain(|b| b.id != block_id); for blocks in channel.schedule_config.day_blocks.values_mut() {
blocks.retain(|b| b.id != block_id);
}
channel.updated_at = chrono::Utc::now(); channel.updated_at = chrono::Utc::now();
match svc.update(channel).await { match svc.update(channel).await {
Ok(c) => ok_json(&c), Ok(c) => ok_json(&c),