valence_core/ownership/service/
write.rs1use serde_json::json;
4
5use crate::error::{Error, Result};
6use crate::owner_ref::OwnerRef;
7use crate::runtime::Valence;
8
9use super::helpers::{
10 append_transfer_history_row, ownership_row_id, skip_ownership_for_table, system_valence,
11};
12use super::OwnershipService;
13
14impl OwnershipService {
15 pub async fn ensure_active_ownership(
20 valence_model: &str,
21 record_id: &str,
22 owner: OwnerRef,
23 v: &Valence,
24 ) -> Result<()> {
25 if skip_ownership_for_table(valence_model) {
26 return Ok(());
27 }
28
29 let id = ownership_row_id(valence_model, record_id);
30 let sys = system_valence(v);
31 let backend = Self::ownership_backend(valence_model, &sys)?;
32 let row = json!({
33 "id": id,
34 "valence_model": valence_model,
35 "record_id": record_id,
36 "owner_id": owner.owner_id,
37 "owner_type": owner.owner_kind.as_str(),
38 "status": "active",
39 });
40 backend
41 .upsert_record("valence_data_ownership", id.as_str(), row)
42 .await
43 .map_err(|e| Error::database(e.to_string()))?;
44 crate::read_cache::invalidate("valence_data_ownership", &id);
45 crate::read_cache::invalidate(valence_model, record_id);
46 Ok(())
47 }
48
49 pub async fn mark_deleted_ownership(
54 valence_model: &str,
55 record_id: &str,
56 v: &Valence,
57 ) -> Result<()> {
58 if skip_ownership_for_table(valence_model) {
59 return Ok(());
60 }
61 let id = ownership_row_id(valence_model, record_id);
62 let sys = system_valence(v);
63 let backend = Self::ownership_backend(valence_model, &sys)?;
64 let patch = json!({ "status": "deleted" });
65 backend
66 .merge_record("valence_data_ownership", &id, patch)
67 .await
68 .map_err(|e| Error::database(e.to_string()))
69 .map(|_| ())?;
70 crate::read_cache::invalidate("valence_data_ownership", &id);
71 crate::read_cache::invalidate(valence_model, record_id);
72 Ok(())
73 }
74
75 pub async fn mark_pending_deletion(
80 valence_model: &str,
81 record_id: &str,
82 v: &Valence,
83 ) -> Result<()> {
84 if skip_ownership_for_table(valence_model) {
85 return Ok(());
86 }
87 let id = ownership_row_id(valence_model, record_id);
88 let sys = system_valence(v);
89 let backend = Self::ownership_backend(valence_model, &sys)?;
90 let row = json!({
91 "id": id,
92 "valence_model": valence_model,
93 "record_id": record_id,
94 "status": "pending_deletion",
95 });
96 backend
97 .upsert_record("valence_data_ownership", id.as_str(), row)
98 .await
99 .map_err(|e| Error::database(e.to_string()))
100 .map(|_| ())?;
101 crate::read_cache::invalidate("valence_data_ownership", &id);
102 crate::read_cache::invalidate(valence_model, record_id);
103 Ok(())
104 }
105
106 pub async fn transfer_ownership(
117 valence_model: &str,
118 record_id: &str,
119 new_owner: OwnerRef,
120 reason: Option<String>,
121 v: &Valence,
122 ) -> Result<()> {
123 let existing = Self::get_ownership_json(valence_model, record_id, v)
124 .await?
125 .ok_or_else(|| {
126 Error::NotFound(format!("ownership missing for {valence_model}:{record_id}"))
127 })?;
128
129 let from_owner_id = existing
130 .get("owner_id")
131 .and_then(|v| v.as_str())
132 .unwrap_or("")
133 .to_string();
134 let from_owner_type = existing
135 .get("owner_type")
136 .and_then(|v| v.as_str())
137 .unwrap_or("system")
138 .to_string();
139
140 let oid = ownership_row_id(valence_model, record_id);
141 let sys = system_valence(v);
142 let backend = Self::ownership_backend(valence_model, &sys)?;
143 let merged = json!({
144 "owner_id": new_owner.owner_id,
145 "owner_type": new_owner.owner_kind.as_str(),
146 "status": "active",
147 });
148 backend
149 .merge_record("valence_data_ownership", &oid, merged)
150 .await
151 .map_err(|e| Error::database(e.to_string()))
152 .map(|_| ())?;
153 crate::read_cache::invalidate("valence_data_ownership", &oid);
154 crate::read_cache::invalidate(valence_model, record_id);
155
156 append_transfer_history_row(
157 valence_model,
158 record_id,
159 &oid,
160 &from_owner_id,
161 &from_owner_type,
162 &new_owner,
163 reason,
164 v,
165 )
166 .await
167 }
168}