1use chrono::{DateTime, Utc};
2use schemars::JsonSchema;
3use serde::{Deserialize, Serialize};
4use serde_json::Value;
5use utoipa::{IntoParams, ToSchema};
6use uuid::Uuid;
7
8use crate::DocumentResponse;
9use crate::Pagination;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, ToSchema, JsonSchema)]
12#[serde(rename_all = "snake_case")]
13pub enum MetadataDataType {
14 Keyword,
15 Integer,
16 Float,
17 Boolean,
18 Datetime,
19}
20
21#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, ToSchema, JsonSchema)]
22#[serde(rename_all = "snake_case")]
23pub enum MetadataValueKind {
24 Scalar,
25 Array,
26}
27
28#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, ToSchema, JsonSchema)]
29#[serde(rename_all = "snake_case")]
30pub enum MetadataIndexStatus {
31 Building,
32 Ready,
33 Failed,
34 Deleting,
35}
36
37#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, JsonSchema)]
38pub struct CreateMetadataIndexRequest {
39 pub path: String,
40 pub data_type: MetadataDataType,
41 pub value_kind: MetadataValueKind,
42 #[serde(default)]
43 pub sortable: bool,
44}
45
46#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, JsonSchema)]
47pub struct UpdateMetadataIndexRequest {
48 pub data_type: MetadataDataType,
49 pub value_kind: MetadataValueKind,
50 #[serde(default)]
51 pub sortable: bool,
52}
53
54#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, JsonSchema)]
55pub struct MetadataIndexResponse {
56 pub index_id: Uuid,
57 pub group_path: String,
58 pub source_key: String,
59 pub path: String,
60 pub data_type: MetadataDataType,
61 pub value_kind: MetadataValueKind,
62 pub sortable: bool,
63 pub status: MetadataIndexStatus,
64 pub processed_documents: i64,
65 pub total_documents: i64,
66 pub error_message: Option<String>,
67 pub created_at: DateTime<Utc>,
68 pub updated_at: DateTime<Utc>,
69}
70
71#[derive(Debug, Clone, Deserialize, IntoParams, ToSchema)]
72#[into_params(parameter_in = Query)]
73pub struct MetadataIndexPageQuery {
74 pub source_key: String,
75 #[serde(default = "default_page")]
76 pub page: u32,
77 #[serde(default = "default_page_size")]
78 pub page_size: u32,
79}
80
81#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
82pub struct MetadataIndexPageResponse {
83 pub items: Vec<MetadataIndexResponse>,
84 pub pagination: Pagination,
85}
86
87const fn default_page() -> u32 {
88 1
89}
90
91const fn default_page_size() -> u32 {
92 50
93}
94
95#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, ToSchema, JsonSchema)]
96#[serde(rename_all = "snake_case")]
97pub enum MetadataFilterOperator {
98 Eq,
99 In,
100 Range,
101 Exists,
102 Contains,
103}
104
105#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, JsonSchema)]
106pub struct MetadataFilter {
107 pub path: String,
108 pub operator: MetadataFilterOperator,
109 #[serde(default, skip_serializing_if = "Option::is_none")]
110 #[schema(value_type = Option<Object>)]
111 pub value: Option<Value>,
112 #[serde(default, skip_serializing_if = "Option::is_none")]
113 #[schema(value_type = Option<Object>)]
114 pub min: Option<Value>,
115 #[serde(default, skip_serializing_if = "Option::is_none")]
116 #[schema(value_type = Option<Object>)]
117 pub max: Option<Value>,
118}
119
120#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, ToSchema, JsonSchema)]
121#[serde(rename_all = "snake_case")]
122pub enum SortOrder {
123 Asc,
124 Desc,
125}
126
127#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, ToSchema, JsonSchema)]
128#[serde(rename_all = "snake_case")]
129pub enum DocumentSortField {
130 PublishedAt,
131 UpdatedAt,
132 Metadata(String),
133}
134
135#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, JsonSchema)]
136pub struct DocumentSort {
137 pub field: DocumentSortField,
138 pub order: SortOrder,
139}
140
141#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, JsonSchema)]
142pub struct DocumentQueryRequest {
143 #[serde(default, skip_serializing_if = "Option::is_none")]
144 pub locale: Option<String>,
145 #[serde(default)]
146 pub source_key: Option<String>,
147 #[serde(default)]
148 pub published_after: Option<DateTime<Utc>>,
149 #[serde(default)]
150 pub published_before: Option<DateTime<Utc>>,
151 #[serde(default)]
152 pub metadata_filters: Vec<MetadataFilter>,
153 #[serde(default)]
154 pub sort: Vec<DocumentSort>,
155 #[serde(default = "default_limit")]
156 pub limit: usize,
157 #[serde(default)]
158 pub cursor: Option<String>,
159}
160
161fn default_limit() -> usize {
162 50
163}
164
165#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, JsonSchema)]
166pub struct DocumentQueryResponse {
167 pub documents: Vec<DocumentResponse>,
168 pub next_cursor: Option<String>,
169}
170
171#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, JsonSchema)]
172pub struct DocumentKey {
173 pub source_key: String,
174 pub external_id: String,
175}
176
177#[derive(Debug, Clone, Serialize, Deserialize, IntoParams, ToSchema)]
178pub struct DocumentLookupQuery {
179 pub source_key: String,
180 pub external_id: String,
181 #[serde(default, skip_serializing_if = "Option::is_none")]
182 pub locale: Option<String>,
183}
184
185#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, JsonSchema)]
186pub struct BatchGetDocumentsRequest {
187 pub keys: Vec<DocumentKey>,
188 #[serde(default, skip_serializing_if = "Option::is_none")]
189 pub locale: Option<String>,
190}
191
192#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, JsonSchema)]
193pub struct BatchDocumentItem {
194 pub key: DocumentKey,
195 pub document: Option<DocumentResponse>,
196}
197
198#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, JsonSchema)]
199pub struct BatchGetDocumentsResponse {
200 pub items: Vec<BatchDocumentItem>,
201}