1use super::*;
2use ahri_tre_protocol::{PublicUuid, refs::ObjectKind, session::SessionStatusPayload, study::*};
3use ahri_tre_types::StudyRecord;
4
5fn governance_scope(
6 session: &SessionStatusPayload,
7 study: &StudyRecord,
8) -> (PublicUuid, StudyRef, String) {
9 let ds = session
10 .datastore_id
11 .expect("governance Session retains its Datastore binding");
12 (
13 ds,
14 object_ref(ds, ObjectKind::Study, study.study_id.0),
15 study.name.as_str().to_owned(),
16 )
17}
18
19pub fn study_add_domain_response(
20 session: SessionStatusPayload,
21 registration: crate::StudyRegistration,
22) -> StudyAddDomainResponse {
23 let ds = session
24 .datastore_id
25 .expect("governance Session retains its Datastore binding");
26 StudyAddDomainResponse {
27 session,
28 registration: study_registration_payload(ds, registration),
29 }
30}
31
32pub fn study_access_grant_response(
33 session: SessionStatusPayload,
34 (study, result): (StudyRecord, crate::StudyAccessGrant),
35) -> StudyAccessGrantResponse {
36 let (ds, study, study_name) = governance_scope(&session, &study);
37 StudyAccessGrantResponse {
38 grant: study_access_grant_summary(ds, study_name.clone(), result.grant),
39 session,
40 study,
41 study_name,
42 }
43}
44
45pub fn study_access_list_response(
46 session: SessionStatusPayload,
47 (study, result): (StudyRecord, crate::StudyAccessGrantList),
48) -> StudyAccessListResponse {
49 let (ds, study, study_name) = governance_scope(&session, &study);
50 StudyAccessListResponse {
51 grants: result
52 .grants
53 .into_iter()
54 .map(|grant| study_access_grant_summary(ds, study_name.clone(), grant))
55 .collect(),
56 session,
57 study,
58 study_name,
59 }
60}
61
62pub fn study_access_revoke_response(
63 session: SessionStatusPayload,
64 (study, result): (StudyRecord, crate::StudyAccessRevocation),
65) -> StudyAccessRevokeResponse {
66 let (_ds, study, study_name) = governance_scope(&session, &study);
67 StudyAccessRevokeResponse {
68 target_user: result.target_user_id,
69 revoked: true,
70 session,
71 study,
72 study_name,
73 }
74}
75
76pub fn study_custodians_list_response(
77 session: SessionStatusPayload,
78 (study, result): (StudyRecord, crate::StudyCustodianList),
79) -> StudyCustodiansListResponse {
80 let (ds, study, study_name) = governance_scope(&session, &study);
81 StudyCustodiansListResponse {
82 custodians: result
83 .custodians
84 .into_iter()
85 .map(|custodian| study_custodian_summary(ds, study_name.clone(), custodian))
86 .collect(),
87 session,
88 study,
89 study_name,
90 }
91}
92
93pub fn study_custodians_add_delegate_response(
94 session: SessionStatusPayload,
95 (study, result): (StudyRecord, crate::StudyCustodian),
96) -> StudyCustodianMutationResponse {
97 let (ds, study, study_name) = governance_scope(&session, &study);
98 StudyCustodianMutationResponse {
99 target_user: result.custodian.user_id.clone(),
100 custodian: Some(study_custodian_summary(
101 ds,
102 study_name.clone(),
103 result.custodian,
104 )),
105 removed: false,
106 session,
107 study,
108 study_name,
109 }
110}
111
112pub fn study_custodians_transfer_primary_response(
113 session: SessionStatusPayload,
114 (study, result): (StudyRecord, crate::StudyPrimaryCustodianshipTransfer),
115) -> StudyCustodianMutationResponse {
116 let (ds, study, study_name) = governance_scope(&session, &study);
117 StudyCustodianMutationResponse {
118 target_user: result.primary_custodian.user_id.clone(),
119 custodian: Some(study_custodian_summary(
120 ds,
121 study_name.clone(),
122 result.primary_custodian,
123 )),
124 removed: false,
125 session,
126 study,
127 study_name,
128 }
129}
130
131pub fn study_custodians_remove_delegate_response(
132 session: SessionStatusPayload,
133 (study, result): (StudyRecord, crate::StudyDelegateCustodianRemoval),
134) -> StudyCustodianMutationResponse {
135 let (_ds, study, study_name) = governance_scope(&session, &study);
136 StudyCustodianMutationResponse {
137 target_user: result.target_user_id,
138 custodian: None,
139 removed: true,
140 session,
141 study,
142 study_name,
143 }
144}
145
146pub fn study_duo_list_response(
147 session: SessionStatusPayload,
148 (study, result): (StudyRecord, crate::StudyDuoRestrictionList),
149) -> StudyDuoListResponse {
150 let (ds, study, study_name) = governance_scope(&session, &study);
151 StudyDuoListResponse {
152 restrictions: result
153 .restrictions
154 .into_iter()
155 .map(|restriction| study_duo_restriction_summary(ds, study_name.clone(), restriction))
156 .collect(),
157 session,
158 study,
159 study_name,
160 }
161}
162
163pub fn study_duo_replace_response(
164 session: SessionStatusPayload,
165 (study, result): (StudyRecord, crate::StudyDuoRestrictionReplacement),
166) -> StudyDuoReplaceResponse {
167 let (ds, study, study_name) = governance_scope(&session, &study);
168 StudyDuoReplaceResponse {
169 restrictions: result
170 .restrictions
171 .into_iter()
172 .map(|restriction| study_duo_restriction_summary(ds, study_name.clone(), restriction))
173 .collect(),
174 session,
175 study,
176 study_name,
177 }
178}
179
180fn study_access_grant_summary(
181 datastore_id: PublicUuid,
182 study_name: String,
183 grant: ahri_tre_types::StudyAccessGrantRecord,
184) -> StudyAccessGrantSummary {
185 StudyAccessGrantSummary {
186 study: object_ref(datastore_id, ObjectKind::Study, grant.study_id.0),
187 study_name,
188 user: grant.user_id,
189 granted_by: grant.granted_by,
190 }
191}
192
193fn study_custodian_summary(
194 datastore_id: PublicUuid,
195 study_name: String,
196 custodian: ahri_tre_types::StudyCustodianLinkRecord,
197) -> StudyCustodianSummary {
198 StudyCustodianSummary {
199 study: object_ref(datastore_id, ObjectKind::Study, custodian.study_id.0),
200 study_name,
201 user: custodian.user_id,
202 primary: custodian.is_primary,
203 granted_by: custodian.granted_by,
204 }
205}
206
207fn study_duo_restriction_summary(
208 datastore_id: PublicUuid,
209 study_name: String,
210 restriction: ahri_tre_types::StudyDuoRestrictionRecord,
211) -> StudyDuoRestrictionSummary {
212 StudyDuoRestrictionSummary {
213 study: object_ref(datastore_id, ObjectKind::Study, restriction.study_id.0),
214 study_name,
215 duo_id: restriction.duo_id,
216 qualifier_ontology_namespace: restriction.qualifier_ontology_namespace,
217 qualifier_ontology_id: restriction.qualifier_ontology_id,
218 qualifier_text: restriction.qualifier_text,
219 qualifier_date: restriction.qualifier_date,
220 qualifier_integer: restriction.qualifier_integer,
221 }
222}
223
224pub fn asset_duo_restriction_summary(
225 study: StudyRef,
226 version: ahri_tre_protocol::refs::VersionRef,
227 restriction: crate::EffectiveAssetVersionDuoRestriction,
228) -> ahri_tre_protocol::asset::AssetDuoRestrictionSummary {
229 use ahri_tre_protocol::asset::AssetDuoRestrictionSource;
230 let (source, governing) = match restriction.source {
231 crate::AssetDuoRestrictionSource::AssetVersion => {
232 (AssetDuoRestrictionSource::AssetVersion, version)
233 }
234 crate::AssetDuoRestrictionSource::StudyDefault => {
235 (AssetDuoRestrictionSource::StudyDefault, study)
236 }
237 };
238 ahri_tre_protocol::asset::AssetDuoRestrictionSummary {
239 source,
240 governing,
241 duo_id: restriction.duo_id,
242 qualifier_ontology_namespace: restriction.qualifier_ontology_namespace,
243 qualifier_ontology_id: restriction.qualifier_ontology_id,
244 qualifier_text: restriction.qualifier_text,
245 qualifier_date: restriction.qualifier_date,
246 qualifier_integer: restriction.qualifier_integer,
247 }
248}
249
250pub fn asset_duo_list_response(
251 session: SessionStatusPayload,
252 result: crate::service::GovernedAssetDuo,
253) -> ahri_tre_protocol::asset::AssetDuoListResponse {
254 let ds = session
255 .datastore_id
256 .expect("governance Session retains its Datastore binding");
257 let asset = safe_asset_catalog(ds, result.catalog).asset;
258 let version = safe_asset_version_summary(ds, result.version);
259 let restrictions = result
260 .restrictions
261 .into_iter()
262 .map(|restriction| {
263 asset_duo_restriction_summary(asset.study_id, version.version_id, restriction)
264 })
265 .collect();
266 ahri_tre_protocol::asset::AssetDuoListResponse {
267 session,
268 study: result.study.name.as_str().into(),
269 asset,
270 version,
271 restrictions,
272 effective: result.effective,
273 }
274}
275pub fn asset_duo_replace_response(
276 session: SessionStatusPayload,
277 result: crate::service::GovernedAssetDuo,
278) -> ahri_tre_protocol::asset::AssetDuoReplaceResponse {
279 let ds = session
280 .datastore_id
281 .expect("governance Session retains its Datastore binding");
282 let asset = safe_asset_catalog(ds, result.catalog).asset;
283 let version = safe_asset_version_summary(ds, result.version);
284 let restrictions = result
285 .restrictions
286 .into_iter()
287 .map(|restriction| {
288 asset_duo_restriction_summary(asset.study_id, version.version_id, restriction)
289 })
290 .collect();
291 ahri_tre_protocol::asset::AssetDuoReplaceResponse {
292 session,
293 study: result.study.name.as_str().into(),
294 asset,
295 version,
296 restrictions,
297 }
298}
299pub fn asset_duo_clear_response(
300 session: SessionStatusPayload,
301 result: crate::service::GovernedAssetDuo,
302) -> ahri_tre_protocol::asset::AssetDuoClearResponse {
303 let ds = session
304 .datastore_id
305 .expect("governance Session retains its Datastore binding");
306 let asset = safe_asset_catalog(ds, result.catalog).asset;
307 let version = safe_asset_version_summary(ds, result.version);
308 let restrictions = result
309 .restrictions
310 .into_iter()
311 .map(|restriction| {
312 asset_duo_restriction_summary(asset.study_id, version.version_id, restriction)
313 })
314 .collect();
315 ahri_tre_protocol::asset::AssetDuoClearResponse {
316 session,
317 study: result.study.name.as_str().into(),
318 asset,
319 version,
320 restrictions,
321 }
322}