Skip to main content

domain/boarding/
care.rs

1//! Boarding care-plan readiness for feeding, medication, and medical-document review gates.
2//!
3//! The policy turns pet care profiles into check-in readiness evidence, keeping automation focused
4//! on surfacing missing instructions and review requirements rather than making medical judgments.
5
6use super::*;
7use crate::{entities, policy};
8
9#[derive(Debug, Clone, Default)]
10/// Boarding care-readiness policy for feeding instructions and medication review.
11pub struct Policy;
12
13impl Policy {
14    /// Builds the pet-specific check-in care plan and review gates from the source care profile.
15    pub fn plan_for_pet(&self, pet_id: PetId, profile: &entities::CareProfile) -> Plan {
16        let mut gates = Vec::new();
17        if profile.feeding_instructions.is_none() {
18            gates.push(ReviewGate::new(
19                GateReason::MissingFeedingInstruction,
20                policy::ReviewGate::MedicalDocumentReview,
21            ));
22        }
23        if profile
24            .medications
25            .iter()
26            .any(|medication| medication.review_requirement.requires_review())
27        {
28            gates.push(ReviewGate::new(
29                GateReason::MedicationRequiresReview,
30                policy::ReviewGate::MedicalDocumentReview,
31            ));
32        }
33        Plan { pet_id, gates }
34    }
35}
36
37#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
38/// Pet-specific boarding care plan used by staff before check-in.
39pub struct Plan {
40    pet_id: PetId,
41    gates: Vec<ReviewGate>,
42}
43
44impl Plan {
45    /// Returns the pet whose boarding care readiness is represented by this plan.
46    pub const fn pet_id(&self) -> PetId {
47        self.pet_id
48    }
49
50    /// Returns unresolved care gates staff must clear before check-in.
51    pub fn gates(&self) -> &[ReviewGate] {
52        &self.gates
53    }
54
55    /// Summarizes whether the plan is ready for check-in or blocked by review gates.
56    pub fn readiness(&self) -> Readiness {
57        if self.gates.is_empty() {
58            Readiness::ReadyForCheckIn
59        } else {
60            Readiness::Blocked
61        }
62    }
63}
64
65#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
66/// Check-in readiness outcome for a boarding care plan.
67pub enum Readiness {
68    /// Feeding and medication evidence is sufficient for staff to proceed with check-in.
69    ReadyForCheckIn,
70    /// One or more care gates must be resolved before check-in proceeds.
71    Blocked,
72}
73
74#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
75/// Specific care-review gate created from missing or sensitive boarding profile evidence.
76pub struct ReviewGate {
77    /// Care-profile reason that triggered the gate.
78    pub reason: GateReason,
79    /// Human review category required to clear this care issue.
80    pub gate: policy::ReviewGate,
81}
82
83impl ReviewGate {
84    /// Creates a care-review gate with the operational reason and required review category.
85    pub const fn new(reason: GateReason, gate: policy::ReviewGate) -> Self {
86        Self { reason, gate }
87    }
88}
89
90#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
91/// Reasons a boarding care plan requires staff or medical-document review.
92pub enum GateReason {
93    /// The source care profile lacks feeding instructions for the boarding stay.
94    MissingFeedingInstruction,
95    /// At least one medication instruction requires staff or medical-document review.
96    MedicationRequiresReview,
97}