liminal_server/auth_lys/
drafts_target.rs1use super::{
4 AgentDraftStore, ApprovalEvidence, ApprovalTransition, AtomicDraftStore, DraftError,
5 issuer_approval,
6};
7use lys_pass::drafts::{ApprovedDraft, Execution};
8use std::num::NonZeroUsize;
9
10pub struct TargetDraftStore {
12 pub agents: AgentDraftStore,
13 pub sites: crate::services::lifecycle::site::executor::SiteDraftStore,
14}
15impl TargetDraftStore {
16 fn target(&mut self, draft: &ApprovedDraft) -> Result<&mut dyn AtomicDraftStore, DraftError> {
17 match draft.target.kind.as_str() {
18 "liminal.agent" => Ok(&mut self.agents),
19 "liminal.network" if draft.target.action == "create_site" => Ok(&mut self.sites),
20 "liminal.service" | "liminal.template" => Ok(&mut self.sites),
21 _ => Err(DraftError::Contract),
22 }
23 }
24}
25impl AtomicDraftStore for TargetDraftStore {
26 fn receipt(&self, id: &str) -> Result<Option<Execution>, DraftError> {
27 let agent = self.agents.receipt(id)?;
28 let site = self.sites.receipt(id)?;
29 if agent.is_some() && site.is_some() {
30 return Err(DraftError::ReceiptMismatch);
31 }
32 Ok(agent.or(site))
33 }
34 fn approval(&self, draft: &ApprovedDraft) -> Result<ApprovalEvidence, DraftError> {
35 issuer_approval(&self.agents.journal, draft)
36 }
37 fn commit(
38 &mut self,
39 draft: &ApprovedDraft,
40 approval: &ApprovalTransition,
41 ) -> Result<Execution, DraftError> {
42 let bound = self.agents.journal.read(|snapshot| {
43 snapshot
44 .prepared
45 .values()
46 .any(|prepared| prepared.draft.as_deref() == Some(&draft.id))
47 })?;
48 if !bound {
49 return self.agents.commit(draft, approval);
50 }
51 self.target(draft)?.commit(draft, approval)
52 }
53 fn acknowledged(&self, id: &str) -> Result<bool, DraftError> {
54 if self.receipt_owner(id)? {
55 self.agents.acknowledged(id)
56 } else {
57 self.sites.acknowledged(id)
58 }
59 }
60 fn acknowledge(&mut self, id: &str, receipt: &Execution) -> Result<(), DraftError> {
61 if self.receipt_owner(id)? {
62 self.agents.acknowledge(id, receipt)
63 } else {
64 self.sites.acknowledge(id, receipt)
65 }
66 }
67 fn pending_acknowledgments(
68 &self,
69 limit: NonZeroUsize,
70 ) -> Result<Vec<ApprovedDraft>, DraftError> {
71 let mut pending = self.agents.pending_acknowledgments(limit)?;
72 pending.extend(self.sites.pending_acknowledgments(limit)?);
73 if pending.len() > limit.get() {
74 return Err(DraftError::Bound);
75 }
76 Ok(pending)
77 }
78 fn deliver_outcome(
79 &mut self,
80 draft: &ApprovedDraft,
81 receipt: &Execution,
82 ) -> Result<(), DraftError> {
83 if self.receipt_owner(&draft.id)? {
84 self.agents.deliver_outcome(draft, receipt)
85 } else {
86 self.sites.deliver_outcome(draft, receipt)
87 }
88 }
89}