qualia_client_core/wellfair/api/
pwa.rs1use super::super::journal::JournalEntry;
4use wellfare_core::finance::{
5 build_ledger_entry_envelope, derived_balance, ledger_entry_summary, parse_ledger_summary,
6 BalanceReport, LedgerEntry,
7};
8use wellfare_core::life_records::{
9 build_case_task_envelope, build_life_event_envelope, build_welfare_case_envelope,
10 case_task_summary, life_event_summary, welfare_case_summary, CaseTaskReport, LifeEventReport,
11 WelfareCaseReport,
12};
13use wellfare_core::mental_wellbeing::{
14 build_therapy_note_envelope, build_wellbeing_observation_envelope, therapy_note_summary,
15 wellbeing_observation_summary, TherapyNote, WellbeingObservation,
16};
17
18use super::*;
19
20impl WebizenHostApi {
21 #[cfg(not(target_arch = "wasm32"))]
27 #[allow(clippy::too_many_arguments)]
28 pub fn publish_qapp_pwa(
29 &self,
30 target_dir: &str,
31 id: &str,
32 name: &str,
33 kind: &str,
34 description: &str,
35 capabilities_csv: &str,
36 wasm_filename: &str,
37 ) -> Result<Vec<String>, String> {
38 let manifest = super::super::qapp_publish::build_manifest(
39 id,
40 name,
41 kind,
42 description,
43 capabilities_csv,
44 wasm_filename,
45 );
46 super::super::qapp_publish::write_pwa_bundle(std::path::Path::new(target_dir), &manifest)
47 }
48
49 pub fn add_life_event(&mut self, report: &LifeEventReport) -> Result<JournalEntry, String> {
50 let payload = serde_json::to_string(report).map_err(|e| e.to_string())?;
51 let hash = Self::payload_hash_hex(&payload);
52 let asserted = Self::now_unix() as u32;
53 let envelope = build_life_event_envelope(
54 report,
55 &self.owner_did,
56 &self.author_did,
57 asserted,
58 Some(hash),
59 );
60 let summary = life_event_summary(report);
61 self.submit_record_with_summary(QAPP_LIFE, envelope, SOURCE_LIFE, Some(summary))?;
62 self.latest_journal_entry()
63 }
64
65 pub fn add_welfare_case(&mut self, report: &WelfareCaseReport) -> Result<JournalEntry, String> {
66 let payload = serde_json::to_string(report).map_err(|e| e.to_string())?;
67 let hash = Self::payload_hash_hex(&payload);
68 let asserted = Self::now_unix() as u32;
69 let envelope = build_welfare_case_envelope(
70 report,
71 &self.owner_did,
72 &self.author_did,
73 asserted,
74 Some(hash),
75 );
76 let summary = welfare_case_summary(report);
77 self.submit_record_with_summary(QAPP_LIFE, envelope, SOURCE_LIFE, Some(summary))?;
78 self.latest_journal_entry()
79 }
80
81 pub fn add_case_task(&mut self, report: &CaseTaskReport) -> Result<JournalEntry, String> {
82 let payload = serde_json::to_string(report).map_err(|e| e.to_string())?;
83 let hash = Self::payload_hash_hex(&payload);
84 let asserted = Self::now_unix() as u32;
85 let envelope = build_case_task_envelope(
86 report,
87 &self.owner_did,
88 &self.author_did,
89 asserted,
90 Some(hash),
91 );
92 let summary = case_task_summary(report);
93 self.submit_record_with_summary(QAPP_LIFE, envelope, SOURCE_LIFE, Some(summary))?;
94 self.latest_journal_entry()
95 }
96
97 pub fn add_wellbeing_observation(
98 &mut self,
99 report: &WellbeingObservation,
100 ) -> Result<JournalEntry, String> {
101 let payload = serde_json::to_string(report).map_err(|e| e.to_string())?;
102 let hash = Self::payload_hash_hex(&payload);
103 let asserted = Self::now_unix() as u32;
104 let envelope = build_wellbeing_observation_envelope(
105 report,
106 &self.owner_did,
107 &self.author_did,
108 asserted,
109 Some(hash),
110 );
111 let summary = wellbeing_observation_summary(report);
112 self.submit_record_with_summary(QAPP_WELLBEING, envelope, SOURCE_WELLBEING, Some(summary))?;
113 self.latest_journal_entry()
114 }
115
116 pub fn add_therapy_note(&mut self, report: &TherapyNote) -> Result<JournalEntry, String> {
117 let payload = serde_json::to_string(report).map_err(|e| e.to_string())?;
118 let hash = Self::payload_hash_hex(&payload);
119 let asserted = Self::now_unix() as u32;
120 let envelope = build_therapy_note_envelope(
121 report,
122 &self.owner_did,
123 &self.author_did,
124 asserted,
125 Some(hash),
126 );
127 let summary = therapy_note_summary(report);
128 self.submit_record_with_summary(QAPP_WELLBEING, envelope, SOURCE_WELLBEING, Some(summary))?;
129 self.latest_journal_entry()
130 }
131
132 pub(crate) fn latest_journal_entry(&self) -> Result<JournalEntry, String> {
133 self.vault
134 .list_health_records(1)
135 .map_err(|e| e.to_string())?
136 .into_iter()
137 .next()
138 .ok_or_else(|| "record committed but not found in journal".to_string())
139 }
140
141 pub fn add_ledger_entry(&mut self, entry: &LedgerEntry) -> Result<JournalEntry, String> {
143 let payload = serde_json::to_string(entry).map_err(|e| e.to_string())?;
144 let hash = Self::payload_hash_hex(&payload);
145 let asserted = Self::now_unix() as u32;
146 let envelope = build_ledger_entry_envelope(
147 entry,
148 &self.owner_did,
149 &self.author_did,
150 asserted,
151 Some(hash),
152 );
153 let summary = ledger_entry_summary(entry);
154 self.submit_record_with_summary(QAPP_FINANCE, envelope, SOURCE_FINANCE, Some(summary))?;
155 self.finalize_batch().ok();
156 self.latest_journal_entry()
157 }
158
159 pub fn list_ledger_entries(&self, limit: usize) -> Result<Vec<JournalEntry>, String> {
161 self.list_journal_by_kind("ledger_entry", limit)
162 }
163
164 pub fn ledger_balance(&self, limit: usize) -> Result<BalanceReport, String> {
167 let rows = self.list_ledger_entries(limit)?;
168 let mut entries = Vec::with_capacity(rows.len());
169 for row in rows {
170 if let Some(ref summary) = row.summary {
171 if let Some((amount_cents, currency)) = parse_ledger_summary(summary) {
172 entries.push(LedgerEntry {
173 id: row.id.clone(),
174 description: String::new(),
175 amount_cents,
176 currency,
177 category: None,
178 counterparty: None,
179 project_id: None,
180 occurred_at_unix: row.asserted_time_unix,
181 });
182 }
183 }
184 }
185 Ok(derived_balance(&entries))
186 }
187}