docbox_database/models/
document_box.rs

1use crate::{DbExecutor, DbResult};
2use chrono::{DateTime, Utc};
3use serde::{Deserialize, Serialize};
4use sqlx::{postgres::PgQueryResult, prelude::FromRow};
5use utoipa::ToSchema;
6
7pub type DocumentBoxScopeRaw = String;
8
9#[derive(Debug, Clone, FromRow, Serialize, ToSchema)]
10pub struct DocumentBox {
11    /// Scope for the document box
12    pub scope: DocumentBoxScopeRaw,
13    /// Date of creation for the document box
14    pub created_at: DateTime<Utc>,
15}
16
17#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
18pub struct WithScope<T> {
19    #[serde(flatten)]
20    pub data: T,
21    pub scope: DocumentBoxScopeRaw,
22}
23
24impl<T> WithScope<T> {
25    pub fn new(data: T, scope: DocumentBoxScopeRaw) -> WithScope<T> {
26        WithScope { data, scope }
27    }
28}
29
30impl DocumentBox {
31    /// Find all document boxes within a specific tenant
32    pub async fn all(db: impl DbExecutor<'_>) -> DbResult<Vec<DocumentBox>> {
33        sqlx::query_as(r#"SELECT * FROM "docbox_boxes""#)
34            .fetch_all(db)
35            .await
36    }
37
38    /// Get a page from the document boxes list
39    pub async fn query(
40        db: impl DbExecutor<'_>,
41        offset: u64,
42        limit: u64,
43    ) -> DbResult<Vec<DocumentBox>> {
44        sqlx::query_as(
45            r#"
46            SELECT * FROM "docbox_boxes" 
47            ORDER BY "created_at" DESC 
48            OFFSET $1 LIMIT $2"#,
49        )
50        .bind(offset as i64)
51        .bind(limit as i64)
52        .fetch_all(db)
53        .await
54    }
55
56    /// Find a specific document box by scope within a tenant
57    pub async fn find_by_scope(
58        db: impl DbExecutor<'_>,
59        scope: &DocumentBoxScopeRaw,
60    ) -> DbResult<Option<DocumentBox>> {
61        sqlx::query_as(r#"SELECT * FROM "docbox_boxes" WHERE "scope" = $1"#)
62            .bind(scope)
63            .fetch_optional(db)
64            .await
65    }
66
67    pub async fn create(db: impl DbExecutor<'_>, scope: String) -> DbResult<DocumentBox> {
68        let document_box = DocumentBox {
69            scope,
70            created_at: Utc::now(),
71        };
72
73        sqlx::query(r#"INSERT INTO "docbox_boxes" ("scope", "created_at") VALUES ($1, $2)"#)
74            .bind(document_box.scope.as_str())
75            .bind(document_box.created_at)
76            .execute(db)
77            .await?;
78
79        Ok(document_box)
80    }
81
82    /// Deletes the document box
83    pub async fn delete(&self, db: impl DbExecutor<'_>) -> DbResult<PgQueryResult> {
84        sqlx::query(r#"DELETE FROM "docbox_boxes" WHERE "scope" = $1"#)
85            .bind(&self.scope)
86            .execute(db)
87            .await
88    }
89}