1use ahri_tre_core::{
2 ArchiveMode, DataFileSearchCursorAnchor, DataFileSearchPredicate, DatasetSearchCursorAnchor,
3 DatasetSearchPredicate, DeleteTarget, EntitySearchCursorAnchor, EntitySearchPredicate,
4 PredicateSetKind, RelationSearchCursorAnchor, RelationSearchPredicate, StudySearchCursorAnchor,
5 StudySearchPredicate, TagAttachmentTarget, VariableSearchCursorAnchor, VariableSearchPredicate,
6};
7use ahri_tre_types::{
8 AssetId, AssetRecord, AssetVersionDuoRestrictionRecord, AssetVersionEntityRecord,
9 AssetVersionRecord, AssetVersionRelationInstanceRecord, DataFileRecord, DatasetRecord,
10 DatasetVariableLinkRecord, DatasetVersionEntityRecord, DatasetVersionRelationInstanceRecord,
11 DatasetVersionWithdrawalRecord, DomainId, DomainRecord, EntityId, EntityInstanceRecord,
12 EntityRecord, EntityRelationId, EntityRelationRecord, KeyRole, NcName, NewAssetRecord,
13 NewAssetVersionDuoRestrictionRecord, NewAssetVersionRecord, NewDomainRecord, NewEntityRecord,
14 NewEntityRelationRecord, NewStudyDuoRestrictionRecord, NewStudyRecord, NewTransformationRecord,
15 RelationInstanceRecord, StudyAccessGrantRecord, StudyCustodianLinkRecord,
16 StudyDuoRestrictionRecord, StudyEntityInstanceRecord, StudyId, StudyRecord,
17 StudyRelationInstanceRecord, TagRecord, TransformationId, TransformationLineageRecord,
18 TransformationRecord, ValueTypeId, ValueTypeRecord, VariableId, VariableRecord, VersionId,
19 VocabularyId, VocabularyItemId, VocabularyItemRecord, VocabularyMappingRecord,
20 VocabularyRecord,
21};
22use chrono::{DateTime, NaiveDate, Utc};
23use serde::{Deserialize, Serialize};
24use std::io::Read;
25use std::path::PathBuf;
26
27#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
28pub enum DatastoreContentCountStatus {
29 Available,
30 Unsupported,
31 Unavailable,
32}
33
34#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
35pub struct DatastoreContentCount {
36 pub status: DatastoreContentCountStatus,
37 pub count: Option<u64>,
38}
39
40impl DatastoreContentCount {
41 pub const fn available(count: u64) -> Self {
42 Self {
43 status: DatastoreContentCountStatus::Available,
44 count: Some(count),
45 }
46 }
47
48 pub const fn unsupported() -> Self {
49 Self {
50 status: DatastoreContentCountStatus::Unsupported,
51 count: None,
52 }
53 }
54
55 pub const fn unavailable() -> Self {
56 Self {
57 status: DatastoreContentCountStatus::Unavailable,
58 count: None,
59 }
60 }
61}
62
63#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
64pub struct DatastoreContentCounts {
65 pub studies: DatastoreContentCount,
66 pub assets: DatastoreContentCount,
67 pub datasets: DatastoreContentCount,
68 pub datafiles: DatastoreContentCount,
69 pub entities: DatastoreContentCount,
70 pub variables: DatastoreContentCount,
71 pub vocabularies: DatastoreContentCount,
72 pub transformations: DatastoreContentCount,
73}
74
75#[derive(Debug, Clone, Serialize, Deserialize)]
76pub struct FileToDatasetRequest {
77 pub classification: ahri_tre_types::IngestClassification,
78 pub study_id: StudyId,
79 pub dataset_asset_id: Option<AssetId>,
80 pub dataset_name: NcName,
81 pub dataset_version_id: Option<VersionId>,
82 pub input_path: String,
83 pub input_format: Option<String>,
84 pub header: Option<bool>,
85 pub delimiter: Option<char>,
86 #[serde(default)]
87 pub null_strings: Vec<String>,
88 pub json_format: Option<String>,
89 pub sheet: Option<String>,
90 pub description: Option<String>,
91 pub agent_instructions: Option<String>,
92 pub version_note: Option<String>,
93 pub transformation: NewTransformationRecord,
94 #[serde(default)]
95 pub variable_registrations: Vec<DatasetVariableRegistrationRequest>,
96}
97
98#[derive(Debug, Clone, Serialize, Deserialize)]
99pub struct IngestFileRequest {
100 pub classification: ahri_tre_types::IngestClassification,
101 pub study_id: StudyId,
102 pub asset_id: Option<AssetId>,
103 pub asset_name: NcName,
104 pub version_id: Option<VersionId>,
105 pub source: IngestFileSource,
106 pub lake_root: String,
107 pub edam_format: Option<String>,
108 pub compress: bool,
109 pub encrypt: Option<bool>,
110 pub description: Option<String>,
111 pub agent_instructions: Option<String>,
112 pub version_note: Option<String>,
113 pub transformation: NewTransformationRecord,
114}
115
116#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
117#[serde(tag = "type", rename_all = "snake_case")]
118pub enum IngestFileSource {
119 LocalPath { path: String },
120 HttpsUri { uri: String },
121}
122
123pub struct IngestFileContent {
125 pub(crate) acquisition: Option<ahri_tre_types::AcquisitionPath>,
126 pub(crate) upload_validation: Option<ahri_tre_lake::UploadValidation>,
127 source_file_name: String,
128 media_type: Option<String>,
129 content_length: Option<u64>,
130 declared_digest: Option<String>,
131 reader: Box<dyn Read + Send>,
132}
133
134impl std::fmt::Debug for IngestFileContent {
135 fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
136 formatter
137 .debug_struct("IngestFileContent")
138 .field("source_file_name", &self.source_file_name)
139 .field("media_type", &self.media_type)
140 .field("content_length", &self.content_length)
141 .field("declared_digest", &self.declared_digest)
142 .field("reader", &"readable content")
143 .finish()
144 }
145}
146
147impl IngestFileContent {
148 pub fn new(
149 source_file_name: impl Into<String>,
150 media_type: Option<String>,
151 content_length: Option<u64>,
152 declared_digest: Option<String>,
153 reader: impl Read + Send + 'static,
154 ) -> Self {
155 Self {
156 upload_validation: None,
157 acquisition: None,
158 source_file_name: source_file_name.into(),
159 media_type,
160 content_length,
161 declared_digest,
162 reader: Box::new(reader),
163 }
164 }
165
166 pub fn source_file_name(&self) -> &str {
167 &self.source_file_name
168 }
169
170 pub fn media_type(&self) -> Option<&str> {
171 self.media_type.as_deref()
172 }
173
174 pub fn content_length(&self) -> Option<u64> {
175 self.content_length
176 }
177
178 pub fn declared_digest(&self) -> Option<&str> {
179 self.declared_digest.as_deref()
180 }
181
182 pub fn reader_mut(&mut self) -> &mut (dyn Read + Send) {
183 self.reader.as_mut()
184 }
185
186 pub fn into_reader(self) -> Box<dyn Read + Send> {
187 self.reader
188 }
189}
190
191#[derive(Debug)]
192pub struct IngestDataFileRequest {
193 pub classification: ahri_tre_types::IngestClassification,
194 pub study: StudySelector,
195 pub asset_name: NcName,
196 pub content: IngestFileContent,
197 pub format: String,
198 pub description: Option<String>,
199 pub new_version: bool,
200 pub bump_major: bool,
201 pub bump_minor: bool,
202 pub compress: bool,
203 pub encrypt: Option<bool>,
204}
205
206#[derive(Debug, Clone, PartialEq, Eq)]
207pub struct DataFileIngestVersion {
208 pub datafile_id: VersionId,
209 pub edam_format: String,
210 pub digest: String,
211}
212
213#[derive(Debug, Clone, PartialEq, Eq)]
214pub struct DataFileIngestResult {
215 pub study_id: StudyId,
216 pub study_name: NcName,
217 pub catalog: DataFileListAssetCatalog,
218 pub datafile: DataFileIngestVersion,
219 pub transformation_id: TransformationId,
220 pub source_size_bytes: u64,
221 pub stored_size_bytes: u64,
222}
223
224impl DataFileIngestResult {
225 pub fn from_governed_result(study: StudyRecord, ingested: IngestedFileAsset) -> Self {
226 Self {
227 study_id: study.study_id,
228 study_name: study.name,
229 catalog: DataFileListAssetCatalog::from_catalogue(ingested.catalog),
230 datafile: DataFileIngestVersion {
231 datafile_id: ingested.datafile.datafile_id,
232 edam_format: ingested.datafile.edam_format,
233 digest: ingested.datafile.digest.as_str().to_string(),
234 },
235 transformation_id: ingested.lineage.transformation.transformation_id,
236 source_size_bytes: ingested.source_size_bytes,
237 stored_size_bytes: ingested.stored_size_bytes,
238 }
239 }
240}
241
242#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
243pub struct IngestedFileAsset {
244 pub catalog: AssetVersionCatalog,
245 pub datafile: DataFileRecord,
246 pub lineage: TransformationLineageRecord,
247 pub source_size_bytes: u64,
248 pub stored_size_bytes: u64,
249}
250
251#[derive(Debug, Clone, Serialize, Deserialize)]
252pub struct IngestDatasetFileRequest {
253 pub classification: ahri_tre_types::IngestClassification,
254 pub study_id: StudyId,
255 pub source_asset_name: Option<NcName>,
256 pub dataset_asset_id: Option<AssetId>,
257 pub dataset_name: NcName,
258 pub dataset_version_id: Option<VersionId>,
259 pub source: IngestFileSource,
260 pub input_format: Option<String>,
261 pub header: Option<bool>,
262 pub delimiter: Option<char>,
263 #[serde(default)]
264 pub null_strings: Vec<String>,
265 pub json_format: Option<String>,
266 pub sheet: Option<String>,
267 pub description: Option<String>,
268 pub agent_instructions: Option<String>,
269 pub version_note: Option<String>,
270 pub compress_source: bool,
271 pub encrypt_source: Option<bool>,
272 pub ingest_transformation: NewTransformationRecord,
273 pub materialize_transformation: NewTransformationRecord,
274 #[serde(default)]
275 pub strict_metadata: bool,
276 pub sample_rows: Option<usize>,
277 pub vocabulary_threshold: Option<usize>,
278 #[serde(default)]
279 pub force_metadata_updates: bool,
280 #[serde(default)]
281 pub variable_registrations: Vec<DatasetVariableRegistrationRequest>,
282}
283
284#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
285pub struct IngestedDatasetFile {
286 pub source_file: IngestedFileAsset,
287 pub dataset: DatasetMaterialization,
288}
289
290#[derive(Debug, Clone, Serialize, Deserialize)]
291pub struct DataFileToDatasetRequest {
292 pub study_id: StudyId,
293 #[serde(default, skip_serializing_if = "Option::is_none")]
294 pub metadata_domain_id: Option<DomainId>,
295 pub dataset_asset_id: Option<AssetId>,
296 pub dataset_name: NcName,
297 pub dataset_version_id: Option<VersionId>,
298 pub source_datafile_id: VersionId,
299 pub input_format: Option<String>,
300 pub header: Option<bool>,
301 pub delimiter: Option<char>,
302 #[serde(default)]
303 pub null_strings: Vec<String>,
304 pub json_format: Option<String>,
305 pub sheet: Option<String>,
306 pub description: Option<String>,
307 pub agent_instructions: Option<String>,
308 pub version_note: Option<String>,
309 pub transformation: NewTransformationRecord,
310 #[serde(default)]
311 pub strict_metadata: bool,
312 pub sample_rows: Option<usize>,
313 pub vocabulary_threshold: Option<usize>,
314 #[serde(default)]
315 pub force_metadata_updates: bool,
316 #[serde(default)]
317 pub variable_registrations: Vec<DatasetVariableRegistrationRequest>,
318}
319
320#[derive(Debug, Clone, Serialize, Deserialize)]
321pub struct ManagedDataFileToDatasetRequest {
322 pub study_id: StudyId,
323 #[serde(default, skip_serializing_if = "Option::is_none")]
324 pub metadata_domain_id: Option<DomainId>,
325 pub dataset_asset_id: Option<AssetId>,
326 pub dataset_name: NcName,
327 pub dataset_version_id: Option<VersionId>,
328 pub source_asset_name: NcName,
329 pub source_version: Option<String>,
330 pub input_format: Option<String>,
331 pub header: Option<bool>,
332 pub delimiter: Option<char>,
333 #[serde(default)]
334 pub null_strings: Vec<String>,
335 pub json_format: Option<String>,
336 pub sheet: Option<String>,
337 pub description: Option<String>,
338 pub agent_instructions: Option<String>,
339 pub version_note: Option<String>,
340 pub transformation: NewTransformationRecord,
341 #[serde(default)]
342 pub strict_metadata: bool,
343 pub sample_rows: Option<usize>,
344 pub vocabulary_threshold: Option<usize>,
345 #[serde(default)]
346 pub force_metadata_updates: bool,
347 #[serde(default)]
348 pub variable_registrations: Vec<DatasetVariableRegistrationRequest>,
349}
350
351#[derive(Debug, Clone, Serialize, Deserialize)]
352pub struct DeriveDatasetFromManagedDataFileRequest {
353 pub study: StudySelector,
354 pub metadata_domain: DomainSelector,
355 pub dataset_name: NcName,
356 pub source: ahri_tre_protocol::ingest::ManagedDataFileSource,
357 pub input_format: Option<String>,
358 pub header: Option<bool>,
359 pub delimiter: Option<char>,
360 #[serde(default)]
361 pub null_strings: Vec<String>,
362 pub json_format: Option<String>,
363 pub sheet: Option<String>,
364 pub description: Option<String>,
365 pub version_note: Option<String>,
366 #[serde(default)]
367 pub replace: bool,
368 pub new_version: Option<String>,
369 pub transformation: NewTransformationRecord,
370 pub sample_rows: Option<usize>,
371 pub vocabulary_threshold: Option<usize>,
372 #[serde(default)]
373 pub force_metadata_updates: bool,
374}
375
376#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
377pub struct DatasetMaterialization {
378 pub catalog: AssetVersionCatalog,
379 pub dataset: DatasetRecord,
380 pub lineage: TransformationLineageRecord,
381 pub lake_schema: String,
382 pub lake_table: String,
383 pub lake_relation: String,
384 pub row_count: usize,
385 pub column_count: usize,
386 pub variables: Vec<RegisteredDatasetVariable>,
387 #[serde(default)]
388 pub metadata_warnings: Vec<String>,
389}
390
391#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
392pub struct ManagedDataFileDatasetMaterialization {
393 pub source: DataFileMetadata,
394 pub dataset: DatasetMaterialization,
395}
396
397#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
398pub struct DerivedManagedDataFileDataset {
399 pub study: StudyRecord,
400 pub materialization: ManagedDataFileDatasetMaterialization,
401}
402
403#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
404#[serde(rename_all = "snake_case")]
405pub enum DatasetExportFormat {
406 Csv,
407 Ndjson,
408 Parquet,
409 Arrow,
410}
411
412impl DatasetExportFormat {
413 pub const fn extension(self) -> &'static str {
414 match self {
415 Self::Csv => "csv",
416 Self::Ndjson => "ndjson",
417 Self::Parquet => "parquet",
418 Self::Arrow => "arrow",
419 }
420 }
421}
422
423#[derive(Debug, Clone, Serialize, Deserialize)]
424pub struct ExportDatasetRequest {
425 pub dataset_id: VersionId,
426 pub target_dir: PathBuf,
427 pub format: DatasetExportFormat,
428 pub limit: Option<usize>,
429 pub compress: bool,
430 pub overwrite: bool,
431 pub transformation: NewTransformationRecord,
432}
433
434#[derive(Debug, Clone, Serialize, Deserialize)]
435pub struct ExportDatasetToPathRequest {
436 pub dataset_id: VersionId,
437 pub target_path: PathBuf,
438 pub format: DatasetExportFormat,
439 pub limit: Option<usize>,
440 pub compress: bool,
441 pub overwrite: bool,
442 pub transformation: NewTransformationRecord,
443}
444
445#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
446pub struct ExportedDataset {
447 pub catalog: AssetVersionCatalog,
448 pub dataset: DatasetRecord,
449 pub lineage: TransformationLineageRecord,
450 pub format: DatasetExportFormat,
451 pub target_path: PathBuf,
452 pub compressed: bool,
453 pub row_count: usize,
454 pub column_count: usize,
455 pub exported_size_bytes: u64,
456 pub warnings: Vec<String>,
457}
458
459#[derive(Debug, Clone, Serialize, Deserialize)]
460pub struct ExportDataFileRequest {
461 pub datafile_id: VersionId,
462 pub target_dir: PathBuf,
463 pub compress: bool,
464 pub overwrite: bool,
465 pub transformation: NewTransformationRecord,
466}
467
468#[derive(Debug, Clone, Serialize, Deserialize)]
469pub struct ListStudyDataFilesRequest {
470 pub study_id: StudyId,
471 pub include_versions: bool,
472}
473
474#[derive(Debug, Clone, Serialize, Deserialize)]
476pub struct ListDataFilesRequest {
477 pub study: StudySelector,
478 pub include_versions: bool,
479}
480
481#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
482pub struct StudyDataFileEntry {
483 pub catalog: AssetVersionCatalog,
484 pub datafiles: Vec<DataFileRecord>,
485}
486
487#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
489pub struct DataFileListResult {
490 pub study_id: StudyId,
491 pub study_name: NcName,
492 pub datafiles: Vec<DataFileListEntry>,
493}
494
495impl DataFileListResult {
496 pub fn from_catalogue(study: StudyRecord, entries: Vec<StudyDataFileEntry>) -> Self {
498 Self {
499 study_id: study.study_id,
500 study_name: study.name,
501 datafiles: entries
502 .into_iter()
503 .map(|entry| DataFileListEntry {
504 catalog: DataFileListAssetCatalog::from_catalogue(entry.catalog),
505 datafiles: entry
506 .datafiles
507 .into_iter()
508 .map(|datafile| DataFileListVersionSummary {
509 datafile_id: datafile.datafile_id,
510 compressed: datafile.compressed,
511 encrypted: datafile.encrypted,
512 compression_algorithm: datafile.compression_algorithm,
513 encryption_algorithm: datafile.encryption_algorithm,
514 edam_format: datafile.edam_format,
515 })
516 .collect(),
517 })
518 .collect(),
519 }
520 }
521}
522
523#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
525pub struct DataFileListEntry {
526 pub catalog: DataFileListAssetCatalog,
527 pub datafiles: Vec<DataFileListVersionSummary>,
528}
529
530#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
532pub struct DataFileListAssetCatalog {
533 pub asset: DataFileListAssetSummary,
534 pub versions: Vec<AssetVersionRecord>,
535 pub latest_version: Option<AssetVersionRecord>,
536}
537
538impl DataFileListAssetCatalog {
539 pub fn from_catalogue(catalog: AssetVersionCatalog) -> Self {
541 Self {
542 asset: DataFileListAssetSummary {
543 asset_id: catalog.asset.asset_id,
544 study_id: catalog.asset.study_id,
545 name: catalog.asset.name,
546 description: catalog.asset.description,
547 asset_type: catalog.asset.asset_type,
548 date_created: catalog.asset.date_created,
549 created_by: catalog.asset.created_by,
550 },
551 versions: catalog.versions,
552 latest_version: catalog.latest_version,
553 }
554 }
555}
556
557#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
559pub struct DataFileListAssetSummary {
560 pub asset_id: AssetId,
561 pub study_id: StudyId,
562 pub name: NcName,
563 pub description: Option<String>,
564 pub asset_type: ahri_tre_types::AssetType,
565 pub date_created: Option<DateTime<Utc>>,
566 pub created_by: Option<String>,
567}
568
569#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
571pub struct DataFileListVersionSummary {
572 pub datafile_id: VersionId,
573 pub compressed: Option<bool>,
574 pub encrypted: Option<bool>,
575 pub compression_algorithm: Option<String>,
576 pub encryption_algorithm: Option<String>,
577 pub edam_format: String,
578}
579
580#[derive(Debug, Clone, Serialize, Deserialize)]
581pub struct DataFileMetadataRequest {
582 pub study_id: StudyId,
583 pub asset_name: NcName,
584 pub version: Option<String>,
585}
586
587#[derive(Debug, Clone, Serialize, Deserialize)]
588pub struct DataFileMetadataByIdRequest {
589 pub datafile_id: VersionId,
590}
591
592#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
593pub struct DataFileMetadata {
594 pub catalog: AssetVersionCatalog,
595 pub version: AssetVersionRecord,
596 pub datafile: DataFileRecord,
597}
598
599#[derive(Debug, Clone, Serialize, Deserialize)]
600pub struct ExportStudyDataFileRequest {
601 pub study_id: StudyId,
602 pub asset_name: NcName,
603 pub version: Option<String>,
604 pub target_dir: PathBuf,
605 pub compress: bool,
606 pub overwrite: bool,
607 pub transformation: NewTransformationRecord,
608}
609
610#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
611pub struct ExportedDataFile {
612 pub catalog: AssetVersionCatalog,
613 pub datafile: DataFileRecord,
614 pub lineage: TransformationLineageRecord,
615 pub target_path: PathBuf,
616 pub compressed: bool,
617 pub stored_size_bytes: u64,
618 pub logical_size_bytes: u64,
619 pub exported_size_bytes: u64,
620}
621
622#[derive(Debug, Clone, Serialize, Deserialize)]
623pub struct RegisterDatasetVariablesRequest {
624 pub dataset_id: VersionId,
625 pub domain_id: DomainId,
626 pub variables: Vec<DatasetVariableRegistrationRequest>,
627}
628
629#[derive(Debug, Clone, Serialize, Deserialize)]
630pub struct RegisterVocabularyRequest {
631 pub domain_id: DomainId,
632 pub vocabulary_id: Option<VocabularyId>,
633 pub name: NcName,
634 pub description: Option<String>,
635 #[serde(default)]
636 pub items: Vec<RegisterVocabularyItemRequest>,
637 pub force_metadata_updates: bool,
638}
639
640#[derive(Debug, Clone, Serialize, Deserialize)]
641pub struct RegisterVocabularyItemRequest {
642 pub vocabulary_item_id: Option<VocabularyItemId>,
643 pub value: i32,
644 pub code: String,
645 pub description: Option<String>,
646}
647
648#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
649pub struct RegisteredVocabulary {
650 pub vocabulary: VocabularyRecord,
651 pub items: Vec<VocabularyItemRecord>,
652}
653
654#[derive(Debug, Clone, Serialize, Deserialize)]
655pub struct VocabularyItemReference {
656 pub vocabulary_item_id: Option<VocabularyItemId>,
657 pub domain_id: Option<DomainId>,
658 pub vocabulary_id: Option<VocabularyId>,
659 pub vocabulary_name: Option<NcName>,
660 pub value: Option<i32>,
661 pub code: Option<String>,
662}
663
664#[derive(Debug, Clone, Serialize, Deserialize)]
665pub struct RegisterVocabularyMappingRequest {
666 pub from: VocabularyItemReference,
667 pub to: VocabularyItemReference,
668}
669
670#[derive(Debug, Clone, Serialize, Deserialize)]
671pub struct ListVocabularyMappingsRequest {
672 pub from_vocabulary_id: Option<VocabularyId>,
673 pub to_vocabulary_id: Option<VocabularyId>,
674 pub involving_vocabulary_id: Option<VocabularyId>,
675 pub item_id: Option<VocabularyItemId>,
676}
677
678#[derive(Debug, Clone, Serialize, Deserialize)]
679pub struct VocabularyMappingSummaryRequest {
680 pub vocabulary_id: VocabularyId,
681}
682
683#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
684pub struct VocabularyMappingDetail {
685 pub mapping: VocabularyMappingRecord,
686 pub from_vocabulary: VocabularyRecord,
687 pub from_item: VocabularyItemRecord,
688 pub to_vocabulary: VocabularyRecord,
689 pub to_item: VocabularyItemRecord,
690}
691
692#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
693pub struct VocabularyMappingSummaryPeer {
694 pub vocabulary: VocabularyRecord,
695 pub outgoing_count: usize,
696 pub incoming_count: usize,
697}
698
699#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
700pub struct VocabularyMappingSummary {
701 pub vocabulary: VocabularyRecord,
702 pub has_mappings: bool,
703 pub outgoing_count: usize,
704 pub incoming_count: usize,
705 pub mapped_vocabularies: Vec<VocabularyMappingSummaryPeer>,
706}
707
708#[derive(Debug, Clone, Serialize, Deserialize)]
709pub struct RegisterVariableRequest {
710 pub domain_id: DomainId,
711 pub variable_id: Option<VariableId>,
712 pub name: NcName,
713 pub value_type_id: Option<ValueTypeId>,
714 pub value_type: Option<String>,
715 pub value_format: Option<String>,
716 pub vocabulary_id: Option<VocabularyId>,
717 pub key_role: KeyRole,
718 pub description: Option<String>,
719 pub note: Option<String>,
720 pub ontology_namespace: Option<String>,
721 pub ontology_class: Option<String>,
722 pub force_metadata_updates: bool,
723}
724
725#[derive(Debug, Clone, Serialize, Deserialize)]
726pub struct ListVariablesRequest {
727 pub domain: Option<DomainSelector>,
728 pub study: Option<StudySelector>,
729}
730
731#[derive(Debug, Clone, Serialize, Deserialize)]
732pub struct GetVariableRequest {
733 pub variable: VariableSelector,
734}
735
736#[derive(Debug, Clone, Serialize, Deserialize)]
737pub struct AddVariableRequest {
738 pub domain: DomainSelector,
739 pub name: String,
740 pub value_type: String,
741 pub value_format: Option<String>,
742 pub key_role: Option<String>,
743 pub description: Option<String>,
744 pub ontology_namespace: Option<String>,
745 pub ontology_class: Option<String>,
746 pub vocabulary: Option<String>,
747 pub vocabulary_items: Option<String>,
748}
749
750#[derive(Debug, Clone, Serialize, Deserialize)]
751pub struct UpdateVariableRequest {
752 pub variable: VariableSelector,
753 pub value_type: Option<String>,
754 pub value_format: Option<String>,
755 pub key_role: Option<String>,
756 pub description: Option<String>,
757 pub ontology_namespace: Option<String>,
758 pub ontology_class: Option<String>,
759 pub vocabulary: Option<String>,
760}
761
762#[derive(Debug, Clone, Serialize, Deserialize)]
763pub struct SearchVariablesRequest {
764 pub kind: PredicateSetKind,
765 pub predicates: Vec<VariableSearchPredicate>,
766 pub limit: u16,
767 pub after: Option<VariableSearchCursorAnchor>,
768}
769
770#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
771#[serde(tag = "kind", rename_all = "snake_case")]
772pub enum SemanticDeleteTarget {
773 Domain { domain: DomainSelector },
774 Variable { variable: VariableSelector },
775 Vocabulary { vocabulary: VocabularySelector },
776 Entity { entity: EntitySelector },
777 EntityRelation { relation: EntityRelationSelector },
778}
779
780#[derive(Debug, Clone, Serialize, Deserialize)]
781pub struct PlanSemanticDeleteRequest {
782 pub target: SemanticDeleteTarget,
783 pub reason: String,
784 pub actor: Option<String>,
785 #[serde(default = "default_semantic_delete_dry_run")]
786 pub dry_run: bool,
787}
788
789const fn default_semantic_delete_dry_run() -> bool {
790 true
791}
792
793#[derive(Debug, Clone, Serialize, Deserialize)]
794pub struct ExecuteSemanticDeleteRequest {
795 pub plan: SemanticDeletePlan,
796 #[serde(default)]
797 pub confirmed: bool,
798}
799
800#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
801pub struct SemanticDeletePlanningResult {
802 pub accepted: bool,
803 pub plan: Option<SemanticDeletePlan>,
804 #[serde(default)]
805 pub validation_errors: Vec<SemanticDeleteValidationError>,
806}
807
808impl SemanticDeletePlanningResult {
809 pub fn accepted(plan: SemanticDeletePlan) -> Self {
810 Self {
811 accepted: true,
812 plan: Some(plan),
813 validation_errors: Vec::new(),
814 }
815 }
816
817 pub fn rejected(validation_errors: Vec<SemanticDeleteValidationError>) -> Self {
818 Self {
819 accepted: false,
820 plan: None,
821 validation_errors,
822 }
823 }
824}
825
826#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
827pub struct SemanticDeleteValidationError {
828 pub code: String,
829 pub message: String,
830}
831
832#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
833pub struct SemanticDeletePlan {
834 pub target: SemanticDeleteTarget,
835 pub target_identity: SemanticDeleteTargetIdentity,
836 pub authorization: SemanticDeleteAuthorization,
837 pub reason: String,
838 pub actor: String,
839 pub dependency_summary: SemanticDeleteDependencySummary,
840 pub disposition: SemanticDeleteDisposition,
841}
842
843#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
844pub struct SemanticDeleteTargetIdentity {
845 pub domain_id: ahri_tre_types::DomainId,
847 pub kind: SemanticDeleteTargetKind,
848 pub id: String,
849 pub domain: Option<String>,
850 pub name: String,
851}
852
853#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
854#[serde(rename_all = "snake_case")]
855pub enum SemanticDeleteTargetKind {
856 Domain,
857 Variable,
858 Vocabulary,
859 Entity,
860 EntityRelation,
861}
862
863#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
864pub struct SemanticDeleteAuthorization {
865 pub status: SemanticDeleteAuthorizationStatus,
866 pub principal: String,
867 pub requirement: String,
868}
869
870#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
871#[serde(rename_all = "snake_case")]
872pub enum SemanticDeleteAuthorizationStatus {
873 ActorRecorded,
874}
875
876#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
877pub struct SemanticDeleteDependencySummary {
878 pub status: SemanticDeleteDependencyStatus,
879 #[serde(default)]
880 pub active_blockers: Vec<SemanticDeleteDependency>,
881 #[serde(default)]
882 pub historical_blockers: Vec<SemanticDeleteDependency>,
883 #[serde(default)]
884 pub unsupported: Vec<SemanticDeleteDependency>,
885 #[serde(default)]
886 pub delete_candidates: Vec<SemanticDeleteDependency>,
887}
888
889impl SemanticDeleteDependencySummary {
890 pub fn clear(target: SemanticDeleteDependency) -> Self {
891 Self {
892 status: SemanticDeleteDependencyStatus::Clear,
893 active_blockers: Vec::new(),
894 historical_blockers: Vec::new(),
895 unsupported: Vec::new(),
896 delete_candidates: vec![target],
897 }
898 }
899
900 pub fn has_blockers(&self) -> bool {
901 !self.active_blockers.is_empty()
902 || !self.historical_blockers.is_empty()
903 || !self.unsupported.is_empty()
904 }
905}
906
907#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
908#[serde(rename_all = "snake_case")]
909pub enum SemanticDeleteDependencyStatus {
910 Clear,
911 Blocked,
912}
913
914#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
915pub struct SemanticDeleteDependency {
916 pub kind: String,
917 pub identifier: String,
918 pub description: String,
919}
920
921#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
922#[serde(rename_all = "snake_case")]
923pub enum SemanticDeleteDisposition {
924 PhysicalDeleteAllowed,
925 Blocked,
926}
927
928#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
929pub struct ExecuteSemanticDeleteResult {
930 pub plan: SemanticDeletePlan,
931 pub deleted: bool,
932 pub disposition: SemanticDeleteExecutionDisposition,
933}
934
935#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
936#[serde(rename_all = "snake_case")]
937pub enum SemanticDeleteExecutionDisposition {
938 PhysicallyDeleted,
939 AlreadyAbsent,
940}
941
942#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
943pub struct RegisteredVariable {
944 pub variable: VariableRecord,
945 pub value_type: ValueTypeRecord,
946 pub vocabulary: Option<VocabularyRecord>,
947 pub vocabulary_items: Vec<VocabularyItemRecord>,
948}
949
950#[derive(Debug, Clone, Serialize, Deserialize)]
951pub struct VariableSearchEntry {
952 pub variable: VariableRecord,
953 pub value_type: ValueTypeRecord,
954 pub vocabulary: Option<VocabularyRecord>,
955 pub vocabulary_items: Vec<VocabularyItemRecord>,
956 pub tags: Vec<TagRecord>,
957}
958
959#[derive(Debug, Clone, Serialize, Deserialize)]
960pub struct VariableSearchResult {
961 pub variables: Vec<VariableSearchEntry>,
962 pub next_cursor: Option<VariableSearchCursorAnchor>,
963}
964
965#[derive(Debug, Clone, Serialize, Deserialize)]
966pub struct SearchEntitiesRequest {
967 pub kind: PredicateSetKind,
968 pub predicates: Vec<EntitySearchPredicate>,
969 pub limit: u16,
970 pub after: Option<EntitySearchCursorAnchor>,
971}
972
973#[derive(Debug, Clone, Serialize, Deserialize)]
974pub struct EntitySearchEntry {
975 pub entity: EntityRecord,
976 pub tags: Vec<TagRecord>,
977}
978
979#[derive(Debug, Clone, Serialize, Deserialize)]
980pub struct EntitySearchResult {
981 pub entities: Vec<EntitySearchEntry>,
982 pub next_cursor: Option<EntitySearchCursorAnchor>,
983}
984
985#[derive(Debug, Clone, Serialize, Deserialize)]
986pub struct SearchRelationsRequest {
987 pub kind: PredicateSetKind,
988 pub predicates: Vec<RelationSearchPredicate>,
989 pub limit: u16,
990 pub after: Option<RelationSearchCursorAnchor>,
991}
992
993#[derive(Debug, Clone, Serialize, Deserialize)]
994pub struct RelationSearchEntry {
995 pub relation: EntityRelationRecord,
996 pub source_entity: EntityRecord,
997 pub target_entity: EntityRecord,
998 pub tags: Vec<TagRecord>,
999}
1000
1001#[derive(Debug, Clone, Serialize, Deserialize)]
1002pub struct RelationSearchResult {
1003 pub relations: Vec<RelationSearchEntry>,
1004 pub next_cursor: Option<RelationSearchCursorAnchor>,
1005}
1006
1007#[derive(Debug, Clone, Serialize, Deserialize)]
1008pub struct ListVocabulariesRequest {
1009 pub domain: Option<DomainSelector>,
1010 pub study: Option<StudySelector>,
1011}
1012
1013#[derive(Debug, Clone, Serialize, Deserialize)]
1014pub struct GetVocabularyRequest {
1015 pub vocabulary: VocabularySelector,
1016}
1017
1018#[derive(Debug, Clone, Serialize, Deserialize)]
1019pub struct AddVocabularyRequest {
1020 pub domain: DomainSelector,
1021 pub name: String,
1022 pub description: Option<String>,
1023 pub items: String,
1024}
1025
1026#[derive(Debug, Clone, Serialize, Deserialize)]
1027pub struct DatasetVariableRegistrationRequest {
1028 pub variable: VariableRecord,
1029 pub row_role: Option<KeyRole>,
1030 pub vocabulary: Option<VocabularyRecord>,
1031 #[serde(default)]
1032 pub vocabulary_items: Vec<VocabularyItemRecord>,
1033}
1034
1035#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1036pub struct RegisteredDatasetVariable {
1037 pub variable: VariableRecord,
1038 pub vocabulary: Option<VocabularyRecord>,
1039 pub vocabulary_items: Vec<VocabularyItemRecord>,
1040 pub link: DatasetVariableLinkRecord,
1041}
1042
1043#[derive(Debug, Clone, Serialize, Deserialize)]
1044pub struct GetDatasetVariablesRequest {
1045 pub dataset_id: VersionId,
1046}
1047
1048#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1049pub struct DatasetVariableMetadata {
1050 pub link: DatasetVariableLinkRecord,
1051 pub variable: VariableRecord,
1052 pub value_type: ValueTypeRecord,
1053 pub vocabulary: Option<VocabularyRecord>,
1054 pub vocabulary_items: Vec<VocabularyItemRecord>,
1055}
1056
1057#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1058pub struct DatasetVariablesMetadata {
1059 pub dataset: DatasetRecord,
1060 pub variables: Vec<DatasetVariableMetadata>,
1061}
1062
1063#[derive(Debug, Clone, Serialize, Deserialize)]
1064pub struct ListStudyDatasetsRequest {
1065 pub study_id: StudyId,
1066 #[serde(default)]
1067 pub include_versions: bool,
1068}
1069
1070#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1071pub struct DatasetListItem {
1072 pub catalog: AssetVersionCatalog,
1073 pub latest_dataset: Option<DatasetRecord>,
1074}
1075
1076#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1077pub struct StudyDatasetList {
1078 pub study_id: StudyId,
1079 pub datasets: Vec<DatasetListItem>,
1080}
1081
1082#[derive(Debug, Clone, Serialize, Deserialize)]
1083pub struct GetStudyDatasetRequest {
1084 pub study_id: StudyId,
1085 pub dataset_name: NcName,
1086 pub with_variables: bool,
1087}
1088
1089#[derive(Debug, Clone, Serialize, Deserialize)]
1090pub struct DatasetMetadataByIdRequest {
1091 pub dataset_id: AssetId,
1092 pub with_variables: bool,
1093}
1094
1095#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1096pub enum DatasetMetadataSelector {
1097 Id { dataset_id: AssetId },
1098 Name { study: StudySelector, name: NcName },
1099}
1100
1101#[derive(Debug, Clone, Serialize, Deserialize)]
1102pub struct ReadDatasetMetadataRequest {
1103 pub dataset: DatasetMetadataSelector,
1104 pub with_variables: bool,
1105}
1106
1107#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1108pub struct StudyDatasetMetadata {
1109 pub catalog: AssetVersionCatalog,
1110 pub dataset: DatasetRecord,
1111 pub variables_included: bool,
1112 pub variable_count: usize,
1113 pub variables: Vec<DatasetVariableMetadata>,
1114}
1115
1116#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1117pub struct DatasetMetadataResult {
1118 pub study: StudyRecord,
1119 pub metadata: StudyDatasetMetadata,
1120}
1121
1122#[derive(Debug, Clone, Serialize, Deserialize)]
1123pub struct PreviewStudyDatasetRequest {
1124 pub study_id: StudyId,
1125 pub dataset_name: NcName,
1126 pub limit: usize,
1127}
1128
1129#[derive(Debug, Clone, Serialize, Deserialize)]
1130pub struct PreviewDatasetByIdRequest {
1131 pub dataset_id: AssetId,
1132 pub limit: usize,
1133}
1134
1135#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1136pub struct DatasetPreviewColumn {
1137 pub name: String,
1138 pub value_type: String,
1139}
1140
1141#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1142pub struct DatasetPreview {
1143 pub catalog: AssetVersionCatalog,
1144 pub dataset: DatasetRecord,
1145 pub columns: Vec<DatasetPreviewColumn>,
1146 pub rows: Vec<Vec<Option<String>>>,
1147 pub displayed_row_count: usize,
1148 pub total_row_count: usize,
1149 pub truncated: bool,
1150 pub limit: usize,
1151}
1152
1153#[derive(Debug, Clone, Serialize, Deserialize)]
1154pub struct WithdrawDatasetVersionRequest {
1155 pub study_id: StudyId,
1156 pub dataset_name: NcName,
1157 pub version: String,
1158 pub reason: String,
1159 pub actor: Option<String>,
1160 #[serde(default)]
1161 pub force: bool,
1162 #[serde(default)]
1163 pub drop_lake_table: bool,
1164}
1165
1166#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
1167#[serde(rename_all = "snake_case")]
1168pub enum LakeTableDropDisposition {
1169 NotRequested,
1170 DroppedIfExisted,
1171 AlreadyWithdrawn,
1172}
1173
1174#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1175pub struct WithdrawDatasetVersionResult {
1176 pub catalog: AssetVersionCatalog,
1177 pub withdrawn_version: AssetVersionRecord,
1178 pub withdrawal: DatasetVersionWithdrawalRecord,
1179 pub promoted_latest_version: Option<AssetVersionRecord>,
1180 pub lake_relation: String,
1181 pub lake_schema: String,
1182 pub lake_table: String,
1183 pub lake_table_drop: LakeTableDropDisposition,
1184 pub already_withdrawn: bool,
1185}
1186
1187#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1188#[serde(tag = "type", rename_all = "snake_case")]
1189pub enum ArchiveDeleteVersionTarget {
1190 Version { version_id: VersionId },
1191 Latest,
1192}
1193
1194#[derive(Debug, Clone, Serialize, Deserialize)]
1195pub struct PlanArchiveDeleteRequest {
1196 pub target: DeleteTarget,
1197 pub archive_mode: ArchiveMode,
1198 #[serde(default)]
1199 pub cascade: bool,
1200 #[serde(default)]
1201 pub force: bool,
1202 pub reason: String,
1203 pub actor: Option<String>,
1204 pub version_target: Option<ArchiveDeleteVersionTarget>,
1205 #[serde(default)]
1206 pub delete_all_versions: bool,
1207 #[serde(default = "default_archive_delete_dry_run")]
1208 pub dry_run: bool,
1209}
1210
1211const fn default_archive_delete_dry_run() -> bool {
1212 true
1213}
1214
1215#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1216pub struct ArchiveDeletePlanningResult {
1217 pub accepted: bool,
1218 pub plan: Option<ArchiveDeletePlan>,
1219 #[serde(default)]
1220 pub validation_errors: Vec<ArchiveDeleteValidationError>,
1221}
1222
1223impl ArchiveDeletePlanningResult {
1224 pub fn accepted(plan: ArchiveDeletePlan) -> Self {
1225 Self {
1226 accepted: true,
1227 plan: Some(plan),
1228 validation_errors: Vec::new(),
1229 }
1230 }
1231
1232 pub fn rejected(validation_errors: Vec<ArchiveDeleteValidationError>) -> Self {
1233 Self {
1234 accepted: false,
1235 plan: None,
1236 validation_errors,
1237 }
1238 }
1239}
1240
1241#[derive(Debug, Clone, Serialize, Deserialize)]
1242pub struct DeleteDatasetAssetVersionRequest {
1243 pub plan: ArchiveDeletePlan,
1244}
1245
1246#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1247pub struct DeleteDatasetAssetVersionResult {
1248 pub plan: ArchiveDeletePlan,
1249 pub deletion: WithdrawDatasetVersionResult,
1250 pub target_version: AssetVersionRecord,
1251 pub tombstone: DatasetVersionWithdrawalRecord,
1252 pub promoted_latest_version: Option<AssetVersionRecord>,
1253 pub lake_cleanup: LakeTableDropDisposition,
1254 pub retry_state: ArchiveDeleteRetryState,
1255}
1256
1257#[derive(Debug, Clone, Serialize, Deserialize)]
1258pub struct DeleteDataFileAssetVersionRequest {
1259 pub plan: ArchiveDeletePlan,
1260}
1261
1262#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1263pub struct DeleteDataFileAssetVersionResult {
1264 pub plan: ArchiveDeletePlan,
1265 pub asset: AssetRecord,
1266 pub target_version: AssetVersionRecord,
1267 pub datafile: DataFileRecord,
1268 pub promoted_latest_version: Option<AssetVersionRecord>,
1269 pub managed_file_cleanup: ArchiveDeleteCleanupDisposition,
1270 pub metadata_cleanup: ArchiveDeleteCleanupDisposition,
1271 pub removed_size_bytes: Option<u64>,
1272 pub retry_state: ArchiveDeleteRetryState,
1273}
1274
1275#[derive(Debug, Clone, Serialize, Deserialize)]
1276pub struct DeleteAssetRequest {
1277 pub plan: ArchiveDeletePlan,
1278}
1279
1280#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1281pub struct DeleteAssetResult {
1282 pub plan: ArchiveDeletePlan,
1283 pub asset: AssetRecord,
1284 pub version_results: Vec<DeleteAssetVersionResult>,
1285 pub deleted_versions: usize,
1286 pub skipped_versions: usize,
1287 pub failed_versions: usize,
1288 pub metadata_cleanup: ArchiveDeleteCleanupDisposition,
1289 pub retry_state: ArchiveDeleteRetryState,
1290}
1291
1292#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1293#[serde(tag = "kind", rename_all = "snake_case")]
1294pub enum DeleteAssetVersionResult {
1295 Dataset(Box<DeleteDatasetAssetVersionResult>),
1296 Datafile(Box<DeleteDataFileAssetVersionResult>),
1297 Skipped {
1298 version: AssetVersionRecord,
1299 reason: String,
1300 },
1301}
1302
1303#[derive(Debug, Clone, Serialize, Deserialize)]
1304pub struct DeleteArchivedStudyRequest {
1305 pub plan: ArchiveDeletePlan,
1306 pub archive: ArchiveStudyForDeletionResult,
1307}
1308
1309#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1310pub struct DeleteArchivedStudyResult {
1311 pub plan: ArchiveDeletePlan,
1312 pub archive: ArchiveStudyForDeletionResult,
1313 pub source_study: StudyRecord,
1314 pub asset_results: Vec<DeleteAssetResult>,
1315 pub deleted_assets: usize,
1316 pub deleted_versions: usize,
1317 pub skipped_versions: usize,
1318 pub failed_versions: usize,
1319 pub metadata_cleanup: ArchiveDeleteCleanupDisposition,
1320 pub retry_state: ArchiveDeleteRetryState,
1321}
1322
1323#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1324pub struct ArchiveDeleteValidationError {
1325 pub code: String,
1326 pub message: String,
1327}
1328
1329#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1330pub struct ArchiveDeletePlan {
1331 pub target: DeleteTarget,
1332 pub archive_mode: ArchiveMode,
1333 pub archive_required: bool,
1334 pub authorization: ArchiveDeleteAuthorization,
1335 pub cascade: bool,
1336 pub force: bool,
1337 pub reason: String,
1338 pub actor: Option<String>,
1339 pub resolved_version: Option<VersionId>,
1340 pub delete_all_versions: bool,
1341 pub dependency_summary: ArchiveDeleteDependencySummary,
1342 pub archive_preview: ArchiveDeleteStagePreview,
1343 pub metadata_cleanup_preview: ArchiveDeleteStagePreview,
1344 pub lake_cleanup_preview: ArchiveDeleteStagePreview,
1345 pub retry_state: ArchiveDeleteRetryState,
1346}
1347
1348#[derive(Debug, Clone, Serialize, Deserialize)]
1349pub struct PrepareStudyArchiveForDeletionRequest {
1350 pub study_id: StudyId,
1351 pub reason: String,
1352 pub actor: Option<String>,
1353}
1354
1355#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1356pub struct PreparedArchiveDatafileIdentity {
1357 pub archive_study_id: StudyId,
1358 pub archive_asset_name: NcName,
1359 pub archive_asset_id: Option<AssetId>,
1360 pub archive_version_id: Option<VersionId>,
1361 pub archive_datafile_id: Option<VersionId>,
1362 pub bundle_file_name: String,
1363 pub mime_type: String,
1364 pub compression: String,
1365 pub dataset_payload_format: DatasetExportFormat,
1366}
1367
1368#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1369pub struct PreparedStudyArchiveForDeletionResult {
1370 pub source_study: StudyRecord,
1371 pub archive_domain: DomainRecord,
1372 pub archive_study: StudyRecord,
1373 pub archive_datafile: PreparedArchiveDatafileIdentity,
1374 pub reason: String,
1375 pub actor: String,
1376 pub archive_stage: ArchiveDeleteStagePreview,
1377 pub metadata_cleanup_stage: ArchiveDeleteStagePreview,
1378 pub lake_cleanup_stage: ArchiveDeleteStagePreview,
1379 pub source_study_delete_started: bool,
1380 pub lake_payload_created: bool,
1381}
1382
1383#[derive(Debug, Clone, Serialize, Deserialize)]
1384pub struct ArchiveStudyForDeletionRequest {
1385 pub study_id: StudyId,
1386 pub reason: String,
1387 pub actor: Option<String>,
1388 #[serde(default)]
1389 pub overwrite_existing_exports: bool,
1390}
1391
1392#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1393pub struct ArchiveStudyForDeletionResult {
1394 pub prepared: PreparedStudyArchiveForDeletionResult,
1395 pub archive_asset: AssetRecord,
1396 pub archive_version: AssetVersionRecord,
1397 pub archive_datafile: DataFileRecord,
1398 pub manifest: StudyArchiveManifest,
1399 pub source_size_bytes: u64,
1400 pub stored_size_bytes: u64,
1401 pub source_study_delete_started: bool,
1402}
1403
1404#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1405pub struct StudyArchiveManifest {
1406 pub target: StudyArchiveTarget,
1407 pub archive: StudyArchiveRegistration,
1408 pub reason: String,
1409 pub actor: String,
1410 pub created_at: DateTime<Utc>,
1411 pub dataset_payload_format: DatasetExportFormat,
1412 #[serde(default)]
1413 pub domains: Vec<DomainRecord>,
1414 #[serde(default)]
1415 pub variables: Vec<VariableRecord>,
1416 #[serde(default)]
1417 pub vocabularies: Vec<VocabularyRecord>,
1418 #[serde(default)]
1419 pub vocabulary_items: Vec<VocabularyItemRecord>,
1420 #[serde(default)]
1421 pub entities: Vec<ahri_tre_types::EntityRecord>,
1422 #[serde(default)]
1423 pub entity_relations: Vec<EntityRelationRecord>,
1424 #[serde(default)]
1425 pub assets: Vec<AssetRecord>,
1426 #[serde(default)]
1427 pub asset_versions: Vec<AssetVersionRecord>,
1428 #[serde(default)]
1429 pub datasets: Vec<ArchivedDatasetFileRecord>,
1430 #[serde(default)]
1431 pub datafiles: Vec<ArchivedDataFileRecord>,
1432 pub summary: StudyArchiveSummary,
1433}
1434
1435#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1436pub struct StudyArchiveTarget {
1437 pub study_id: StudyId,
1438 pub study_name: NcName,
1439}
1440
1441#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1442pub struct StudyArchiveRegistration {
1443 pub archive_study_id: StudyId,
1444 pub archive_asset_name: NcName,
1445 pub bundle_file_name: String,
1446 pub mime_type: String,
1447 pub compression: String,
1448}
1449
1450#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1451pub struct ArchivedDatasetFileRecord {
1452 pub asset_id: AssetId,
1453 pub asset_name: NcName,
1454 pub version_id: VersionId,
1455 pub major: i32,
1456 pub minor: i32,
1457 pub patch: i32,
1458 pub bundle_path: String,
1459 pub file_format: DatasetExportFormat,
1460 pub row_count: usize,
1461 pub column_count: usize,
1462 pub exported_size_bytes: u64,
1463}
1464
1465#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1466pub struct ArchivedDataFileRecord {
1467 pub asset_id: AssetId,
1468 pub asset_name: NcName,
1469 pub version_id: VersionId,
1470 pub major: i32,
1471 pub minor: i32,
1472 pub patch: i32,
1473 pub bundle_path: String,
1474 pub edam_format: String,
1475 pub exported_size_bytes: u64,
1476}
1477
1478#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
1479pub struct StudyArchiveSummary {
1480 pub asset_count: usize,
1481 pub asset_version_count: usize,
1482 pub dataset_count: usize,
1483 pub datafile_count: usize,
1484 pub domain_count: usize,
1485 pub variable_count: usize,
1486 pub vocabulary_count: usize,
1487 pub vocabulary_item_count: usize,
1488 pub entity_count: usize,
1489 pub entity_relation_count: usize,
1490}
1491
1492#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1493pub struct ArchiveDeleteAuthorization {
1494 pub status: ArchiveDeleteAuthorizationStatus,
1495 pub principal: String,
1496 pub requirement: String,
1497}
1498
1499#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
1500#[serde(rename_all = "snake_case")]
1501pub enum ArchiveDeleteAuthorizationStatus {
1502 Authorized,
1503 ActorRecorded,
1504}
1505
1506#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1507pub struct ArchiveDeleteDependencySummary {
1508 pub status: ArchiveDeleteDependencyStatus,
1509 #[serde(default)]
1510 pub items: Vec<ArchiveDeleteDependencyPreview>,
1511}
1512
1513impl ArchiveDeleteDependencySummary {
1514 pub fn not_analyzed() -> Self {
1515 Self {
1516 status: ArchiveDeleteDependencyStatus::NotAnalyzed,
1517 items: Vec::new(),
1518 }
1519 }
1520}
1521
1522#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
1523#[serde(rename_all = "snake_case")]
1524pub enum ArchiveDeleteDependencyStatus {
1525 NotAnalyzed,
1526 Clear,
1527 RequiresCascade,
1528 Blocked,
1529}
1530
1531#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1532pub struct ArchiveDeleteDependencyPreview {
1533 pub kind: String,
1534 pub identifier: String,
1535 pub action: ArchiveDeleteDependencyAction,
1536}
1537
1538#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
1539#[serde(rename_all = "snake_case")]
1540pub enum ArchiveDeleteDependencyAction {
1541 Archive,
1542 Delete,
1543 MarkInactive,
1544 Retain,
1545 Block,
1546}
1547
1548#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1549pub struct ArchiveDeleteStagePreview {
1550 pub required: bool,
1551 pub disposition: ArchiveDeleteCleanupDisposition,
1552 pub retryable: bool,
1553 pub summary: String,
1554}
1555
1556impl ArchiveDeleteStagePreview {
1557 pub fn pending(required: bool, summary: impl Into<String>) -> Self {
1558 Self {
1559 required,
1560 disposition: ArchiveDeleteCleanupDisposition::Pending,
1561 retryable: false,
1562 summary: summary.into(),
1563 }
1564 }
1565}
1566
1567#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
1568#[serde(rename_all = "snake_case")]
1569pub enum ArchiveDeleteCleanupDisposition {
1570 NotRequired,
1571 Pending,
1572 Completed,
1573 Skipped,
1574 FailedRetryable,
1575 FailedTerminal,
1576}
1577
1578#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
1579#[serde(rename_all = "snake_case")]
1580pub enum ArchiveDeleteRetryState {
1581 NotStarted,
1582 NotRetryable,
1583 Retryable,
1584 Completed,
1585}
1586
1587#[derive(Debug, Clone, Serialize, Deserialize)]
1588pub struct GetTagsRequest {
1589 pub target: TagAttachmentTarget,
1590}
1591
1592#[derive(Debug, Clone, Serialize, Deserialize)]
1593pub struct SetTagsRequest {
1594 pub target: TagAttachmentTarget,
1595 #[serde(default)]
1596 pub tags: Vec<String>,
1597}
1598
1599#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1600pub struct TargetTags {
1601 pub target: TagAttachmentTarget,
1602 pub tags: Vec<TagRecord>,
1603}
1604
1605#[derive(Debug, Clone, Serialize, Deserialize)]
1606pub struct RegisterEntityRequest {
1607 pub entity: NewEntityRecord,
1608}
1609
1610#[derive(Debug, Clone, Serialize, Deserialize)]
1611pub struct RegisterEntityRelationRequest {
1612 pub relation: NewEntityRelationRecord,
1613}
1614
1615#[derive(Debug, Clone, Serialize, Deserialize)]
1616pub struct ListEntitiesRequest {
1617 pub domain: DomainSelector,
1618}
1619
1620#[derive(Debug, Clone, Serialize, Deserialize)]
1621pub struct GetEntityRequest {
1622 pub entity: EntitySelector,
1623}
1624
1625#[derive(Debug, Clone, Serialize, Deserialize)]
1626pub struct AddEntityRequest {
1627 pub domain: DomainSelector,
1628 pub name: String,
1629 pub description: Option<String>,
1630 pub agent_instructions: Option<String>,
1631 pub ontology_namespace: Option<String>,
1632 pub ontology_class: Option<String>,
1633}
1634
1635#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1636pub enum EntitySelector {
1637 Id {
1638 entity_id: EntityId,
1639 },
1640 Name {
1641 domain: DomainSelector,
1642 name: String,
1643 },
1644}
1645
1646impl From<(String, String)> for EntitySelector {
1647 fn from((domain, name): (String, String)) -> Self {
1648 Self::Name {
1649 domain: domain.into(),
1650 name,
1651 }
1652 }
1653}
1654
1655impl From<(&str, &str)> for EntitySelector {
1656 fn from((domain, name): (&str, &str)) -> Self {
1657 Self::Name {
1658 domain: domain.into(),
1659 name: name.to_string(),
1660 }
1661 }
1662}
1663
1664impl From<EntityId> for EntitySelector {
1665 fn from(entity_id: EntityId) -> Self {
1666 Self::Id { entity_id }
1667 }
1668}
1669
1670#[derive(Debug, Clone, Serialize, Deserialize)]
1671pub struct ListEntityRelationsRequest {
1672 pub domain: DomainSelector,
1673}
1674
1675#[derive(Debug, Clone, Serialize, Deserialize)]
1676pub struct GetEntityRelationRequest {
1677 pub relation: EntityRelationSelector,
1678}
1679
1680#[derive(Debug, Clone, Serialize, Deserialize)]
1681pub struct AddEntityRelationRequest {
1682 pub domain: DomainSelector,
1683 pub name: String,
1684 pub subject: String,
1685 pub object: String,
1686 pub description: Option<String>,
1687 pub agent_instructions: Option<String>,
1688 pub ontology_namespace: Option<String>,
1689 pub ontology_class: Option<String>,
1690}
1691
1692#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1693pub enum EntityRelationSelector {
1694 Id {
1695 entity_relation_id: EntityRelationId,
1696 },
1697 Name {
1698 domain: DomainSelector,
1699 name: String,
1700 },
1701}
1702
1703impl From<(String, String)> for EntityRelationSelector {
1704 fn from((domain, name): (String, String)) -> Self {
1705 Self::Name {
1706 domain: domain.into(),
1707 name,
1708 }
1709 }
1710}
1711
1712impl From<(&str, &str)> for EntityRelationSelector {
1713 fn from((domain, name): (&str, &str)) -> Self {
1714 Self::Name {
1715 domain: domain.into(),
1716 name: name.to_string(),
1717 }
1718 }
1719}
1720
1721impl From<EntityRelationId> for EntityRelationSelector {
1722 fn from(entity_relation_id: EntityRelationId) -> Self {
1723 Self::Id { entity_relation_id }
1724 }
1725}
1726
1727#[derive(Debug, Clone, Serialize, Deserialize)]
1728pub struct GetEntityInstanceRequest {
1729 pub instance_id: i64,
1730}
1731
1732#[derive(Debug, Clone, Serialize, Deserialize)]
1733pub struct ListEntityInstancesRequest {
1734 pub domain: String,
1735 pub entity: String,
1736}
1737
1738#[derive(Debug, Clone, Serialize, Deserialize)]
1739pub struct AddEntityInstanceRequest {
1740 pub domain: String,
1741 pub entity: String,
1742 pub transformation_id: TransformationId,
1743 pub label: Option<String>,
1744 pub note: Option<String>,
1745}
1746
1747#[derive(Debug, Clone, Serialize, Deserialize)]
1748pub struct AddStudyEntityInstanceMappingRequest {
1749 pub study: String,
1750 pub instance_id: i64,
1751 pub external_id: String,
1752 pub transformation_id: TransformationId,
1753}
1754
1755#[derive(Debug, Clone, Serialize, Deserialize)]
1756pub struct GetStudyEntityInstanceMappingRequest {
1757 pub study: String,
1758 pub domain: String,
1759 pub entity: String,
1760 pub external_id: String,
1761}
1762
1763#[derive(Debug, Clone, Serialize, Deserialize)]
1764pub struct EntityInstanceMapping {
1765 pub instance: EntityInstanceRecord,
1766 pub mapping: StudyEntityInstanceRecord,
1767}
1768
1769#[derive(Debug, Clone, Serialize, Deserialize)]
1770pub struct ListStudyEntityInstanceMappingsRequest {
1771 pub study: String,
1772 pub domain: Option<String>,
1773 pub entity: Option<String>,
1774}
1775
1776#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1777pub struct EntityInstanceMappingReadback {
1778 pub study: StudyRecord,
1779 pub domain: DomainRecord,
1780 pub entity: EntityRecord,
1781 pub instance: EntityInstanceRecord,
1782 pub mapping: StudyEntityInstanceRecord,
1783}
1784
1785#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1786pub struct EntityInstanceMappingList {
1787 pub study: StudyRecord,
1788 pub mappings: Vec<EntityInstanceMappingReadback>,
1789}
1790
1791#[derive(Debug, Clone, Serialize, Deserialize)]
1792pub struct AddEntityAssetLinkRequest {
1793 pub study: String,
1794 pub instance_id: i64,
1795 pub asset: String,
1796 pub version: Option<String>,
1797 pub transformation_id: TransformationId,
1798}
1799
1800#[derive(Debug, Clone, Serialize, Deserialize)]
1801pub struct ListEntityAssetLinksRequest {
1802 pub instance_id: Option<i64>,
1803 pub study: Option<String>,
1804 pub asset: Option<String>,
1805 pub version: Option<String>,
1806}
1807
1808#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1809pub struct EntityAssetLinkReadback {
1810 pub study: StudyRecord,
1811 pub asset: AssetRecord,
1812 pub version: AssetVersionRecord,
1813 pub domain: DomainRecord,
1814 pub entity: EntityRecord,
1815 pub instance: EntityInstanceRecord,
1816 pub study_mapping: Option<StudyEntityInstanceRecord>,
1817 pub link: AssetVersionEntityRecord,
1818}
1819
1820#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1821pub struct EntityAssetLinkList {
1822 pub resolved_asset: Option<AssetRecord>,
1823 pub resolved_version: Option<AssetVersionRecord>,
1824 pub links: Vec<EntityAssetLinkReadback>,
1825}
1826
1827#[derive(Debug, Clone, Serialize, Deserialize)]
1828pub struct AddEntityDatasetLinkRequest {
1829 pub study: String,
1830 pub instance_id: i64,
1831 pub dataset: String,
1832 pub variable: String,
1833 pub version: Option<String>,
1834 pub transformation_id: TransformationId,
1835}
1836
1837#[derive(Debug, Clone, Serialize, Deserialize)]
1838pub struct ListEntityInstanceDatasetsRequest {
1839 pub instance_id: i64,
1840}
1841
1842#[derive(Debug, Clone, Serialize, Deserialize)]
1843pub struct GetEntityDatasetLinkRequest {
1844 pub instance_id: i64,
1845 pub study: Option<String>,
1846 pub dataset: String,
1847 pub version: Option<String>,
1848}
1849
1850#[derive(Debug, Clone, Serialize, Deserialize)]
1851pub struct ListEntityDatasetLinksRequest {
1852 pub study: Option<String>,
1853 pub dataset: String,
1854 pub version: Option<String>,
1855}
1856
1857#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1858pub struct EntityDatasetLinkReadback {
1859 pub study: StudyRecord,
1860 pub dataset: AssetRecord,
1861 pub version: AssetVersionRecord,
1862 pub domain: DomainRecord,
1863 pub entity: EntityRecord,
1864 pub instance: EntityInstanceRecord,
1865 pub study_mapping: Option<StudyEntityInstanceRecord>,
1866 pub variable: VariableRecord,
1867 pub link: DatasetVersionEntityRecord,
1868}
1869
1870#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1871pub struct EntityDatasetLinkList {
1872 pub resolved_dataset: Option<AssetRecord>,
1873 pub resolved_version: Option<AssetVersionRecord>,
1874 pub links: Vec<EntityDatasetLinkReadback>,
1875}
1876
1877#[derive(Debug, Clone, Serialize, Deserialize)]
1878pub struct GetRelationInstanceRequest {
1879 pub relation_instance_id: i64,
1880}
1881
1882#[derive(Debug, Clone, Serialize, Deserialize)]
1883pub struct ListRelationInstancesRequest {
1884 pub domain: String,
1885 pub name: String,
1886}
1887
1888#[derive(Debug, Clone, Serialize, Deserialize)]
1889pub struct AddRelationInstanceRequest {
1890 pub domain: String,
1891 pub name: String,
1892 pub subject_instance_id: i64,
1893 pub object_instance_id: i64,
1894 pub transformation_id: TransformationId,
1895 pub valid_from: Option<NaiveDate>,
1896 pub valid_to: Option<NaiveDate>,
1897 pub note: Option<String>,
1898}
1899
1900#[derive(Debug, Clone, Serialize, Deserialize)]
1901pub struct AddStudyRelationInstanceMappingRequest {
1902 pub study: String,
1903 pub relation_instance_id: i64,
1904 pub external_id: String,
1905 pub transformation_id: TransformationId,
1906}
1907
1908#[derive(Debug, Clone, Serialize, Deserialize)]
1909pub struct GetStudyRelationInstanceMappingRequest {
1910 pub study: String,
1911 pub domain: String,
1912 pub name: String,
1913 pub external_id: String,
1914}
1915
1916#[derive(Debug, Clone, Serialize, Deserialize)]
1917pub struct RelationInstanceMapping {
1918 pub instance: RelationInstanceRecord,
1919 pub mapping: StudyRelationInstanceRecord,
1920}
1921
1922#[derive(Debug, Clone, Serialize, Deserialize)]
1923pub struct ListStudyRelationInstanceMappingsRequest {
1924 pub study: String,
1925 pub domain: Option<String>,
1926 pub relation: Option<String>,
1927}
1928
1929#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1930pub struct RelationInstanceMappingReadback {
1931 pub study: StudyRecord,
1932 pub domain: DomainRecord,
1933 pub relation: EntityRelationRecord,
1934 pub subject_entity: EntityRecord,
1935 pub object_entity: EntityRecord,
1936 pub subject_instance: EntityInstanceRecord,
1937 pub object_instance: EntityInstanceRecord,
1938 pub instance: RelationInstanceRecord,
1939 pub mapping: StudyRelationInstanceRecord,
1940}
1941
1942#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1943pub struct RelationInstanceMappingList {
1944 pub study: StudyRecord,
1945 pub mappings: Vec<RelationInstanceMappingReadback>,
1946}
1947
1948#[derive(Debug, Clone, Serialize, Deserialize)]
1949pub struct AddRelationAssetLinkRequest {
1950 pub study: String,
1951 pub relation_instance_id: i64,
1952 pub asset: String,
1953 pub version: Option<String>,
1954 pub transformation_id: TransformationId,
1955}
1956
1957#[derive(Debug, Clone, Serialize, Deserialize)]
1958pub struct ListRelationAssetLinksRequest {
1959 pub relation_instance_id: Option<i64>,
1960 pub study: Option<String>,
1961 pub asset: Option<String>,
1962 pub version: Option<String>,
1963}
1964
1965#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1966pub struct RelationAssetLinkReadback {
1967 pub study: StudyRecord,
1968 pub asset: AssetRecord,
1969 pub version: AssetVersionRecord,
1970 pub domain: DomainRecord,
1971 pub relation: EntityRelationRecord,
1972 pub subject_entity: EntityRecord,
1973 pub object_entity: EntityRecord,
1974 pub subject_instance: EntityInstanceRecord,
1975 pub object_instance: EntityInstanceRecord,
1976 pub instance: RelationInstanceRecord,
1977 pub study_mapping: Option<StudyRelationInstanceRecord>,
1978 pub link: AssetVersionRelationInstanceRecord,
1979}
1980
1981#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1982pub struct RelationAssetLinkList {
1983 pub resolved_asset: Option<AssetRecord>,
1984 pub resolved_version: Option<AssetVersionRecord>,
1985 pub links: Vec<RelationAssetLinkReadback>,
1986}
1987
1988#[derive(Debug, Clone, Serialize, Deserialize)]
1989pub struct AddRelationDatasetLinkRequest {
1990 pub study: String,
1991 pub relation_instance_id: i64,
1992 pub dataset: String,
1993 pub subject_variable: String,
1994 pub object_variable: String,
1995 pub relation_variable: Option<String>,
1996 pub version: Option<String>,
1997 pub transformation_id: TransformationId,
1998}
1999
2000#[derive(Debug, Clone, Serialize, Deserialize)]
2001pub struct GetRelationDatasetLinkRequest {
2002 pub relation_instance_id: i64,
2003 pub study: Option<String>,
2004 pub dataset: String,
2005 pub version: Option<String>,
2006}
2007
2008#[derive(Debug, Clone, Serialize, Deserialize)]
2009pub struct ListRelationDatasetLinksRequest {
2010 pub study: Option<String>,
2011 pub dataset: String,
2012 pub version: Option<String>,
2013}
2014
2015#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2016pub struct RelationDatasetLinkReadback {
2017 pub study: StudyRecord,
2018 pub dataset: AssetRecord,
2019 pub version: AssetVersionRecord,
2020 pub domain: DomainRecord,
2021 pub relation: EntityRelationRecord,
2022 pub subject_entity: EntityRecord,
2023 pub object_entity: EntityRecord,
2024 pub subject_instance: EntityInstanceRecord,
2025 pub object_instance: EntityInstanceRecord,
2026 pub instance: RelationInstanceRecord,
2027 pub study_mapping: Option<StudyRelationInstanceRecord>,
2028 pub subject_variable: VariableRecord,
2029 pub object_variable: VariableRecord,
2030 pub relation_variable: Option<VariableRecord>,
2031 pub link: DatasetVersionRelationInstanceRecord,
2032}
2033
2034#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2035pub struct RelationDatasetLinkList {
2036 pub resolved_dataset: Option<AssetRecord>,
2037 pub resolved_version: Option<AssetVersionRecord>,
2038 pub links: Vec<RelationDatasetLinkReadback>,
2039}
2040
2041#[derive(Debug, Clone, Serialize, Deserialize)]
2042pub struct EnsureStudyEntityInstanceRequest {
2043 pub study_id: StudyId,
2044 pub entity_id: EntityId,
2045 pub external_id: String,
2046 pub canonical_uuid: Option<uuid::Uuid>,
2047 pub label: Option<String>,
2048 pub note: Option<String>,
2049 pub transformation_id: TransformationId,
2050}
2051
2052#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2053pub struct StudyEntityInstanceRegistration {
2054 pub instance: EntityInstanceRecord,
2055 pub mapping: StudyEntityInstanceRecord,
2056}
2057
2058#[derive(Debug, Clone, Serialize, Deserialize)]
2059pub struct EnsureEntityInstancesFromDatasetRequest {
2060 pub study: String,
2061 pub domain: String,
2062 pub entity: String,
2063 pub dataset: String,
2064 pub version: Option<String>,
2065 pub external_id_variable: String,
2066 pub label_template: Option<String>,
2067 pub dry_run: bool,
2068}
2069
2070#[derive(Debug, Clone, Serialize, Deserialize)]
2071pub struct EnsureRelationInstancesFromDatasetRequest {
2072 pub study: String,
2073 pub domain: String,
2074 pub relation: String,
2075 pub dataset: String,
2076 pub version: Option<String>,
2077 pub relation_external_id_variable: String,
2078 pub subject_external_id_variable: String,
2079 pub object_external_id_variable: String,
2080 pub valid_from_variable: Option<String>,
2081 pub valid_to_variable: Option<String>,
2082 pub dry_run: bool,
2083}
2084
2085#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2086pub struct EntityInstanceDatasetBatchCounts {
2087 pub created_instances: usize,
2088 pub reused_instances: usize,
2089 pub created_study_mappings: usize,
2090 pub reused_study_mappings: usize,
2091 pub created_dataset_links: usize,
2092 pub reused_dataset_links: usize,
2093 pub rejected_rows: usize,
2094 pub conflicts: usize,
2095}
2096
2097#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2098pub struct EntityInstanceDatasetBatchConflict {
2099 pub external_id: String,
2100 pub message: String,
2101}
2102
2103#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2104pub struct EntityInstanceDatasetBatchRejectedRow {
2105 pub row_number: usize,
2106 pub reason: String,
2107}
2108
2109#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2110pub struct EntityInstanceDatasetBatchResult {
2111 pub schema_version: String,
2112 pub operation: String,
2113 pub dry_run: bool,
2114 pub study: String,
2115 pub domain: String,
2116 pub entity: String,
2117 pub dataset: String,
2118 pub requested_version: Option<String>,
2119 pub resolved_version: String,
2120 pub external_id_variable: String,
2121 pub label_template: Option<String>,
2122 pub transformation_id: Option<TransformationId>,
2123 pub transformation: Option<TransformationLineageRecord>,
2124 pub counts: EntityInstanceDatasetBatchCounts,
2125 pub conflicts: Vec<EntityInstanceDatasetBatchConflict>,
2126 pub rejected_rows: Vec<EntityInstanceDatasetBatchRejectedRow>,
2127}
2128
2129#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2130pub struct RelationInstanceDatasetBatchCounts {
2131 pub created_instances: usize,
2132 pub reused_instances: usize,
2133 pub created_study_mappings: usize,
2134 pub reused_study_mappings: usize,
2135 pub created_dataset_links: usize,
2136 pub reused_dataset_links: usize,
2137 pub missing_endpoints: usize,
2138 pub rejected_rows: usize,
2139 pub conflicts: usize,
2140}
2141
2142#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2143pub struct RelationInstanceDatasetBatchConflict {
2144 pub external_id: String,
2145 pub message: String,
2146}
2147
2148#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2149pub struct RelationInstanceDatasetBatchMissingEndpoint {
2150 pub relation_external_id: String,
2151 pub endpoint_role: String,
2152 pub endpoint_external_id: String,
2153 pub entity_id: EntityId,
2154}
2155
2156#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2157pub struct RelationInstanceDatasetBatchRejectedRow {
2158 pub row_number: usize,
2159 pub reason: String,
2160}
2161
2162#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2163pub struct RelationInstanceDatasetBatchResult {
2164 pub schema_version: String,
2165 pub operation: String,
2166 pub dry_run: bool,
2167 pub study: String,
2168 pub domain: String,
2169 pub relation: String,
2170 pub dataset: String,
2171 pub requested_version: Option<String>,
2172 pub resolved_version: String,
2173 pub relation_external_id_variable: String,
2174 pub subject_external_id_variable: String,
2175 pub object_external_id_variable: String,
2176 pub valid_from_variable: Option<String>,
2177 pub valid_to_variable: Option<String>,
2178 pub transformation_id: Option<TransformationId>,
2179 pub transformation: Option<TransformationLineageRecord>,
2180 pub counts: RelationInstanceDatasetBatchCounts,
2181 pub conflicts: Vec<RelationInstanceDatasetBatchConflict>,
2182 pub missing_endpoints: Vec<RelationInstanceDatasetBatchMissingEndpoint>,
2183 pub rejected_rows: Vec<RelationInstanceDatasetBatchRejectedRow>,
2184}
2185
2186#[derive(Debug, Clone, Serialize, Deserialize)]
2187pub struct EnsureStudyRelationInstanceRequest {
2188 pub study_id: StudyId,
2189 pub entity_relation_id: EntityRelationId,
2190 pub external_id: String,
2191 pub subject_entity_instance_id: i64,
2192 pub object_entity_instance_id: i64,
2193 pub valid_from: Option<NaiveDate>,
2194 pub valid_to: Option<NaiveDate>,
2195 pub note: Option<String>,
2196 pub transformation_id: TransformationId,
2197}
2198
2199#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2200pub struct StudyRelationInstanceRegistration {
2201 pub instance: RelationInstanceRecord,
2202 pub mapping: StudyRelationInstanceRecord,
2203}
2204
2205#[derive(Debug, Clone, Serialize, Deserialize)]
2206pub struct LinkDatasetVersionEntitiesRequest {
2207 #[serde(default)]
2208 pub links: Vec<DatasetVersionEntityRecord>,
2209}
2210
2211#[derive(Debug, Clone, Serialize, Deserialize)]
2212pub struct LinkDatasetVersionRelationInstancesRequest {
2213 #[serde(default)]
2214 pub links: Vec<DatasetVersionRelationInstanceRecord>,
2215}
2216
2217#[derive(Debug, Clone, Serialize, Deserialize)]
2218pub struct ListStudyTransformationsRequest {
2219 pub study: String,
2220}
2221
2222#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2223pub struct TransformationSummary {
2224 pub transformation: TransformationRecord,
2225 pub inputs: Vec<ahri_tre_types::TransformationInputLinkRecord>,
2226 pub outputs: Vec<ahri_tre_types::TransformationOutputLinkRecord>,
2227}
2228
2229#[derive(Debug, Clone, Serialize, Deserialize)]
2230pub struct SqlToDatasetRequest {
2231 pub classification: ahri_tre_types::IngestClassification,
2232 pub study_id: StudyId,
2233 pub domain_id: DomainId,
2234 pub dataset_asset_id: Option<AssetId>,
2235 pub dataset_name: NcName,
2236 pub dataset_version_id: Option<VersionId>,
2237 pub sql: String,
2238 pub description: Option<String>,
2239 pub agent_instructions: Option<String>,
2240 pub version_note: Option<String>,
2241 pub transformation: NewTransformationRecord,
2242 pub force_metadata_updates: bool,
2243}
2244
2245#[derive(Debug, Clone, Serialize, Deserialize)]
2246pub struct DatasetSqlTransformRequest {
2247 pub study_id: StudyId,
2248 pub dataset_asset_id: Option<AssetId>,
2249 pub dataset_name: NcName,
2250 pub dataset_version_id: Option<VersionId>,
2251 pub inputs: std::collections::BTreeMap<String, VersionId>,
2252 pub views: std::collections::BTreeMap<String, String>,
2253 pub budgets: ahri_tre_types::DisclosureBudgetOverrides,
2254 pub sql: String,
2255 pub description: Option<String>,
2256 pub agent_instructions: Option<String>,
2257 pub version_note: Option<String>,
2258 pub transformation: NewTransformationRecord,
2259}
2260
2261#[derive(Debug, Clone, Serialize, Deserialize)]
2262pub struct OfflineRedcapIngestRequest {
2263 #[serde(default)]
2264 pub no_register_dictionary: bool,
2265 pub classification: ahri_tre_types::IngestClassification,
2266 pub study_id: Option<StudyId>,
2267 pub domain_id: Option<DomainId>,
2268 pub domain_name: Option<NcName>,
2269 pub study_name: Option<NcName>,
2270 pub project_info_path: String,
2271 pub metadata_path: String,
2272 pub records_eav_path: String,
2273 #[serde(default)]
2274 pub forms: Vec<String>,
2275 #[serde(default)]
2276 pub skip_forms: Vec<String>,
2277 pub dataset_prefix: Option<NcName>,
2278 pub description: Option<String>,
2279 pub agent_instructions: Option<String>,
2280 pub version_note: Option<String>,
2281 pub ingest_transformation: NewTransformationRecord,
2282 pub transform_transformation: NewTransformationRecord,
2283 pub force_metadata_updates: bool,
2284 pub compress: bool,
2285 pub encrypt: Option<bool>,
2286}
2287
2288#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2289pub struct RedcapIngestResult {
2290 pub form_outcomes: Vec<ahri_tre_protocol::ingest::RedcapFormOutcome>,
2291 pub study: StudyRecord,
2292 pub datafiles: Vec<IngestedFileAsset>,
2293 pub ingest_lineage: TransformationLineageRecord,
2294 pub datasets: Vec<DatasetMaterialization>,
2295 pub warnings: Vec<String>,
2296}
2297
2298#[derive(Debug, Clone, Serialize, Deserialize)]
2299pub struct AnalyzeSqlSourceRequest {
2300 pub sql: String,
2301}
2302
2303#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2304pub struct SqlSourceAnalysis {
2305 pub source_kind: String,
2306 pub source_description: String,
2307 pub columns: Vec<SqlSourceColumnAnalysis>,
2308 pub warnings: Vec<String>,
2309}
2310
2311#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2312pub struct SqlSourceColumnAnalysis {
2313 pub name: String,
2314 pub sql_type: String,
2315 pub value_type_id: ahri_tre_types::ValueTypeId,
2316 pub value_type: String,
2317 pub description: Option<String>,
2318 pub source_table: Option<String>,
2319 pub source_column: Option<String>,
2320 pub vocabulary: Option<SqlSourceVocabularyAnalysis>,
2321}
2322
2323#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2324pub struct SqlSourceVocabularyAnalysis {
2325 pub name: String,
2326 pub description: Option<String>,
2327 pub items: Vec<SqlSourceVocabularyItemAnalysis>,
2328}
2329
2330#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2331pub struct SqlSourceVocabularyItemAnalysis {
2332 pub value: i32,
2333 pub code: String,
2334 pub description: Option<String>,
2335}
2336
2337#[derive(Debug, Clone)]
2338pub struct OpenDuckDbSourceRequest {
2339 pub path: PathBuf,
2340}
2341
2342#[derive(Debug, Clone)]
2343pub struct OpenSqliteSourceRequest {
2344 pub path: PathBuf,
2345}
2346
2347#[derive(Debug, Clone)]
2348pub struct OpenPostgresSourceRequest {
2349 pub config: ahri_tre_pgmeta::DirectPostgresConnectConfig,
2350 pub schema: Option<String>,
2351}
2352
2353#[derive(Debug, Clone)]
2354pub struct OpenMsSqlSourceRequest {
2355 pub connection_string: String,
2356 pub safe_description: Option<String>,
2357 pub schema: Option<String>,
2358}
2359
2360#[derive(Debug, Clone, Serialize, Deserialize)]
2361pub struct RegisterDomainRequest {
2362 pub domain: DomainRecord,
2363}
2364
2365#[derive(Debug, Clone, Serialize, Deserialize)]
2366pub struct RegisterNewDomainRequest {
2367 pub domain: NewDomainRecord,
2368}
2369
2370#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2371pub struct ListDomainsRequest {}
2372
2373#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2375pub struct DomainListResult {
2376 pub domains: Vec<DomainRecord>,
2377}
2378
2379#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2380pub enum DomainSelector {
2381 Id { domain_id: DomainId },
2382 Name { name: String },
2383}
2384
2385impl From<String> for DomainSelector {
2386 fn from(name: String) -> Self {
2387 Self::Name { name }
2388 }
2389}
2390
2391impl From<&str> for DomainSelector {
2392 fn from(name: &str) -> Self {
2393 Self::Name {
2394 name: name.to_string(),
2395 }
2396 }
2397}
2398
2399impl From<&String> for DomainSelector {
2400 fn from(name: &String) -> Self {
2401 Self::from(name.as_str())
2402 }
2403}
2404
2405impl From<DomainId> for DomainSelector {
2406 fn from(domain_id: DomainId) -> Self {
2407 Self::Id { domain_id }
2408 }
2409}
2410
2411#[derive(Debug, Clone, Serialize, Deserialize)]
2412pub struct GetDomainRequest {
2413 pub domain: DomainSelector,
2414}
2415
2416#[derive(Debug, Clone, Serialize, Deserialize)]
2417pub struct AddDomainRequest {
2418 pub name: String,
2419 pub description: Option<String>,
2420 pub uri: Option<String>,
2421}
2422
2423#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2425pub struct DomainAddResult {
2426 pub domain: DomainRecord,
2427}
2428
2429#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2430pub struct ListStudiesRequest {}
2431
2432#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2434pub struct StudyListResult {
2435 pub studies: Vec<StudyRegistration>,
2436}
2437
2438#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2439pub struct SearchStudiesRequest {
2440 pub kind: PredicateSetKind,
2441 pub predicates: Vec<StudySearchPredicate>,
2442 pub limit: u16,
2443 pub after: Option<StudySearchCursorAnchor>,
2444}
2445
2446#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2447pub struct StudySearchEntry {
2448 pub study: StudyRecord,
2449 pub domains: Vec<DomainRecord>,
2450 pub tags: Vec<TagRecord>,
2451}
2452
2453#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2454pub struct StudySearchResult {
2455 pub studies: Vec<StudySearchEntry>,
2456 pub next_cursor: Option<StudySearchCursorAnchor>,
2457}
2458
2459#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2460pub struct SearchDatasetsRequest {
2461 pub kind: PredicateSetKind,
2462 pub predicates: Vec<DatasetSearchPredicate>,
2463 pub limit: u16,
2464 pub after: Option<DatasetSearchCursorAnchor>,
2465}
2466
2467#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2468pub struct DatasetSearchEntry {
2469 pub study: StudyRecord,
2470 pub asset: AssetRecord,
2471 pub latest_version: AssetVersionRecord,
2472 pub variable_count: Option<u64>,
2473 pub tags: Vec<TagRecord>,
2474}
2475
2476#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2477pub struct DatasetSearchResult {
2478 pub datasets: Vec<DatasetSearchEntry>,
2479 pub next_cursor: Option<DatasetSearchCursorAnchor>,
2480}
2481
2482#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2483pub struct SearchDataFilesRequest {
2484 pub kind: PredicateSetKind,
2485 pub predicates: Vec<DataFileSearchPredicate>,
2486 pub limit: u16,
2487 pub after: Option<DataFileSearchCursorAnchor>,
2488}
2489
2490#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2491pub struct DataFileSearchEntry {
2492 pub study: StudyRecord,
2493 pub asset: AssetRecord,
2494 pub latest_version: AssetVersionRecord,
2495 pub datafile: DataFileRecord,
2496 pub tags: Vec<TagRecord>,
2497}
2498
2499#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2500pub struct DataFileSearchResult {
2501 pub datafiles: Vec<DataFileSearchEntry>,
2502 pub next_cursor: Option<DataFileSearchCursorAnchor>,
2503}
2504
2505#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2506pub enum StudySelector {
2507 Id {
2508 study_id: StudyId,
2509 },
2510 Name {
2511 domain: Option<DomainSelector>,
2512 name: String,
2513 },
2514}
2515
2516impl From<String> for StudySelector {
2517 fn from(name: String) -> Self {
2518 Self::Name { domain: None, name }
2519 }
2520}
2521
2522impl From<&str> for StudySelector {
2523 fn from(name: &str) -> Self {
2524 Self::Name {
2525 domain: None,
2526 name: name.to_string(),
2527 }
2528 }
2529}
2530
2531impl From<&String> for StudySelector {
2532 fn from(name: &String) -> Self {
2533 Self::from(name.as_str())
2534 }
2535}
2536
2537impl From<StudyId> for StudySelector {
2538 fn from(study_id: StudyId) -> Self {
2539 Self::Id { study_id }
2540 }
2541}
2542
2543#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2544pub enum VariableSelector {
2545 Id {
2546 variable_id: VariableId,
2547 },
2548 Name {
2549 domain: DomainSelector,
2550 name: String,
2551 },
2552}
2553
2554impl From<(String, String)> for VariableSelector {
2555 fn from((domain, name): (String, String)) -> Self {
2556 Self::Name {
2557 domain: domain.into(),
2558 name,
2559 }
2560 }
2561}
2562
2563impl From<(&str, &str)> for VariableSelector {
2564 fn from((domain, name): (&str, &str)) -> Self {
2565 Self::Name {
2566 domain: domain.into(),
2567 name: name.to_string(),
2568 }
2569 }
2570}
2571
2572impl From<VariableId> for VariableSelector {
2573 fn from(variable_id: VariableId) -> Self {
2574 Self::Id { variable_id }
2575 }
2576}
2577
2578#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2579pub enum VocabularySelector {
2580 Id {
2581 vocabulary_id: VocabularyId,
2582 },
2583 Name {
2584 domain: DomainSelector,
2585 name: String,
2586 },
2587}
2588
2589impl From<(String, String)> for VocabularySelector {
2590 fn from((domain, name): (String, String)) -> Self {
2591 Self::Name {
2592 domain: domain.into(),
2593 name,
2594 }
2595 }
2596}
2597
2598impl From<(&str, &str)> for VocabularySelector {
2599 fn from((domain, name): (&str, &str)) -> Self {
2600 Self::Name {
2601 domain: domain.into(),
2602 name: name.to_string(),
2603 }
2604 }
2605}
2606
2607impl From<VocabularyId> for VocabularySelector {
2608 fn from(vocabulary_id: VocabularyId) -> Self {
2609 Self::Id { vocabulary_id }
2610 }
2611}
2612
2613#[derive(Debug, Clone, Serialize, Deserialize)]
2614pub struct GetStudyRequest {
2615 pub study: StudySelector,
2616}
2617
2618#[derive(Debug, Clone, Serialize, Deserialize)]
2619pub struct AddStudyRequest {
2620 pub name: String,
2621 pub external_id: String,
2622 pub study_type: String,
2623 pub domain: DomainSelector,
2624 pub description: Option<String>,
2625}
2626
2627#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2629pub struct StudyAddResult {
2630 pub registration: StudyRegistration,
2631}
2632
2633#[derive(Debug, Clone, Serialize, Deserialize)]
2634pub struct AddStudyDomainRequest {
2635 pub study: StudySelector,
2636 pub domain: DomainSelector,
2637}
2638
2639#[derive(Debug, Clone, Serialize, Deserialize)]
2640pub struct RegisterStudyRequest {
2641 pub study: StudyRecord,
2642 pub domain_ids: Vec<DomainId>,
2643}
2644
2645#[derive(Debug, Clone, Serialize, Deserialize)]
2646pub struct RegisterNewStudyRequest {
2647 pub study: NewStudyRecord,
2648 pub domain_ids: Vec<DomainId>,
2649}
2650
2651#[derive(Debug, Clone, Serialize, Deserialize)]
2652pub struct RegisterDomainStudyRequest {
2653 pub domain: DomainRecord,
2654 pub study: StudyRecord,
2655}
2656
2657#[derive(Debug, Clone, Serialize, Deserialize)]
2658pub struct GetStudyRegistrationRequest {
2659 pub study_id: Option<StudyId>,
2660 pub study_name: Option<NcName>,
2661}
2662
2663#[derive(Debug, Clone, Serialize, Deserialize)]
2664pub struct ListStudyAccessGrantsRequest {
2665 pub study_id: StudyId,
2666}
2667
2668#[derive(Debug, Clone, Serialize, Deserialize)]
2669pub struct GrantStudyAccessRequest {
2670 pub study_id: StudyId,
2671 pub target_user_id: String,
2672}
2673
2674#[derive(Debug, Clone, Serialize, Deserialize)]
2675pub struct RevokeStudyAccessRequest {
2676 pub study_id: StudyId,
2677 pub target_user_id: String,
2678}
2679
2680#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2681pub struct StudyAccessGrant {
2682 pub grant: StudyAccessGrantRecord,
2683}
2684
2685#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2686pub struct StudyAccessRevocation {
2687 pub study_id: StudyId,
2688 pub target_user_id: String,
2689}
2690
2691#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2692pub struct StudyAccessGrantList {
2693 pub study_id: StudyId,
2694 pub grants: Vec<StudyAccessGrantRecord>,
2695}
2696
2697#[derive(Debug, Clone, Serialize, Deserialize)]
2698pub struct ListStudyCustodiansRequest {
2699 pub study_id: StudyId,
2700}
2701
2702#[derive(Debug, Clone, Serialize, Deserialize)]
2703pub struct AddDelegateCustodianRequest {
2704 pub study_id: StudyId,
2705 pub target_user_id: String,
2706}
2707
2708#[derive(Debug, Clone, Serialize, Deserialize)]
2709pub struct TransferPrimaryCustodianshipRequest {
2710 pub study_id: StudyId,
2711 pub target_user_id: String,
2712}
2713
2714#[derive(Debug, Clone, Serialize, Deserialize)]
2715pub struct RemoveDelegateCustodianRequest {
2716 pub study_id: StudyId,
2717 pub target_user_id: String,
2718}
2719
2720#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2721pub struct StudyCustodian {
2722 pub custodian: StudyCustodianLinkRecord,
2723}
2724
2725#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2726pub struct StudyPrimaryCustodianshipTransfer {
2727 pub primary_custodian: StudyCustodianLinkRecord,
2728}
2729
2730#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2731pub struct StudyDelegateCustodianRemoval {
2732 pub study_id: StudyId,
2733 pub target_user_id: String,
2734}
2735
2736#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2737pub struct StudyCustodianList {
2738 pub study_id: StudyId,
2739 pub custodians: Vec<StudyCustodianLinkRecord>,
2740}
2741
2742#[derive(Debug, Clone, Serialize, Deserialize)]
2743pub struct ListStudyDuoRestrictionsRequest {
2744 pub study_id: StudyId,
2745}
2746
2747#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2748pub struct StudyDuoRestrictionInput {
2749 pub code: Option<String>,
2750 pub duo_id: Option<String>,
2751 pub qualifier_ontology_namespace: Option<String>,
2752 pub qualifier_ontology_id: Option<String>,
2753 pub qualifier_text: Option<String>,
2754 pub qualifier_date: Option<NaiveDate>,
2755 pub qualifier_integer: Option<i32>,
2756}
2757
2758impl StudyDuoRestrictionInput {
2759 pub fn into_new_restriction(
2760 self,
2761 study_id: StudyId,
2762 ) -> Result<NewStudyDuoRestrictionRecord, String> {
2763 let code = self
2764 .code
2765 .as_deref()
2766 .map(str::trim)
2767 .filter(|v| !v.is_empty());
2768 let duo_id = self
2769 .duo_id
2770 .as_deref()
2771 .map(str::trim)
2772 .filter(|v| !v.is_empty());
2773 let resolved_duo_id = match (code, duo_id) {
2774 (None, None) => return Err("DUO restriction requires code or duo_id".to_string()),
2775 (Some(_), Some(_)) => {
2776 return Err("DUO restriction accepts code or duo_id, not both".to_string());
2777 }
2778 (Some(value), None) | (None, Some(value)) => value.to_string(),
2779 };
2780
2781 Ok(NewStudyDuoRestrictionRecord {
2782 study_id,
2783 duo_id: resolved_duo_id,
2784 qualifier_ontology_namespace: self.qualifier_ontology_namespace,
2785 qualifier_ontology_id: self.qualifier_ontology_id,
2786 qualifier_text: self.qualifier_text,
2787 qualifier_date: self.qualifier_date,
2788 qualifier_integer: self.qualifier_integer,
2789 })
2790 }
2791}
2792
2793#[derive(Debug, Clone, Serialize, Deserialize)]
2794pub struct ReplaceStudyDuoRestrictionsRequest {
2795 pub study_id: StudyId,
2796 pub restrictions: Vec<StudyDuoRestrictionInput>,
2797}
2798
2799#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2800pub struct AssetVersionDuoRestrictionInput {
2801 pub code: Option<String>,
2802 pub duo_id: Option<String>,
2803 pub qualifier_ontology_namespace: Option<String>,
2804 pub qualifier_ontology_id: Option<String>,
2805 pub qualifier_text: Option<String>,
2806 pub qualifier_date: Option<NaiveDate>,
2807 pub qualifier_integer: Option<i32>,
2808}
2809
2810impl AssetVersionDuoRestrictionInput {
2811 pub fn into_new_restriction(
2812 self,
2813 version_id: VersionId,
2814 ) -> Result<NewAssetVersionDuoRestrictionRecord, String> {
2815 let code = self
2816 .code
2817 .as_deref()
2818 .map(str::trim)
2819 .filter(|v| !v.is_empty());
2820 let duo_id = self
2821 .duo_id
2822 .as_deref()
2823 .map(str::trim)
2824 .filter(|v| !v.is_empty());
2825 let resolved_duo_id = match (code, duo_id) {
2826 (None, None) => return Err("DUO restriction requires code or duo_id".to_string()),
2827 (Some(_), Some(_)) => {
2828 return Err("DUO restriction accepts code or duo_id, not both".to_string());
2829 }
2830 (Some(value), None) | (None, Some(value)) => value.to_string(),
2831 };
2832
2833 Ok(NewAssetVersionDuoRestrictionRecord {
2834 version_id,
2835 duo_id: resolved_duo_id,
2836 qualifier_ontology_namespace: self.qualifier_ontology_namespace,
2837 qualifier_ontology_id: self.qualifier_ontology_id,
2838 qualifier_text: self.qualifier_text,
2839 qualifier_date: self.qualifier_date,
2840 qualifier_integer: self.qualifier_integer,
2841 })
2842 }
2843}
2844
2845#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2846pub struct StudyDuoRestrictionList {
2847 pub study_id: StudyId,
2848 pub restrictions: Vec<StudyDuoRestrictionRecord>,
2849}
2850
2851#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2852pub struct StudyDuoRestrictionReplacement {
2853 pub study_id: StudyId,
2854 pub restrictions: Vec<StudyDuoRestrictionRecord>,
2855}
2856
2857#[derive(Debug, Clone, Serialize, Deserialize)]
2858pub struct ListAssetVersionDuoRestrictionsRequest {
2859 pub version_id: VersionId,
2860}
2861
2862#[derive(Debug, Clone, Serialize, Deserialize)]
2863pub struct ListEffectiveAssetVersionDuoRestrictionsRequest {
2864 pub study_id: StudyId,
2865 pub version_id: VersionId,
2866}
2867
2868#[derive(Debug, Clone, Serialize, Deserialize)]
2869pub struct ReplaceAssetVersionDuoRestrictionsRequest {
2870 pub version_id: VersionId,
2871 pub restrictions: Vec<AssetVersionDuoRestrictionInput>,
2872}
2873
2874#[derive(Debug, Clone, Serialize, Deserialize)]
2875pub struct ClearAssetVersionDuoRestrictionsRequest {
2876 pub version_id: VersionId,
2877}
2878
2879#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2880pub struct AssetVersionDuoRestrictionList {
2881 pub version_id: VersionId,
2882 pub restrictions: Vec<AssetVersionDuoRestrictionRecord>,
2883}
2884
2885#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2886#[serde(rename_all = "kebab-case")]
2887pub enum AssetDuoRestrictionSource {
2888 AssetVersion,
2889 StudyDefault,
2890}
2891
2892#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2893pub struct EffectiveAssetVersionDuoRestriction {
2894 pub source: AssetDuoRestrictionSource,
2895 pub duo_id: String,
2896 pub qualifier_ontology_namespace: Option<String>,
2897 pub qualifier_ontology_id: Option<String>,
2898 pub qualifier_text: Option<String>,
2899 pub qualifier_date: Option<NaiveDate>,
2900 pub qualifier_integer: Option<i32>,
2901}
2902
2903#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2904pub struct EffectiveAssetVersionDuoRestrictionList {
2905 pub study_id: StudyId,
2906 pub version_id: VersionId,
2907 pub restrictions: Vec<EffectiveAssetVersionDuoRestriction>,
2908}
2909
2910#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2911pub struct AssetVersionDuoRestrictionReplacement {
2912 pub version_id: VersionId,
2913 pub restrictions: Vec<AssetVersionDuoRestrictionRecord>,
2914}
2915
2916#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2917pub struct AssetVersionDuoRestrictionClear {
2918 pub version_id: VersionId,
2919 pub restrictions: Vec<AssetVersionDuoRestrictionRecord>,
2920}
2921
2922#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2923pub struct StudyRegistration {
2924 pub study: StudyRecord,
2925 pub domains: Vec<DomainRecord>,
2926 pub tags: Vec<TagRecord>,
2927}
2928
2929#[derive(Debug, Clone, Serialize, Deserialize)]
2930pub struct CreateAssetRequest {
2931 pub asset: AssetRecord,
2932}
2933
2934#[derive(Debug, Clone, Serialize, Deserialize)]
2935pub struct CreateNewAssetRequest {
2936 pub asset: NewAssetRecord,
2937}
2938
2939#[derive(Debug, Clone, Serialize, Deserialize)]
2940pub struct CreateAssetVersionRequest {
2941 pub classification: ahri_tre_types::IngestClassification,
2942 pub version: AssetVersionRecord,
2943}
2944
2945#[derive(Debug, Clone, Serialize, Deserialize)]
2946pub struct CreateNewAssetVersionRequest {
2947 pub version: NewAssetVersionRecord,
2948}
2949
2950#[derive(Debug, Clone, Serialize, Deserialize)]
2951pub struct GetAssetRequest {
2952 pub asset_id: Option<AssetId>,
2953 pub study_id: Option<StudyId>,
2954 pub asset_name: Option<NcName>,
2955}
2956
2957#[derive(Debug, Clone, Serialize, Deserialize)]
2958pub struct ListStudyAssetsRequest {
2959 pub study_id: StudyId,
2960}
2961
2962#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2963pub struct AssetVersionCatalog {
2964 pub asset: AssetRecord,
2965 pub versions: Vec<AssetVersionRecord>,
2966 pub latest_version: Option<AssetVersionRecord>,
2967}
2968
2969#[derive(Debug, Clone, Serialize, Deserialize)]
2970pub struct RecordTransformationRequest {
2971 pub transformation: NewTransformationRecord,
2972 pub input_version_ids: Vec<VersionId>,
2973 pub output_version_ids: Vec<VersionId>,
2974}
2975
2976#[derive(Debug, Clone, Serialize, Deserialize)]
2977pub struct TransformAssetsRequest {
2978 pub transformation: NewTransformationRecord,
2979 pub input_version_ids: Vec<VersionId>,
2980 pub output_version_ids: Vec<VersionId>,
2981}
2982
2983#[derive(Debug, Clone, Serialize, Deserialize)]
2984pub struct RecordExportRequest {
2985 pub transformation: NewTransformationRecord,
2986 pub input_version_ids: Vec<VersionId>,
2987}