Skip to main content

cedros_data/
models.rs

1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3use serde_json::Value;
4
5#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
6#[serde(rename_all = "lowercase")]
7pub enum CollectionMode {
8    Jsonb,
9    Typed,
10}
11
12impl CollectionMode {
13    pub fn as_str(&self) -> &'static str {
14        match self {
15            Self::Jsonb => "jsonb",
16            Self::Typed => "typed",
17        }
18    }
19}
20
21#[derive(Debug, Clone, Serialize, Deserialize)]
22pub struct Site {
23    pub display_name: String,
24    pub metadata: Value,
25}
26
27#[derive(Debug, Clone, Serialize, Deserialize)]
28pub struct Collection {
29    pub collection_name: String,
30    pub mode: CollectionMode,
31    pub table_name: Option<String>,
32    pub strict_contract: Option<ContractSchema>,
33}
34
35#[derive(Debug, Clone, Serialize, Deserialize)]
36pub struct RegisterSiteRequest {
37    pub display_name: String,
38    #[serde(default = "default_object")]
39    pub metadata: Value,
40}
41
42#[derive(Debug, Clone, Serialize, Deserialize)]
43pub struct RegisterCollectionRequest {
44    pub collection_name: String,
45    pub mode: CollectionMode,
46    pub table_name: Option<String>,
47    pub strict_contract: Option<ContractSchema>,
48}
49
50#[derive(Debug, Clone, Serialize, Deserialize)]
51pub struct RegisterCustomSchemaRequest {
52    pub definition: CustomSchemaDefinition,
53}
54
55#[derive(Debug, Clone, Serialize, Deserialize)]
56pub struct UpsertEntryRequest {
57    pub collection_name: String,
58    pub entry_key: String,
59    pub payload: Value,
60}
61
62#[derive(Debug, Clone, Serialize, Deserialize)]
63pub struct QueryEntriesRequest {
64    pub collection_name: String,
65    #[serde(default)]
66    pub entry_keys: Vec<String>,
67    pub contains: Option<Value>,
68    #[serde(default = "default_limit")]
69    pub limit: i64,
70    #[serde(default)]
71    pub offset: i64,
72    #[serde(default)]
73    pub visitor_id: Option<String>,
74}
75
76#[derive(Debug, Clone, Serialize, Deserialize)]
77pub struct EntryRecord {
78    pub entry_key: String,
79    pub payload: Value,
80    pub updated_at: DateTime<Utc>,
81}
82
83#[derive(Debug, Clone, Serialize, Deserialize)]
84pub struct ExportSiteRequest;
85
86#[derive(Debug, Clone, Serialize, Deserialize)]
87pub struct ImportSiteRequest {
88    pub export: SiteExport,
89    #[serde(default)]
90    pub overwrite_contracts: bool,
91}
92
93#[derive(Debug, Clone, Serialize, Deserialize)]
94pub struct ImportResult {
95    pub collections_imported: usize,
96    pub entries_imported: usize,
97    pub contracts_imported: usize,
98}
99
100#[derive(Debug, Clone, Serialize, Deserialize)]
101pub struct VerifyContractRequest {
102    pub collection_name: String,
103    pub samples: Vec<Value>,
104}
105
106#[derive(Debug, Clone, Serialize, Deserialize)]
107pub struct SiteExport {
108    pub site: Site,
109    pub collections: Vec<Collection>,
110    pub custom_schema: Option<CustomSchemaDefinition>,
111    pub contracts: Vec<CollectionContractRecord>,
112    pub entries: Vec<CollectionEntriesExport>,
113}
114
115#[derive(Debug, Clone, Serialize, Deserialize)]
116pub struct CollectionEntriesExport {
117    pub collection_name: String,
118    pub entries: Vec<EntryRecord>,
119}
120
121#[derive(Debug, Clone, Serialize, Deserialize)]
122pub struct CollectionContractRecord {
123    pub collection_name: String,
124    pub version: i32,
125    pub contract: ContractSchema,
126}
127
128#[derive(Debug, Clone, Serialize, Deserialize)]
129pub struct CustomSchemaApplyReport {
130    pub applied: bool,
131    pub version: i32,
132    pub additive_changes: Vec<String>,
133    pub breaking_changes: Vec<String>,
134    pub generated_sql: Vec<String>,
135}
136
137#[derive(Debug, Clone, Serialize, Deserialize)]
138pub struct ContractVerificationReport {
139    pub passes: bool,
140    pub additive_changes: Vec<String>,
141    pub breaking_changes: Vec<String>,
142    pub stored_contract: Option<ContractSchema>,
143    pub incoming_contract: ContractSchema,
144}
145
146#[derive(Debug, Clone, Serialize, Deserialize)]
147pub struct DefaultPageTemplate {
148    pub key: String,
149    pub title: String,
150    pub route: String,
151    pub section: String,
152}
153
154impl DefaultPageTemplate {
155    pub fn new(key: &str, title: &str, route: &str, section: &str) -> Self {
156        Self {
157            key: key.to_string(),
158            title: title.to_string(),
159            route: route.to_string(),
160            section: section.to_string(),
161        }
162    }
163}
164
165#[derive(Debug, Clone, Serialize, Deserialize)]
166pub struct SiteBootstrapReport {
167    pub collections_seeded: usize,
168    pub entries_seeded: usize,
169}
170
171#[derive(Debug, Clone, Serialize, Deserialize)]
172pub struct ContractSchema {
173    pub fields: Vec<ContractField>,
174}
175
176#[derive(Debug, Clone, Serialize, Deserialize)]
177pub struct ContractField {
178    pub path: String,
179    pub required: bool,
180    pub types: Vec<ValueType>,
181}
182
183#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
184#[serde(rename_all = "lowercase")]
185pub enum ValueType {
186    String,
187    Number,
188    Boolean,
189    Object,
190    Array,
191    Null,
192}
193
194#[derive(Debug, Clone, Serialize, Deserialize)]
195pub struct CustomSchemaDefinition {
196    #[serde(default)]
197    pub types: Vec<CustomTypeDefinition>,
198    #[serde(default)]
199    pub tables: Vec<CustomTableDefinition>,
200}
201
202#[derive(Debug, Clone, Serialize, Deserialize)]
203#[serde(tag = "kind", rename_all = "snake_case")]
204pub enum CustomTypeDefinition {
205    Enum {
206        name: String,
207        values: Vec<String>,
208    },
209    Composite {
210        name: String,
211        fields: Vec<CustomColumnDefinition>,
212    },
213}
214
215#[derive(Debug, Clone, Serialize, Deserialize)]
216pub struct CustomTableDefinition {
217    pub name: String,
218    #[serde(default)]
219    pub columns: Vec<CustomColumnDefinition>,
220    #[serde(default)]
221    pub primary_key: Vec<String>,
222    #[serde(default)]
223    pub unique_constraints: Vec<UniqueConstraintDefinition>,
224    #[serde(default)]
225    pub foreign_keys: Vec<ForeignKeyDefinition>,
226    #[serde(default)]
227    pub indexes: Vec<IndexDefinition>,
228}
229
230#[derive(Debug, Clone, Serialize, Deserialize)]
231pub struct CustomColumnDefinition {
232    pub name: String,
233    pub data_type: String,
234    #[serde(default)]
235    pub nullable: bool,
236    pub default_sql: Option<String>,
237}
238
239#[derive(Debug, Clone, Serialize, Deserialize)]
240pub struct UniqueConstraintDefinition {
241    pub name: Option<String>,
242    pub columns: Vec<String>,
243}
244
245#[derive(Debug, Clone, Serialize, Deserialize)]
246pub struct ForeignKeyDefinition {
247    pub name: Option<String>,
248    pub columns: Vec<String>,
249    pub ref_table: String,
250    pub ref_columns: Vec<String>,
251    pub on_delete: Option<String>,
252}
253
254#[derive(Debug, Clone, Serialize, Deserialize)]
255pub struct IndexDefinition {
256    pub name: Option<String>,
257    pub columns: Vec<String>,
258    #[serde(default)]
259    pub unique: bool,
260}
261
262#[cfg(feature = "storage")]
263#[derive(Debug, Clone, Serialize, Deserialize)]
264pub struct Asset {
265    pub id: uuid::Uuid,
266    pub filename: String,
267    pub original_key: String,
268    pub content_type: String,
269    pub size_bytes: i64,
270    pub width: Option<i32>,
271    pub height: Option<i32>,
272    pub variants: Value,
273    pub alt_text: Option<String>,
274    pub metadata: Value,
275    pub created_at: DateTime<Utc>,
276    pub updated_at: DateTime<Utc>,
277}
278
279#[cfg(feature = "storage")]
280#[derive(Debug, Clone, Serialize, Deserialize)]
281pub struct AssetVariant {
282    pub suffix: String,
283    pub key: String,
284    pub url: String,
285    pub content_type: String,
286    pub width: u32,
287    pub height: u32,
288}
289
290#[cfg(feature = "storage")]
291#[derive(Debug, Clone, Serialize, Deserialize)]
292pub struct QueryAssetsParams {
293    #[serde(default = "default_assets_limit")]
294    pub limit: i64,
295    #[serde(default)]
296    pub offset: i64,
297}
298
299#[cfg(feature = "storage")]
300fn default_assets_limit() -> i64 {
301    50
302}
303
304#[cfg(feature = "storage")]
305#[derive(Debug, Clone, Serialize, Deserialize)]
306pub struct UpdateAssetRequest {
307    pub alt_text: Option<String>,
308    pub metadata: Option<Value>,
309}
310
311fn default_object() -> Value {
312    Value::Object(Default::default())
313}
314
315fn default_limit() -> i64 {
316    100
317}