Skip to main content

context69_contracts/
documents.rs

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}