Skip to main content

ahri_tre_protocol/
dictionary_discovery.rs

1use crate::{
2    domain::DomainSummary,
3    refs::{DataFileRef, DatasetRef, DomainRef, StudyRef, TagSummary, VariableRef, VocabularyRef},
4    study::BrowserContentSummaryPolicy,
5};
6use serde::{Deserialize, Serialize};
7
8pub const BROWSER_DICTIONARY_ERROR_TARGET_DATASTORE: &str = "browser_dictionary_datastore";
9/// Stable target for a selected datastore whose metadata authority is unavailable.
10pub const BROWSER_DICTIONARY_ERROR_TARGET_DATASTORE_UNAVAILABLE: &str =
11    "browser_dictionary_datastore_unavailable";
12pub const BROWSER_DICTIONARY_ERROR_TARGET_STUDY: &str = "browser_dictionary_study";
13pub const BROWSER_DICTIONARY_ERROR_TARGET_RESOURCE: &str = "browser_dictionary_resource";
14pub const BROWSER_DICTIONARY_ERROR_TARGET_SERVICE: &str = "browser_dictionary_service";
15
16#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
17pub struct BrowserDictionaryDiscoveryRequest {
18    pub datastore_id: crate::PublicUuid,
19    pub study: StudyRef,
20    pub resource: BrowserDictionaryDiscoveryResourceRef,
21}
22
23#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
24#[serde(tag = "kind", rename_all = "snake_case")]
25pub enum BrowserDictionaryDiscoveryResourceRef {
26    Dataset {
27        dataset: DatasetRef,
28    },
29    /// Legacy request-only selector retained so v1 callers receive the
30    /// documented Datafile dictionary transition response.
31    DataFile {
32        datafile: DataFileRef,
33    },
34}
35
36/// The owning Dataset version returned by successful dictionary discovery.
37///
38/// This response type deliberately has no Datafile variant. The legacy
39/// request selector remains decodable only for the compatible HTTP transition.
40#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
41#[serde(tag = "kind", rename_all = "snake_case")]
42pub enum BrowserDictionaryDiscoveryDatasetRef {
43    Dataset { dataset: DatasetRef },
44}
45
46#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
47pub struct BrowserDictionaryDiscoveryEmptyState {
48    pub code: String,
49    pub message: String,
50}
51
52#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
53pub struct BrowserVocabularyItemDiscoveryRecord {
54    pub item_id: crate::refs::VocabularyItemRef,
55    pub vocabulary: VocabularyRef,
56    pub value: i32,
57    pub code: String,
58    #[serde(default, skip_serializing_if = "Option::is_none")]
59    pub description: Option<String>,
60}
61
62#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
63pub struct BrowserVocabularyDiscoveryRecord {
64    pub vocabulary: VocabularyRef,
65    pub domain: DomainRef,
66    pub name: String,
67    #[serde(default, skip_serializing_if = "Option::is_none")]
68    pub description: Option<String>,
69    #[serde(default)]
70    pub items: Vec<BrowserVocabularyItemDiscoveryRecord>,
71}
72
73#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
74pub struct BrowserVocabularyMappingDiscoveryRecord {
75    pub mapping_id: crate::refs::VocabularyMappingRef,
76    pub from_vocabulary: VocabularyRef,
77    pub from_item_id: crate::refs::VocabularyItemRef,
78    pub from_code: String,
79    pub from_value: i32,
80    pub to_vocabulary: VocabularyRef,
81    pub to_item_id: crate::refs::VocabularyItemRef,
82    pub to_code: String,
83    pub to_value: i32,
84}
85
86#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
87pub struct BrowserDictionaryVariableDiscoveryRecord {
88    pub variable: VariableRef,
89    pub domain: DomainRef,
90    pub name: String,
91    pub value_type: String,
92    pub value_type_id: crate::refs::ValueTypeRef,
93    #[serde(default, skip_serializing_if = "Option::is_none")]
94    pub value_format: Option<String>,
95    pub row_role: String,
96    pub key_role: String,
97    #[serde(default, skip_serializing_if = "Option::is_none")]
98    pub description: Option<String>,
99    #[serde(default, skip_serializing_if = "Option::is_none")]
100    pub note: Option<String>,
101    #[serde(default, skip_serializing_if = "Option::is_none")]
102    pub ontology_namespace: Option<String>,
103    #[serde(default, skip_serializing_if = "Option::is_none")]
104    pub ontology_class: Option<String>,
105    #[serde(default, skip_serializing_if = "Option::is_none")]
106    pub vocabulary: Option<BrowserVocabularyDiscoveryRecord>,
107    #[serde(default)]
108    pub vocabulary_mappings: Vec<BrowserVocabularyMappingDiscoveryRecord>,
109    #[serde(default)]
110    pub tags: Vec<TagSummary>,
111}
112
113/// Browser dictionary discovery is a metadata-only variable projection.
114///
115/// It intentionally excludes dataset rows, datafile bytes, previews,
116/// Content-derived summaries, storage paths, raw SQL, credentials, diagnostics,
117/// and runtime handles.
118#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
119pub struct BrowserDictionaryDiscoveryResponse {
120    pub authority: String,
121    pub datastore_id: crate::PublicUuid,
122    pub study: StudyRef,
123    pub resource: BrowserDictionaryDiscoveryDatasetRef,
124    #[serde(default)]
125    pub domains: Vec<DomainSummary>,
126    #[serde(default)]
127    pub variables: Vec<BrowserDictionaryVariableDiscoveryRecord>,
128    #[serde(default, skip_serializing_if = "Option::is_none")]
129    pub empty_state: Option<BrowserDictionaryDiscoveryEmptyState>,
130    pub content_derived_summaries: BrowserContentSummaryPolicy,
131}