Skip to main content

shared/domain/user_role/
repository.rs

1use std::sync::Arc;
2
3use crate::error::{CoreError, InternalError, ResourceKind, Result};
4
5use super::model::UserRole;
6use super::ports::database::DatabaseAdapter;
7use super::ports::query::QueryBuilder;
8
9#[derive(Clone)]
10pub struct UserRoleRepository {
11    adapter: Arc<dyn DatabaseAdapter<UserRole>>,
12}
13
14impl UserRoleRepository {
15    pub fn new(adapter: Arc<dyn DatabaseAdapter<UserRole>>) -> Self {
16        Self { adapter }
17    }
18}
19
20impl UserRoleRepository {
21    #[tracing::instrument(name = "db.user_role.insert", skip(self, role))]
22    pub async fn insert(&self, role: UserRole) -> Result<()> {
23        match self.adapter.upsert(role).await {
24            Ok(_id) => Ok(()),
25            Err(err) => {
26                tracing::error!("Failed to assign role to user - {err}");
27                Err(CoreError::Internal(InternalError::Database(
28                    err.to_string(),
29                )))
30            }
31        }
32    }
33
34    #[tracing::instrument(name = "db.user_role.find", skip(self, id))]
35    pub async fn find(&self, id: &str) -> Result<UserRole> {
36        let filter = QueryBuilder::default().eq("id", id);
37
38        match self.adapter.find_one(filter).await {
39            Ok(Some(role)) => Ok(role),
40            Ok(None) => Err(CoreError::NotFound(ResourceKind::Role {
41                id: Some(id.into()),
42            })),
43            Err(err) => {
44                tracing::error!(error_code = "InternalError::Database", error = %err, "Database query failed");
45                Err(err)
46            }
47        }
48    }
49
50    #[tracing::instrument(name = "db.user_role.find_all", skip(self, user_id))]
51    pub async fn find_all(&self, user_id: &str) -> Result<Vec<UserRole>> {
52        let filter = QueryBuilder::default().eq("userId", user_id);
53
54        match self.adapter.find_all(filter).await {
55            Ok(roles) => Ok(roles),
56            Err(err) => {
57                tracing::error!(error_code = "InternalError::Database", error = %err, "Database query failed");
58                Err(err)
59            }
60        }
61    }
62
63    #[tracing::instrument(name = "db.user_role.find_all_by_user_and_role", skip(self, user_id))]
64    pub async fn find_all_by_user_and_role(
65        &self,
66        user_id: &str,
67        role_id: &str,
68    ) -> Result<UserRole> {
69        let filter = QueryBuilder::default()
70            .eq("userId", user_id)
71            .eq("roleId", role_id);
72
73        match self.adapter.find_one(filter).await {
74            Ok(Some(user_role)) => Ok(user_role),
75            Ok(None) => Err(CoreError::NotFound(ResourceKind::Role {
76                id: Some(role_id.into()),
77            })),
78            Err(err) => {
79                tracing::error!(error_code = "InternalError::Database", error = %err, "Database query failed");
80                Err(err)
81            }
82        }
83    }
84
85    #[tracing::instrument(name = "db.user_role.find", skip(self, user_id, role_id))]
86    pub async fn delete(&self, user_id: &str, role_id: &str) -> Result<()> {
87        let filter = QueryBuilder::default()
88            .eq("userId", user_id)
89            .eq("roleId", role_id);
90
91        match self.adapter.delete_one(filter).await {
92            Ok(_) => Ok(()),
93            Err(err) => {
94                tracing::error!(error_code = "InternalError::Database", error = %err, "Database query failed");
95                Err(err)
96            }
97        }
98    }
99}