Skip to main content

ahri_tre_protocol/
asset.rs

1use crate::{
2    PublicName,
3    refs::{AssetRef, SessionSelector},
4    study::StudySelector,
5};
6use ahri_tre_types::{AssetRecord, AssetType, AssetVersionRecord};
7use chrono::{DateTime, Utc};
8use serde::{Deserialize, Serialize};
9
10#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
11#[serde(tag = "kind", rename_all = "snake_case", deny_unknown_fields)]
12pub enum AssetSelector {
13    Id {
14        asset: AssetRef,
15        #[serde(default, skip_serializing_if = "Option::is_none")]
16        study: Option<StudySelector>,
17        #[serde(default, skip_serializing_if = "Option::is_none")]
18        asset_type: Option<AssetType>,
19    },
20    Name {
21        study: StudySelector,
22        name: PublicName,
23        #[serde(default, skip_serializing_if = "Option::is_none")]
24        asset_type: Option<AssetType>,
25    },
26}
27
28#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
29pub struct AssetListRequest {
30    #[serde(default, skip_serializing_if = "Option::is_none")]
31    pub session: Option<SessionSelector>,
32    pub study: StudySelector,
33    #[serde(default, skip_serializing_if = "Option::is_none")]
34    pub asset_type: Option<AssetType>,
35}
36
37#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
38pub struct AssetGetRequest {
39    #[serde(default, skip_serializing_if = "Option::is_none")]
40    pub session: Option<SessionSelector>,
41    pub asset: AssetSelector,
42}
43
44#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
45pub struct AssetVersionsRequest {
46    #[serde(default, skip_serializing_if = "Option::is_none")]
47    pub session: Option<SessionSelector>,
48    pub asset: AssetSelector,
49}
50
51#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
52pub struct AssetDuoListRequest {
53    #[serde(default, skip_serializing_if = "Option::is_none")]
54    pub session: Option<SessionSelector>,
55    pub asset: AssetSelector,
56    #[serde(default, skip_serializing_if = "Option::is_none")]
57    pub version: Option<String>,
58    #[serde(default)]
59    pub effective: bool,
60}
61
62#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
63pub struct AssetDuoRestrictionInput {
64    #[serde(default, skip_serializing_if = "Option::is_none")]
65    pub code: Option<String>,
66    #[serde(default, skip_serializing_if = "Option::is_none")]
67    pub duo_id: Option<String>,
68    #[serde(default, skip_serializing_if = "Option::is_none")]
69    pub qualifier_ontology_namespace: Option<String>,
70    #[serde(default, skip_serializing_if = "Option::is_none")]
71    pub qualifier_ontology_id: Option<String>,
72    #[serde(default, skip_serializing_if = "Option::is_none")]
73    pub qualifier_text: Option<String>,
74    #[serde(default, skip_serializing_if = "Option::is_none")]
75    pub qualifier_date: Option<chrono::NaiveDate>,
76    #[serde(default, skip_serializing_if = "Option::is_none")]
77    pub qualifier_integer: Option<i32>,
78}
79
80#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
81pub struct AssetDuoReplaceRequest {
82    #[serde(default, skip_serializing_if = "Option::is_none")]
83    pub session: Option<SessionSelector>,
84    pub asset: AssetSelector,
85    #[serde(default, skip_serializing_if = "Option::is_none")]
86    pub version: Option<String>,
87    #[serde(default)]
88    pub restrictions: Vec<AssetDuoRestrictionInput>,
89}
90
91#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
92pub struct AssetDuoClearRequest {
93    #[serde(default, skip_serializing_if = "Option::is_none")]
94    pub session: Option<SessionSelector>,
95    pub asset: AssetSelector,
96    #[serde(default, skip_serializing_if = "Option::is_none")]
97    pub version: Option<String>,
98}
99
100#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
101pub struct AssetCatalog {
102    pub asset: AssetRecord,
103    pub versions: Vec<AssetVersionRecord>,
104    pub latest_version: Option<AssetVersionRecord>,
105}
106
107/// Safe catalogue projection of an Asset.
108///
109/// Agent instructions are deliberately excluded because list operations do
110/// not authorize returning workflow instructions or other non-catalogue
111/// metadata.
112#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
113pub struct SafeAssetSummary {
114    pub asset_id: AssetRef,
115    pub study_id: crate::refs::StudyRef,
116    pub name: String,
117    #[serde(default, skip_serializing_if = "Option::is_none")]
118    pub description: Option<String>,
119    pub asset_type: AssetType,
120    #[serde(default, skip_serializing_if = "Option::is_none")]
121    pub date_created: Option<DateTime<Utc>>,
122    #[serde(default, skip_serializing_if = "Option::is_none")]
123    pub created_by: Option<String>,
124}
125
126/// Safe catalogue projection of one governed Asset version.
127#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
128pub struct SafeAssetVersionSummary {
129    pub version_id: crate::refs::VersionRef,
130    pub asset_id: AssetRef,
131    pub major: i32,
132    pub minor: i32,
133    pub patch: i32,
134    #[serde(default, skip_serializing_if = "Option::is_none")]
135    pub version_label: Option<String>,
136    #[serde(default, skip_serializing_if = "Option::is_none")]
137    pub version_note: Option<String>,
138    #[serde(default, skip_serializing_if = "Option::is_none")]
139    pub is_latest: Option<bool>,
140    #[serde(default, skip_serializing_if = "Option::is_none")]
141    pub doi: Option<String>,
142    #[serde(default, skip_serializing_if = "Option::is_none")]
143    pub created_at: Option<DateTime<Utc>>,
144    #[serde(default, skip_serializing_if = "Option::is_none")]
145    pub created_by: Option<String>,
146}
147
148/// Safe Asset and version scope used by remote catalogue list operations.
149#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
150pub struct SafeAssetCatalog {
151    pub asset: SafeAssetSummary,
152    #[serde(default)]
153    pub versions: Vec<SafeAssetVersionSummary>,
154    #[serde(default, skip_serializing_if = "Option::is_none")]
155    pub latest_version: Option<SafeAssetVersionSummary>,
156}
157
158#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
159pub struct AssetListResponse {
160    pub session: crate::session::SessionStatusPayload,
161    pub study: String,
162    pub study_id: crate::refs::StudyRef,
163    pub assets: Vec<SafeAssetSummary>,
164}
165
166#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
167pub struct AssetGetResponse {
168    pub session: crate::session::SessionStatusPayload,
169    pub study: String,
170    pub catalog: SafeAssetCatalog,
171}
172
173#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
174pub struct AssetVersionsResponse {
175    pub session: crate::session::SessionStatusPayload,
176    pub study: String,
177    pub asset: SafeAssetSummary,
178    pub versions: Vec<SafeAssetVersionSummary>,
179    pub latest_version: Option<SafeAssetVersionSummary>,
180}
181
182#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
183#[serde(rename_all = "kebab-case")]
184pub enum AssetDuoRestrictionSource {
185    AssetVersion,
186    StudyDefault,
187}
188
189#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
190pub struct AssetDuoRestrictionSummary {
191    pub governing: crate::refs::ObjectRef,
192    pub source: AssetDuoRestrictionSource,
193    pub duo_id: String,
194    #[serde(default, skip_serializing_if = "Option::is_none")]
195    pub qualifier_ontology_namespace: Option<String>,
196    #[serde(default, skip_serializing_if = "Option::is_none")]
197    pub qualifier_ontology_id: Option<String>,
198    #[serde(default, skip_serializing_if = "Option::is_none")]
199    pub qualifier_text: Option<String>,
200    #[serde(default, skip_serializing_if = "Option::is_none")]
201    pub qualifier_date: Option<chrono::NaiveDate>,
202    #[serde(default, skip_serializing_if = "Option::is_none")]
203    pub qualifier_integer: Option<i32>,
204}
205
206#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
207pub struct AssetDuoListResponse {
208    pub session: crate::session::SessionStatusPayload,
209    pub study: String,
210    pub asset: SafeAssetSummary,
211    pub version: SafeAssetVersionSummary,
212    pub effective: bool,
213    pub restrictions: Vec<AssetDuoRestrictionSummary>,
214}
215
216#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
217pub struct AssetDuoReplaceResponse {
218    pub session: crate::session::SessionStatusPayload,
219    pub study: String,
220    pub asset: SafeAssetSummary,
221    pub version: SafeAssetVersionSummary,
222    pub restrictions: Vec<AssetDuoRestrictionSummary>,
223}
224
225#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
226pub struct AssetDuoClearResponse {
227    pub session: crate::session::SessionStatusPayload,
228    pub study: String,
229    pub asset: SafeAssetSummary,
230    pub version: SafeAssetVersionSummary,
231    pub restrictions: Vec<AssetDuoRestrictionSummary>,
232}