sz_rust_workflow/api/
version_manager.rs1use std::sync::Arc;
5
6use serde::Serialize;
7
8use crate::error::{WorkflowError, WorkflowErrorCode, WorkflowResult};
9use crate::repository::{DefinitionId, DefinitionRepository};
10
11#[derive(Debug, Clone, Serialize)]
13pub struct DefinitionSummary {
14 pub id: DefinitionId,
15 pub flow_key: String,
16 pub version: String,
17 pub name: String,
18 pub active: bool,
19 pub deprecated: bool,
20}
21
22pub struct VersionManager {
24 definition_repo: Arc<dyn DefinitionRepository>,
25}
26
27impl VersionManager {
28 pub fn new(definition_repo: Arc<dyn DefinitionRepository>) -> Self {
29 Self { definition_repo }
30 }
31
32 pub async fn list_versions(&self, flow_key: &str) -> WorkflowResult<Vec<DefinitionSummary>> {
34 let defs = self.definition_repo.list_versions(flow_key).await?;
35 Ok(defs
36 .into_iter()
37 .map(|d| DefinitionSummary {
38 id: String::new(),
39 flow_key: d.flow_key,
40 version: d.version.to_string(),
41 name: d.name,
42 active: d.active,
43 deprecated: d.deprecated,
44 })
45 .collect())
46 }
47
48 pub async fn set_active(&self, id: &DefinitionId) -> WorkflowResult<()> {
50 let def = self.definition_repo.get(id).await?.ok_or_else(|| {
51 WorkflowError::with_field(WorkflowErrorCode::VersionNotFound, "版本不存在", "id", id)
52 })?;
53 if def.deprecated {
54 return Err(WorkflowError::with_field(
55 WorkflowErrorCode::VersionNotFound,
56 "已弃用版本不可设为生效",
57 "id",
58 id,
59 ));
60 }
61 self.definition_repo.set_active(id).await
62 }
63
64 pub async fn deprecate(&self, id: &DefinitionId) -> WorkflowResult<()> {
66 self.definition_repo.deprecate(id).await
67 }
68}
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73 use crate::definition::FlowDefinition;
74 use crate::repository::InMemoryDefinitionRepository;
75
76 fn make_def(key: &str, ver: &str, active: bool) -> FlowDefinition {
77 FlowDefinition {
78 flow_key: key.into(),
79 version: semver::Version::parse(ver).unwrap(),
80 name: "test".into(),
81 nodes: vec![],
82 start_node: "start".into(),
83 active,
84 deprecated: false,
85 machine: None,
86 flow: None,
87 }
88 }
89
90 #[tokio::test]
91 async fn list_versions() {
92 let repo = Arc::new(InMemoryDefinitionRepository::default());
93 repo.save(&make_def("test", "1.0.0", true)).await.unwrap();
94 repo.save(&make_def("test", "2.0.0", false)).await.unwrap();
95 let mgr = VersionManager::new(repo);
96 let versions = mgr.list_versions("test").await.unwrap();
97 assert_eq!(versions.len(), 2);
98 }
99
100 #[tokio::test]
101 async fn set_active_not_found() {
102 let repo = Arc::new(InMemoryDefinitionRepository::default());
103 let mgr = VersionManager::new(repo);
104 let result = mgr.set_active(&"nonexistent".to_string()).await;
105 assert!(result.is_err());
106 assert_eq!(result.unwrap_err().code, WorkflowErrorCode::VersionNotFound);
107 }
108}