Skip to main content

domain/
workflow.rs

1//! Workflow events and outcomes for reviewable resort operations.
2//!
3//! Workflows connect source-derived facts to staff-visible tasks, customer-message drafts, policy
4//! context, and recommended next actions. They preserve evidence and review reasons so AI agents can
5//! reduce manual triage while keeping live care, labor, payment, and customer communications inside
6//! explicit approval boundaries.
7
8use chrono::{DateTime, Utc};
9use nutype::nutype;
10#[allow(unused_imports)]
11use serde::{Deserialize, Serialize};
12use uuid::Uuid;
13
14use crate::{entities, policy};
15
16#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
17/// Stable identifier for a workflow event emitted by an agent, adapter, or staff-facing process.
18pub struct EventId(pub Uuid);
19
20#[nutype(
21    sanitize(trim),
22    validate(not_empty, len_char_max = 500),
23    derive(
24        Debug,
25        Clone,
26        PartialEq,
27        Eq,
28        PartialOrd,
29        Ord,
30        Hash,
31        Serialize,
32        Deserialize
33    )
34)]
35pub struct Summary(String);
36
37/// Risk marker surfaced when a workflow may affect pet safety, labor cost, payment, or customer trust.
38#[nutype(
39    sanitize(trim),
40    validate(not_empty, len_char_max = 160),
41    derive(
42        Debug,
43        Clone,
44        PartialEq,
45        Eq,
46        PartialOrd,
47        Ord,
48        Hash,
49        Serialize,
50        Deserialize
51    )
52)]
53pub struct RiskFlag(String);
54
55/// Evidence note proving what source fact, review, or staff action verified a workflow outcome.
56#[nutype(
57    sanitize(trim),
58    validate(not_empty, len_char_max = 500),
59    derive(
60        Debug,
61        Clone,
62        PartialEq,
63        Eq,
64        PartialOrd,
65        Ord,
66        Hash,
67        Serialize,
68        Deserialize
69    )
70)]
71pub struct VerificationNote(String);
72
73/// Review explanation recorded when automation must stop at a manager, medical, or customer-message gate.
74#[nutype(
75    sanitize(trim),
76    validate(not_empty, len_char_max = 300),
77    derive(
78        Debug,
79        Clone,
80        PartialEq,
81        Eq,
82        PartialOrd,
83        Ord,
84        Hash,
85        Serialize,
86        Deserialize
87    )
88)]
89pub struct ReviewReason(String);
90
91/// External workflow-provider vocabulary retained before promotion into domain tasks or messages.
92pub mod external {
93    use nutype::nutype;
94    #[allow(unused_imports)]
95    use serde::{Deserialize, Serialize};
96
97    /// External workflow provider or system name that supplied a task, message, or status update.
98    #[nutype(
99        sanitize(trim),
100        validate(not_empty, len_char_max = 120),
101        derive(
102            Debug,
103            Clone,
104            PartialEq,
105            Eq,
106            PartialOrd,
107            Ord,
108            Hash,
109            Serialize,
110            Deserialize
111        )
112    )]
113    pub struct Provider(String);
114
115    /// External workflow identifier used to correlate provider tasks and status updates.
116    #[nutype(
117        sanitize(trim),
118        validate(not_empty, len_char_max = 120),
119        derive(
120            Debug,
121            Clone,
122            PartialEq,
123            Eq,
124            PartialOrd,
125            Ord,
126            Hash,
127            Serialize,
128            Deserialize
129        )
130    )]
131    pub struct Id(String);
132}
133
134/// Provider task fields used to create staff work without losing source evidence.
135pub mod task {
136    use nutype::nutype;
137    #[allow(unused_imports)]
138    use serde::{Deserialize, Serialize};
139
140    /// Staff-visible task title summarizing the operational work item.
141    #[nutype(
142        sanitize(trim),
143        validate(not_empty, len_char_max = 160),
144        derive(
145            Debug,
146            Clone,
147            PartialEq,
148            Eq,
149            PartialOrd,
150            Ord,
151            Hash,
152            Serialize,
153            Deserialize
154        )
155    )]
156    pub struct Title(String);
157
158    /// Task or message body text that carries source evidence and review instructions.
159    #[nutype(
160        sanitize(trim),
161        validate(not_empty, len_char_max = 2000),
162        derive(
163            Debug,
164            Clone,
165            PartialEq,
166            Eq,
167            PartialOrd,
168            Ord,
169            Hash,
170            Serialize,
171            Deserialize
172        )
173    )]
174    pub struct Body(String);
175}
176
177/// Provider message fields used before normalization into customer-message workflows.
178pub mod message {
179    use nutype::nutype;
180    #[allow(unused_imports)]
181    use serde::{Deserialize, Serialize};
182
183    #[nutype(
184        sanitize(trim),
185        validate(not_empty, len_char_max = 80),
186        derive(
187            Debug,
188            Clone,
189            PartialEq,
190            Eq,
191            PartialOrd,
192            Ord,
193            Hash,
194            Serialize,
195            Deserialize
196        )
197    )]
198    pub struct Channel(String);
199
200    #[nutype(
201        sanitize(trim),
202        validate(not_empty, len_char_max = 2000),
203        derive(
204            Debug,
205            Clone,
206            PartialEq,
207            Eq,
208            PartialOrd,
209            Ord,
210            Hash,
211            Serialize,
212            Deserialize
213        )
214    )]
215    pub struct Body(String);
216}
217
218/// Provider status-update fields used to reconcile external task or message progress.
219pub mod status_update {
220    use crate::entities;
221    use nutype::nutype;
222    #[allow(unused_imports)]
223    use serde::{Deserialize, Serialize};
224
225    /// Provider-supplied status reason text preserved as review evidence.
226    pub mod reason {
227        use super::*;
228
229        #[nutype(
230            sanitize(trim),
231            validate(not_empty, len_char_max = 500),
232            derive(
233                Debug,
234                Clone,
235                PartialEq,
236                Eq,
237                PartialOrd,
238                Ord,
239                Hash,
240                Serialize,
241                Deserialize
242            )
243        )]
244        pub struct Reason(String);
245    }
246
247    pub use reason::Reason;
248
249    #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
250    /// Intended reservation transition requested by a workflow before policy and review checks are applied.
251    pub enum TransitionIntent {
252        /// Request medical review workflow state, command, or review outcome.
253        RequestMedicalReview,
254        /// Apply capacity decision workflow state, command, or review outcome.
255        ApplyCapacityDecision,
256        /// Confirm accepted offer workflow state, command, or review outcome.
257        ConfirmAcceptedOffer,
258        /// Cancel reservation workflow state, command, or review outcome.
259        CancelReservation,
260        /// Reject by policy workflow state, command, or review outcome.
261        RejectByPolicy,
262        /// Complete checkout workflow state, command, or review outcome.
263        CompleteCheckout,
264    }
265
266    #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
267    /// Workflow-scoped reservation transition request with target state, reason, and review intent.
268    pub struct Reservation {
269        /// Workflow status value preserved for staff review and audit evidence.
270        pub status: entities::reservation::Status,
271        /// Workflow intent value preserved for staff review and audit evidence.
272        pub intent: TransitionIntent,
273        /// Business reason staff should review before proceeding.
274        pub reason: Reason,
275    }
276
277    #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
278    /// Workflow target that a task, event, or recommended action is about.
279    pub enum Target {
280        /// Reservation record participating in the workflow.
281        Reservation(Reservation),
282    }
283}
284
285#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
286/// Workflow event that records what changed, who/what it concerns, and what evidence/risk came with it.
287pub struct Event {
288    /// Workflow event ID value preserved for staff review and audit evidence.
289    pub event_id: EventId,
290    /// Workflow event type value preserved for staff review and audit evidence.
291    pub event_type: EventType,
292    /// Workflow occurred at value preserved for staff review and audit evidence.
293    pub occurred_at: DateTime<Utc>,
294    /// Workflow actor value preserved for staff review and audit evidence.
295    pub actor: entities::ActorRef,
296    /// Workflow location ID value preserved for staff review and audit evidence.
297    pub location_id: entities::LocationId,
298    /// Workflow subject value preserved for staff review and audit evidence.
299    pub subject: Subject,
300    /// Workflow policy context value preserved for staff review and audit evidence.
301    pub policy_context: PolicyContext,
302}
303
304#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
305/// Event category emitted by triage, policy, review, external sync, or source ingestion.
306pub enum EventType {
307    /// Inquiry received workflow state, command, or review outcome.
308    InquiryReceived,
309    /// Customer registered workflow state, command, or review outcome.
310    CustomerRegistered,
311    /// Pet profile created workflow state, command, or review outcome.
312    PetProfileCreated,
313    /// Vaccine document uploaded workflow state, command, or review outcome.
314    VaccineDocumentUploaded,
315    /// Booking requested workflow state, command, or review outcome.
316    BookingRequested,
317    /// Booking triage needed workflow state, command, or review outcome.
318    BookingTriageNeeded,
319    /// Booking confirmation needed workflow state, command, or review outcome.
320    BookingConfirmationNeeded,
321    /// Daily note created workflow state, command, or review outcome.
322    DailyNoteCreated,
323    /// Daily update needed workflow state, command, or review outcome.
324    DailyUpdateNeeded,
325    /// Incident created workflow state, command, or review outcome.
326    IncidentCreated,
327    /// Checkout completed workflow state, command, or review outcome.
328    CheckoutCompleted,
329    /// Review request eligible workflow state, command, or review outcome.
330    ReviewRequestEligible,
331    /// Membership changed workflow state, command, or review outcome.
332    MembershipChanged,
333    /// Loyalty credit available workflow state, command, or review outcome.
334    LoyaltyCreditAvailable,
335}
336
337#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
338/// Subject of a workflow event or recommendation.
339pub enum Subject {
340    /// Customer record participating in the workflow.
341    Customer(entities::CustomerId),
342    /// Pet record participating in the workflow.
343    Pet(entities::PetId),
344    /// Reservation record participating in the workflow.
345    Reservation(entities::reservation::Id),
346    /// External system object referenced from domain history.
347    External {
348        /// Workflow provider value preserved for staff review and audit evidence.
349        provider: external::Provider,
350        /// Workflow id value preserved for staff review and audit evidence.
351        id: external::Id,
352    },
353}
354
355#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
356/// Policy context attached to a workflow so reviewers can see allowed actions and required gates.
357pub struct PolicyContext {
358    /// Workflow allowed actions value preserved for staff review and audit evidence.
359    pub allowed_actions: Vec<AllowedAction>,
360    /// Workflow automation level value preserved for staff review and audit evidence.
361    pub automation_level: policy::automation::Level,
362    /// Workflow required reviews value preserved for staff review and audit evidence.
363    pub required_reviews: Vec<policy::ReviewGate>,
364}
365
366#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
367/// Action an automation policy permits for a workflow outcome.
368pub enum AllowedAction {
369    /// Read entities workflow state, command, or review outcome.
370    ReadEntities,
371    /// Extract structured data workflow state, command, or review outcome.
372    ExtractStructuredData,
373    /// Draft customer message workflow state, command, or review outcome.
374    DraftCustomerMessage,
375    /// Create internal task workflow state, command, or review outcome.
376    CreateInternalTask,
377    /// Suggest reservation status workflow state, command, or review outcome.
378    SuggestReservationStatus,
379    /// Suggest play eligibility workflow state, command, or review outcome.
380    SuggestPlayEligibility,
381    /// Summarize care notes workflow state, command, or review outcome.
382    SummarizeCareNotes,
383    /// Flag risk workflow state, command, or review outcome.
384    FlagRisk,
385}
386
387#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
388/// Workflow result carrying status, summary, recommended action, and verification notes for staff review.
389pub struct Result<T> {
390    /// Workflow status value preserved for staff review and audit evidence.
391    pub status: Status,
392    /// Workflow summary value preserved for staff review and audit evidence.
393    pub summary: Summary,
394    /// Workflow structured output value preserved for staff review and audit evidence.
395    pub structured_output: Option<T>,
396    /// Workflow recommended actions value preserved for staff review and audit evidence.
397    pub recommended_actions: Vec<RecommendedAction>,
398    /// Workflow risk flags value preserved for staff review and audit evidence.
399    pub risk_flags: Vec<RiskFlag>,
400    /// Workflow verification value preserved for staff review and audit evidence.
401    pub verification: Vec<VerificationNote>,
402    /// Workflow human review reason value preserved for staff review and audit evidence.
403    pub human_review_reason: Option<ReviewReason>,
404}
405
406#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
407/// Normalized lifecycle states used to reconcile source-system data with domain workflows.
408pub enum Status {
409    /// Completed workflow state, command, or review outcome.
410    Completed,
411    /// Needs human review workflow state, command, or review outcome.
412    NeedsHumanReview,
413    /// Rejected by policy workflow state, command, or review outcome.
414    RejectedByPolicy,
415    /// Needs more information workflow state, command, or review outcome.
416    NeedsMoreInformation,
417    /// Failed safely workflow state, command, or review outcome.
418    FailedSafely,
419}
420
421#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
422/// Recommended next action for staff, managers, or automation after evaluating a workflow.
423pub enum RecommendedAction {
424    /// Internal task workflow state, command, or review outcome.
425    InternalTask {
426        /// Workflow title value preserved for staff review and audit evidence.
427        title: task::Title,
428        /// Workflow body value preserved for staff review and audit evidence.
429        body: task::Body,
430    },
431    /// Draft message workflow state, command, or review outcome.
432    DraftMessage {
433        /// Workflow channel value preserved for staff review and audit evidence.
434        channel: message::Channel,
435        /// Workflow body value preserved for staff review and audit evidence.
436        body: message::Body,
437    },
438    /// Update status workflow state, command, or review outcome.
439    UpdateStatus {
440        /// Workflow target value preserved for staff review and audit evidence.
441        target: status_update::Target,
442    },
443    /// Request human review workflow state, command, or review outcome.
444    RequestHumanReview(policy::ReviewGate),
445}