feat(workstate): résumés de conversation dans le read-model (Lot C backend)
Étend le read-model work-state pour exposer un résumé par conversation (participants, dernier message/activité, compteurs) câblé jusqu'au DTO camelCase de l'état app-tauri. - application : assemblage des résumés de conversation dans le work-state. - app-tauri : DTO camelCase des résumés + exposition dans l'état. Tests verts : application workstate (21), app-tauri dto_agents (21), aucun warning Rust. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -222,6 +222,7 @@ fn project_work_state_dto_serialises_live_and_busy_camelcase() {
|
||||
},
|
||||
tickets: vec![],
|
||||
}],
|
||||
conversations: vec![],
|
||||
});
|
||||
|
||||
let v = serde_json::to_value(&dto).unwrap();
|
||||
@ -279,6 +280,7 @@ fn project_work_state_dto_serialises_tickets_camelcase() {
|
||||
},
|
||||
],
|
||||
}],
|
||||
conversations: vec![],
|
||||
});
|
||||
|
||||
let v = serde_json::to_value(&dto).unwrap();
|
||||
@ -304,6 +306,80 @@ fn project_work_state_dto_serialises_tickets_camelcase() {
|
||||
assert_eq!(next["requesterLabel"], "User");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn project_work_state_dto_serialises_conversations_camelcase() {
|
||||
use application::{
|
||||
ConversationPreviewStatus, ConversationTurnWorkPreview, ConversationWorkSummary,
|
||||
};
|
||||
use domain::{ConversationId, TurnId, TurnRole};
|
||||
|
||||
let requester = AgentId::from_uuid(Uuid::from_u128(20));
|
||||
let ready_conv = ConversationId::from_uuid(Uuid::from_u128(40));
|
||||
let missing_conv = ConversationId::from_uuid(Uuid::from_u128(41));
|
||||
let up_to = TurnId::from_uuid(Uuid::from_u128(50));
|
||||
|
||||
let dto = app_tauri_lib::dto::ProjectWorkStateDto::from(ProjectWorkState {
|
||||
agents: vec![],
|
||||
conversations: vec![
|
||||
ConversationWorkSummary {
|
||||
conversation_id: ready_conv,
|
||||
status: ConversationPreviewStatus::Ready,
|
||||
objective_preview: Some("Livrer le lot C".to_owned()),
|
||||
summary_preview: Some("Résumé du fil".to_owned()),
|
||||
summary_len: 1024,
|
||||
up_to: Some(up_to),
|
||||
recent_turns: vec![],
|
||||
},
|
||||
ConversationWorkSummary {
|
||||
conversation_id: missing_conv,
|
||||
status: ConversationPreviewStatus::Missing,
|
||||
objective_preview: None,
|
||||
summary_preview: None,
|
||||
summary_len: 0,
|
||||
up_to: None,
|
||||
recent_turns: vec![ConversationTurnWorkPreview {
|
||||
role: TurnRole::Prompt,
|
||||
source: TicketWorkSource::Agent {
|
||||
agent_id: requester,
|
||||
},
|
||||
at_ms: 1_700,
|
||||
text_preview: "Analyse le module".to_owned(),
|
||||
text_len: 17,
|
||||
}],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
let v = serde_json::to_value(&dto).unwrap();
|
||||
let ready = &v["conversations"][0];
|
||||
assert_eq!(ready["conversationId"], ready_conv.to_string());
|
||||
assert_eq!(ready["status"], "ready");
|
||||
assert_eq!(ready["objectivePreview"], "Livrer le lot C");
|
||||
assert_eq!(ready["summaryPreview"], "Résumé du fil");
|
||||
assert_eq!(ready["summaryLen"], 1024);
|
||||
assert_eq!(ready["upTo"], up_to.to_string());
|
||||
assert_eq!(ready["recentTurns"], json!([]));
|
||||
// No snake_case leak.
|
||||
assert!(ready.get("conversation_id").is_none());
|
||||
assert!(ready.get("summary_preview").is_none());
|
||||
assert!(ready.get("up_to").is_none());
|
||||
|
||||
let missing = &v["conversations"][1];
|
||||
assert_eq!(missing["status"], "missing");
|
||||
// Absent previews surface as null (predictable, not omitted).
|
||||
assert!(missing["summaryPreview"].is_null());
|
||||
assert!(missing["upTo"].is_null());
|
||||
let turn = &missing["recentTurns"][0];
|
||||
assert_eq!(turn["role"], "prompt");
|
||||
assert_eq!(turn["source"]["kind"], "agent");
|
||||
assert_eq!(turn["source"]["agentId"], requester.to_string());
|
||||
assert_eq!(turn["atMs"], 1_700);
|
||||
assert_eq!(turn["textPreview"], "Analyse le module");
|
||||
assert_eq!(turn["textLen"], 17);
|
||||
assert!(turn.get("at_ms").is_none());
|
||||
assert!(turn.get("text_preview").is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn launch_agent_request_carries_conversation_id_for_resume() {
|
||||
let raw = json!({
|
||||
|
||||
Reference in New Issue
Block a user