1use std::sync::Arc;
2
3use haste_fhir_client::{request::SearchRequest, url::Parameter};
4use haste_fhir_model::r4::generated::resources::{Resource, ResourceType, SearchParameter};
5use haste_fhir_operation_error::OperationOutcomeError;
6use haste_jwt::{ProjectId, ResourceId, TenantId, VersionId};
7use haste_repository::types::{FHIRMethod, SupportedFHIRVersions};
8use serde::Deserialize;
9
10pub mod config;
11pub mod elastic_search;
12pub mod indexing_conversion;
13pub mod memory;
14pub mod pg_search;
15pub mod project_parameters;
16mod query;
17pub mod search_parameter_cardinality;
18mod search_ranges;
19
20#[cfg(test)]
21mod proptests;
22
23pub const DEFAULT_COUNT: u64 = 50;
25
26pub const MAX_COUNT: u64 = 10_000;
29
30#[derive(Clone)]
31pub struct IndexResource {
32 pub id: ResourceId,
33 pub version_id: VersionId,
34
35 pub tenant: TenantId,
36 pub project: ProjectId,
37
38 pub fhir_method: FHIRMethod,
39 pub resource_type: ResourceType,
40 pub resource: Resource,
41
42 pub sequence: i64,
46}
47
48#[derive(Deserialize, Debug)]
49pub struct SearchEntry {
50 pub id: ResourceId,
51 pub resource_type: ResourceType,
52 pub version_id: VersionId,
53 pub project: ProjectId,
54}
55
56pub struct SearchReturn {
57 pub total: Option<i64>,
58 pub entries: Vec<SearchEntry>,
59}
60
61#[derive(Debug, Clone)]
66pub struct AnyOf(pub Vec<Parameter>);
67
68#[derive(Debug, Default)]
69pub struct SearchOptions {
70 pub count_limit: Option<u64>,
71 pub any_of: Option<AnyOf>,
72}
73
74#[derive(Clone, Debug)]
75pub enum ParameterLevel {
76 Project,
77 System,
78}
79
80#[derive(Clone, Debug)]
81pub struct ResolvedParameter {
82 #[allow(dead_code)]
83 pub level: ParameterLevel,
84 pub search_parameter: Arc<SearchParameter>,
85}
86impl ResolvedParameter {
87 pub fn new(level: ParameterLevel, search_parameter: Arc<SearchParameter>) -> Self {
88 ResolvedParameter {
89 level,
90 search_parameter,
91 }
92 }
93}
94
95pub trait SearchParameterResolve: Send + Sync {
96 fn by_resource_type(
98 &self,
99 tenant: &TenantId,
100 project: &ProjectId,
101 resource_type: &ResourceType,
102 ) -> impl Future<Output = Result<Vec<ResolvedParameter>, OperationOutcomeError>> + Send;
103 fn by_name(
105 &self,
106 tenant: &TenantId,
107 project: &ProjectId,
108 resource_type: Option<&ResourceType>,
109 code: &str,
110 ) -> impl Future<Output = Result<Option<ResolvedParameter>, OperationOutcomeError>> + Send;
111 fn all(
113 &self,
114 tenant: &TenantId,
115 project: &ProjectId,
116 ) -> impl Future<Output = Result<Vec<ResolvedParameter>, OperationOutcomeError>> + Send;
117 fn invalidate_project(
120 &self,
121 _tenant: &TenantId,
122 _project: &ProjectId,
123 ) -> impl Future<Output = ()> + Send {
124 std::future::ready(())
125 }
126}
127
128pub struct IndexFailure {
129 pub resource: IndexResource,
130 pub error: OperationOutcomeError,
131}
132
133pub struct IndexOutcome {
134 pub succeeded: usize,
135 pub failed: Vec<IndexFailure>,
136}
137
138pub trait SearchEngine: Send + Sync {
139 fn search(
140 &self,
141 fhir_version: &SupportedFHIRVersions,
142 tenant: &TenantId,
143 projects: &ProjectId,
144 search_request: &SearchRequest,
145 options: Option<SearchOptions>,
146 ) -> impl Future<Output = Result<SearchReturn, OperationOutcomeError>> + Send;
147
148 fn index(
149 &self,
150 fhir_version: SupportedFHIRVersions,
151 resource: Vec<IndexResource>,
152 ) -> impl Future<Output = Result<IndexOutcome, OperationOutcomeError>> + Send;
153
154 fn migrate(
155 &self,
156 fhir_version: &SupportedFHIRVersions,
157 ) -> impl Future<Output = Result<(), haste_fhir_operation_error::OperationOutcomeError>> + Send;
158}