feat(workstate): actions contrôlées sur le work-state (Lot D backend)
Ajoute un module d'actions contrôlées (`workstate/actions.rs`) côté application et l'expose via des commandes Tauri : DTO camelCase, câblage commands/state/lib. Les actions valident leurs invariants avant d'agir sur le read-model. - application : use cases d'actions contrôlées + intégration au work-state. - app-tauri : commandes dédiées, DTO et enregistrement dans le handler. Tests verts : application workstate_actions (7), workstate (21), app-tauri dto_agents (25), list_live_agents_r0b (5), cargo check OK. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -552,3 +552,82 @@ fn launch_agent_output_propagates_assigned_conversation_id() {
|
||||
"no snake_case leak"
|
||||
);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Lot D — attach/stop live agent DTOs (controlled actions)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#[test]
|
||||
fn attach_live_agent_request_deserialises_camelcase() {
|
||||
use app_tauri_lib::dto::AttachLiveAgentRequestDto;
|
||||
|
||||
let raw = json!({
|
||||
"projectId": Uuid::from_u128(1).to_string(),
|
||||
"agentId": Uuid::from_u128(2).to_string(),
|
||||
"nodeId": Uuid::from_u128(3).to_string()
|
||||
});
|
||||
let dto: AttachLiveAgentRequestDto = serde_json::from_value(raw).unwrap();
|
||||
assert_eq!(dto.project_id, Uuid::from_u128(1).to_string());
|
||||
assert_eq!(dto.agent_id, Uuid::from_u128(2).to_string());
|
||||
assert_eq!(dto.node_id, Uuid::from_u128(3).to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn attach_live_agent_response_serialises_camelcase_with_kind() {
|
||||
use app_tauri_lib::dto::AttachLiveAgentResponseDto;
|
||||
use application::{AttachLiveAgentOutput, LiveSessionKind};
|
||||
|
||||
let agent = AgentId::from_uuid(Uuid::from_u128(11));
|
||||
let node = NodeId::from_uuid(Uuid::from_u128(12));
|
||||
let session = SessionId::from_uuid(Uuid::from_u128(13));
|
||||
let dto = AttachLiveAgentResponseDto::from(AttachLiveAgentOutput {
|
||||
agent_id: agent,
|
||||
node_id: node,
|
||||
session_id: session,
|
||||
kind: LiveSessionKind::Pty,
|
||||
});
|
||||
|
||||
let v = serde_json::to_value(&dto).unwrap();
|
||||
assert_eq!(v["agentId"], agent.to_string());
|
||||
assert_eq!(v["nodeId"], node.to_string());
|
||||
assert_eq!(v["sessionId"], session.to_string());
|
||||
assert_eq!(v["kind"], "pty");
|
||||
// No snake_case leak.
|
||||
assert!(v.get("agent_id").is_none());
|
||||
assert!(v.get("session_id").is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn stop_live_agent_request_deserialises_camelcase() {
|
||||
use app_tauri_lib::dto::StopLiveAgentRequestDto;
|
||||
|
||||
let raw = json!({
|
||||
"projectId": Uuid::from_u128(1).to_string(),
|
||||
"agentId": Uuid::from_u128(2).to_string()
|
||||
});
|
||||
let dto: StopLiveAgentRequestDto = serde_json::from_value(raw).unwrap();
|
||||
assert_eq!(dto.project_id, Uuid::from_u128(1).to_string());
|
||||
assert_eq!(dto.agent_id, Uuid::from_u128(2).to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn stop_live_agent_response_serialises_camelcase_with_kind() {
|
||||
use app_tauri_lib::dto::StopLiveAgentResponseDto;
|
||||
use application::{LiveSessionKind, StopLiveAgentOutput};
|
||||
|
||||
let agent = AgentId::from_uuid(Uuid::from_u128(11));
|
||||
let session = SessionId::from_uuid(Uuid::from_u128(13));
|
||||
let dto = StopLiveAgentResponseDto::from(StopLiveAgentOutput {
|
||||
agent_id: agent,
|
||||
session_id: session,
|
||||
kind: LiveSessionKind::Structured,
|
||||
});
|
||||
|
||||
let v = serde_json::to_value(&dto).unwrap();
|
||||
assert_eq!(v["agentId"], agent.to_string());
|
||||
assert_eq!(v["sessionId"], session.to_string());
|
||||
assert_eq!(v["kind"], "structured");
|
||||
// Stop response carries no node id (the session is gone).
|
||||
assert!(v.get("nodeId").is_none());
|
||||
assert!(v.get("session_id").is_none());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user