Skip to main content

shared/infrastructure/database/mongodb/
indexes.rs

1use mongodb::{Database, IndexModel, bson::doc, options::IndexOptions};
2
3use crate::domain::model::{PasswordResetToken, RolePermission, User, UserRole};
4
5pub struct MongodbIndexes {
6    pub db: Database,
7}
8impl MongodbIndexes {
9    pub async fn create_unique_email_index(&self) -> Result<(), mongodb::error::Error> {
10        let options = IndexOptions::builder().unique(true).build();
11        let model = IndexModel::builder()
12            .keys(doc! { "email": 1 })
13            .options(options)
14            .build();
15
16        self.db
17            .collection::<User>("users")
18            .create_index(model)
19            .await?;
20
21        Ok(())
22    }
23
24    pub async fn create_token_hash_index(&self) -> Result<(), mongodb::error::Error> {
25        let options = IndexOptions::builder()
26            .unique(true)
27            // TODO: implement TTL index, for auto removing
28            // use std::time::Duration;
29            // .expire_after(Some(Duration::from_secs(60 * 60))) // 30 minutes
30            .build();
31        let model = IndexModel::builder()
32            .keys(doc! { "token": 1 })
33            .options(options)
34            .build();
35
36        self.db
37            .collection::<PasswordResetToken>("password_reset_tokens")
38            .create_index(model)
39            .await?;
40
41        Ok(())
42    }
43
44    pub async fn create_role_permission_index(&self) -> Result<(), mongodb::error::Error> {
45        let options = IndexOptions::builder().unique(true).build();
46        let model = IndexModel::builder()
47            .keys(doc! { "roleId": 1, "permissionId": 1 })
48            .options(options)
49            .build();
50
51        self.db
52            .collection::<RolePermission>("role_permissions")
53            .create_index(model)
54            .await?;
55
56        Ok(())
57    }
58    pub async fn create_user_role_index(&self) -> Result<(), mongodb::error::Error> {
59        let options = IndexOptions::builder().unique(true).build();
60        let model = IndexModel::builder()
61            .keys(doc! { "roleId": 1, "userId": 1 })
62            .options(options)
63            .build();
64
65        self.db
66            .collection::<UserRole>("user_roles")
67            .create_index(model)
68            .await?;
69
70        Ok(())
71    }
72}