made_api/
ceremony_summary.rs1use std::collections::BTreeMap;
2
3use serde::{Deserialize, Serialize};
4
5use crate::InterventionView;
6
7#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
9pub struct CeremonyParticipant {
10 pub role_id: String,
11 pub specialty: String,
12 pub bound_at_millis: i64,
13}
14
15#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
22pub struct CeremonySummary {
23 pub ceremony_id: String,
24 pub definition_name: String,
25 pub definition_version: String,
26 pub definition_digest: Option<String>,
31 pub current_state: String,
32 pub participants: Vec<CeremonyParticipant>,
33 pub interventions: Vec<InterventionView>,
35 pub context: BTreeMap<String, serde_json::Value>,
39 pub created_at_millis: i64,
40 pub updated_at_millis: i64,
41 pub completed_at_millis: Option<i64>,
42}
43
44#[cfg(test)]
45mod tests {
46 use super::*;
47
48 #[test]
49 fn a_summary_survives_the_wire() {
50 let summary = CeremonySummary {
51 ceremony_id: "c-1".to_owned(),
52 definition_name: "scope_discovery".to_owned(),
53 definition_version: "1.0".to_owned(),
54 definition_digest: Some("abc123".to_owned()),
55 current_state: "STARTED".to_owned(),
56 participants: vec![CeremonyParticipant {
57 role_id: "FACILITATOR".to_owned(),
58 specialty: "coordination".to_owned(),
59 bound_at_millis: 1_700_000_000_000,
60 }],
61 interventions: Vec::new(),
62 context: BTreeMap::from([(
63 "requested_by".to_owned(),
64 serde_json::Value::String("consumer-1".to_owned()),
65 )]),
66 created_at_millis: 1_700_000_000_000,
67 updated_at_millis: 1_700_000_000_000,
68 completed_at_millis: None,
69 };
70 let bytes = serde_json::to_vec(&summary).expect("serializes");
71 assert_eq!(
72 serde_json::from_slice::<CeremonySummary>(&bytes).expect("deserializes"),
73 summary
74 );
75 }
76
77 #[test]
78 fn an_unbound_instance_has_no_digest_rather_than_a_placeholder() {
79 let summary = CeremonySummary {
80 ceremony_id: "c-1".to_owned(),
81 definition_name: "draft".to_owned(),
82 definition_version: "1.0".to_owned(),
83 definition_digest: None,
84 current_state: "STARTED".to_owned(),
85 participants: Vec::new(),
86 interventions: Vec::new(),
87 context: BTreeMap::new(),
88 created_at_millis: 1,
89 updated_at_millis: 1,
90 completed_at_millis: None,
91 };
92 assert!(
93 summary.definition_digest.is_none(),
94 "a placeholder digest would let an unpublished draft read as provable"
95 );
96 }
97}