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(
17 valence_model: &str,
18 record_id: &str,
19 owner: OwnerRef,
20 v: &Valence,
21 ) -> Result<()> {
22 if skip_ownership_for_table(valence_model) {
23 return Ok(());
24 }
25
26 let id = ownership_row_id(valence_model, record_id);
27 let sys = system_valence(v);
28 let backend = Self::ownership_backend(valence_model, &sys)?;
29 let row = json!({
30 "id": id,
31 "valence_model": valence_model,
32 "record_id": record_id,
33 "owner_id": owner.owner_id,
34 "owner_type": owner.owner_kind.as_str(),
35 "status": "active",
36 });
37 backend
38 .upsert_record("valence_data_ownership", id.as_str(), row)
39 .await
40 .map_err(|e| Error::Database(e.to_string()))?;
41 crate::read_cache::invalidate("valence_data_ownership", &id);
42 crate::read_cache::invalidate(valence_model, record_id);
43 Ok(())
44 }
45
46 pub async fn mark_deleted_ownership(
48 valence_model: &str,
49 record_id: &str,
50 v: &Valence,
51 ) -> Result<()> {
52 if skip_ownership_for_table(valence_model) {
53 return Ok(());
54 }
55 let id = ownership_row_id(valence_model, record_id);
56 let sys = system_valence(v);
57 let backend = Self::ownership_backend(valence_model, &sys)?;
58 let patch = json!({ "status": "deleted" });
59 backend
60 .merge_record("valence_data_ownership", &id, patch)
61 .await
62 .map_err(|e| Error::Database(e.to_string()))
63 .map(|_| ())?;
64 crate::read_cache::invalidate("valence_data_ownership", &id);
65 crate::read_cache::invalidate(valence_model, record_id);
66 Ok(())
67 }
68
69 pub async fn mark_pending_deletion(
71 valence_model: &str,
72 record_id: &str,
73 v: &Valence,
74 ) -> Result<()> {
75 if skip_ownership_for_table(valence_model) {
76 return Ok(());
77 }
78 let id = ownership_row_id(valence_model, record_id);
79 let sys = system_valence(v);
80 let backend = Self::ownership_backend(valence_model, &sys)?;
81 let row = json!({
82 "id": id,
83 "valence_model": valence_model,
84 "record_id": record_id,
85 "status": "pending_deletion",
86 });
87 backend
88 .upsert_record("valence_data_ownership", id.as_str(), row)
89 .await
90 .map_err(|e| Error::Database(e.to_string()))
91 .map(|_| ())?;
92 crate::read_cache::invalidate("valence_data_ownership", &id);
93 crate::read_cache::invalidate(valence_model, record_id);
94 Ok(())
95 }
96
97 pub async fn transfer_ownership(
99 valence_model: &str,
100 record_id: &str,
101 new_owner: OwnerRef,
102 reason: Option<String>,
103 v: &Valence,
104 ) -> Result<()> {
105 let existing = Self::get_ownership_json(valence_model, record_id, v)
106 .await?
107 .ok_or_else(|| {
108 Error::NotFound(format!("ownership missing for {valence_model}:{record_id}"))
109 })?;
110
111 let from_owner_id = existing
112 .get("owner_id")
113 .and_then(|v| v.as_str())
114 .unwrap_or("")
115 .to_string();
116 let from_owner_type = existing
117 .get("owner_type")
118 .and_then(|v| v.as_str())
119 .unwrap_or("system")
120 .to_string();
121
122 let oid = ownership_row_id(valence_model, record_id);
123 let sys = system_valence(v);
124 let backend = Self::ownership_backend(valence_model, &sys)?;
125 let merged = json!({
126 "owner_id": new_owner.owner_id,
127 "owner_type": new_owner.owner_kind.as_str(),
128 "status": "active",
129 });
130 backend
131 .merge_record("valence_data_ownership", &oid, merged)
132 .await
133 .map_err(|e| Error::Database(e.to_string()))
134 .map(|_| ())?;
135 crate::read_cache::invalidate("valence_data_ownership", &oid);
136 crate::read_cache::invalidate(valence_model, record_id);
137
138 append_transfer_history_row(
139 valence_model,
140 record_id,
141 &oid,
142 &from_owner_id,
143 &from_owner_type,
144 &new_owner,
145 reason,
146 v,
147 )
148 .await
149 }
150}