Skip to main content

domain/
care.rs

1//! Care-plan and medical-instruction value objects for safe resort workflows.
2//!
3//! ## Operator-summary
4//!
5//! This module supports the staff queue that turns feeding instructions, allergies,
6//! medical conditions, medication schedules, emergency contacts, and veterinarian
7//! contacts into safe care tasks and shift handoffs. It can reduce labor by making
8//! medication-administration work, special handling, and daily-brief warnings visible
9//! without forcing staff to reread free-text pet notes for every stay.
10//!
11//! It must not automate live medical, medication, grooming, boarding, or customer
12//! communication decisions. Medication names, doses, schedules, medical notes, allergy
13//! labels, customer/provider instructions, and veterinarian or emergency-contact facts
14//! remain authoritative only as their reviewed source records and approval history allow;
15//! this module merely preserves those facts as redacted domain values. Review gates protect
16//! pets, customers, and staff by requiring care-team review before ambiguous, sensitive,
17//! or changed medication/special-care instructions can drive service work or
18//! customer-visible copy.
19//!
20//! Care data is sensitive source evidence: these values promote provider/customer facts
21//! into redacted, validated domain types before staff tasks, daily briefs, or customer
22//! messaging can use them. Review requirements make medication and special-handling labor
23//! explicit instead of hiding the work in free-text notes.
24
25use nutype::nutype;
26#[allow(unused_imports)]
27use serde::{Deserialize, Serialize};
28use std::fmt;
29
30#[nutype(
31    sanitize(trim),
32    validate(not_empty, len_char_max = 1000),
33    derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)
34)]
35/// Redacted feeding instructions that can create care tasks and labor requirements.
36pub struct FeedingInstruction(String);
37
38#[nutype(
39    sanitize(trim),
40    validate(not_empty, len_char_max = 120),
41    derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)
42)]
43/// Redacted allergy label that guards unsafe care or grooming recommendations.
44pub struct AllergyName(String);
45
46#[nutype(
47    sanitize(trim),
48    validate(not_empty, len_char_max = 160),
49    derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)
50)]
51/// Redacted medical-condition label requiring careful human handling.
52pub struct MedicalConditionName(String);
53
54#[nutype(
55    sanitize(trim),
56    validate(not_empty, len_char_max = 1000),
57    derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)
58)]
59/// Redacted medical note retained as evidence, not as autonomous medical advice.
60pub struct MedicalNote(String);
61
62#[nutype(
63    sanitize(trim),
64    validate(not_empty, len_char_max = 160),
65    derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)
66)]
67/// Redacted staff/customer contact name for care-plan coordination.
68pub struct ContactName(String);
69
70#[nutype(
71    sanitize(trim),
72    validate(not_empty, len_char_max = 160),
73    derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)
74)]
75/// Redacted medication name used to schedule administration work safely.
76pub struct MedicationName(String);
77
78#[nutype(
79    sanitize(trim),
80    validate(not_empty, len_char_max = 160),
81    derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)
82)]
83/// Redacted medication dose retained for staff review and audit trails.
84pub struct MedicationDose(String);
85
86#[nutype(
87    sanitize(trim),
88    validate(not_empty, len_char_max = 400),
89    derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)
90)]
91/// Redacted medication schedule that can drive labor and shift-handoff tasks.
92pub struct MedicationSchedule(String);
93
94#[nutype(
95    sanitize(trim),
96    validate(not_empty, len_char_max = 400),
97    derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)
98)]
99/// Redacted reason explaining why care-team review is required before action.
100pub struct ReviewReason(String);
101
102macro_rules! redacted_debug {
103    ($type:ident, $label:literal) => {
104        impl fmt::Debug for $type {
105            fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
106                formatter.write_str($label)
107            }
108        }
109    };
110}
111
112redacted_debug!(FeedingInstruction, "FeedingInstruction(<redacted>)");
113redacted_debug!(AllergyName, "AllergyName(<redacted>)");
114redacted_debug!(MedicalConditionName, "MedicalConditionName(<redacted>)");
115redacted_debug!(MedicalNote, "MedicalNote(<redacted>)");
116redacted_debug!(ContactName, "ContactName(<redacted>)");
117redacted_debug!(MedicationName, "MedicationName(<redacted>)");
118redacted_debug!(MedicationDose, "MedicationDose(<redacted>)");
119redacted_debug!(MedicationSchedule, "MedicationSchedule(<redacted>)");
120redacted_debug!(ReviewReason, "ReviewReason(<redacted>)");
121
122#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
123/// Named staff or customer contact used for care-plan coordination.
124pub struct ContactRef {
125    /// Contact or display name used by staff.
126    pub name: ContactName,
127}
128
129impl ContactRef {
130    /// Assembles this care value from already-validated domain parts.
131    pub fn new(name: ContactName) -> Self {
132        Self { name }
133    }
134}
135
136#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
137/// Whether medication instructions require additional care-team review.
138pub enum MedicationReviewRequirement {
139    /// Medication instructions do not add a review gate beyond normal staff handling.
140    NotRequired,
141    /// Business reason staff should review before proceeding.
142    RequiresReview {
143        /// Care reason staff should review before applying the override.
144        reason: ReviewReason,
145    },
146}
147
148impl MedicationReviewRequirement {
149    /// Returns whether care-team review is required before proceeding.
150    pub fn requires_review(&self) -> bool {
151        matches!(self, Self::RequiresReview { .. })
152    }
153}