Skip to content

Commit 20c4226

Browse files
apoorvdixit88github-actions[bot]sahkalsai-harsha-vardhaninventvenkat
authored
feat(user): setup user tables (#2803)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Sahkal Poddar <[email protected]> Co-authored-by: Sahkal Poddar <[email protected]> Co-authored-by: Sai Harsha Vardhan <[email protected]> Co-authored-by: Venkatesh <[email protected]> Co-authored-by: venkatesh.devendran <[email protected]> Co-authored-by: Abhishek Marrivagu <[email protected]>
1 parent 966369b commit 20c4226

File tree

19 files changed

+919
-1
lines changed

19 files changed

+919
-1
lines changed

crates/diesel_models/src/enums.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,3 +401,25 @@ pub enum FraudCheckLastStep {
401401
TransactionOrRecordRefund,
402402
Fulfillment,
403403
}
404+
405+
#[derive(
406+
Clone,
407+
Copy,
408+
Debug,
409+
Default,
410+
Eq,
411+
PartialEq,
412+
serde::Serialize,
413+
serde::Deserialize,
414+
strum::Display,
415+
strum::EnumString,
416+
frunk::LabelledGeneric,
417+
)]
418+
#[router_derive::diesel_enum(storage_type = "text")]
419+
#[serde(rename_all = "snake_case")]
420+
#[strum(serialize_all = "snake_case")]
421+
pub enum UserStatus {
422+
Active,
423+
#[default]
424+
InvitationSent,
425+
}

crates/diesel_models/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ pub mod reverse_lookup;
3838
pub mod routing_algorithm;
3939
#[allow(unused_qualifications)]
4040
pub mod schema;
41+
pub mod user;
42+
pub mod user_role;
4143

4244
use diesel_impl::{DieselArray, OptionalDieselArray};
4345

crates/diesel_models/src/query.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,5 @@ pub mod process_tracker;
2828
pub mod refund;
2929
pub mod reverse_lookup;
3030
pub mod routing_algorithm;
31+
pub mod user;
32+
pub mod user_role;
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
use diesel::{associations::HasTable, ExpressionMethods};
2+
use error_stack::report;
3+
use router_env::tracing::{self, instrument};
4+
5+
use crate::{
6+
errors::{self},
7+
query::generics,
8+
schema::users::dsl,
9+
user::*,
10+
PgPooledConn, StorageResult,
11+
};
12+
13+
impl UserNew {
14+
#[instrument(skip(conn))]
15+
pub async fn insert(self, conn: &PgPooledConn) -> StorageResult<User> {
16+
generics::generic_insert(conn, self).await
17+
}
18+
}
19+
20+
impl User {
21+
pub async fn find_by_user_email(conn: &PgPooledConn, user_email: &str) -> StorageResult<Self> {
22+
generics::generic_find_one::<<Self as HasTable>::Table, _, _>(
23+
conn,
24+
dsl::email.eq(user_email.to_owned()),
25+
)
26+
.await
27+
}
28+
29+
pub async fn find_by_user_id(conn: &PgPooledConn, user_id: &str) -> StorageResult<Self> {
30+
generics::generic_find_one::<<Self as HasTable>::Table, _, _>(
31+
conn,
32+
dsl::user_id.eq(user_id.to_owned()),
33+
)
34+
.await
35+
}
36+
37+
pub async fn update_by_user_id(
38+
conn: &PgPooledConn,
39+
user_id: &str,
40+
user: UserUpdate,
41+
) -> StorageResult<Self> {
42+
generics::generic_update_with_results::<<Self as HasTable>::Table, _, _, _>(
43+
conn,
44+
dsl::user_id.eq(user_id.to_owned()),
45+
UserUpdateInternal::from(user),
46+
)
47+
.await?
48+
.first()
49+
.cloned()
50+
.ok_or_else(|| {
51+
report!(errors::DatabaseError::NotFound).attach_printable("Error while updating user")
52+
})
53+
}
54+
55+
pub async fn delete_by_user_id(conn: &PgPooledConn, user_id: &str) -> StorageResult<bool> {
56+
generics::generic_delete::<<Self as HasTable>::Table, _>(
57+
conn,
58+
dsl::user_id.eq(user_id.to_owned()),
59+
)
60+
.await
61+
}
62+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
use diesel::{associations::HasTable, BoolExpressionMethods, ExpressionMethods};
2+
use router_env::tracing::{self, instrument};
3+
4+
use crate::{query::generics, schema::user_roles::dsl, user_role::*, PgPooledConn, StorageResult};
5+
6+
impl UserRoleNew {
7+
#[instrument(skip(conn))]
8+
pub async fn insert(self, conn: &PgPooledConn) -> StorageResult<UserRole> {
9+
generics::generic_insert(conn, self).await
10+
}
11+
}
12+
13+
impl UserRole {
14+
pub async fn find_by_user_id(conn: &PgPooledConn, user_id: String) -> StorageResult<Self> {
15+
generics::generic_find_one::<<Self as HasTable>::Table, _, _>(
16+
conn,
17+
dsl::user_id.eq(user_id),
18+
)
19+
.await
20+
}
21+
22+
pub async fn update_by_user_id_merchant_id(
23+
conn: &PgPooledConn,
24+
user_id: String,
25+
merchant_id: String,
26+
update: UserRoleUpdate,
27+
) -> StorageResult<Self> {
28+
generics::generic_update_with_unique_predicate_get_result::<
29+
<Self as HasTable>::Table,
30+
_,
31+
_,
32+
_,
33+
>(
34+
conn,
35+
dsl::user_id
36+
.eq(user_id)
37+
.and(dsl::merchant_id.eq(merchant_id)),
38+
UserRoleUpdateInternal::from(update),
39+
)
40+
.await
41+
}
42+
43+
pub async fn delete_by_user_id(conn: &PgPooledConn, user_id: String) -> StorageResult<bool> {
44+
generics::generic_delete::<<Self as HasTable>::Table, _>(conn, dsl::user_id.eq(user_id))
45+
.await
46+
}
47+
48+
pub async fn list_by_user_id(conn: &PgPooledConn, user_id: String) -> StorageResult<Vec<Self>> {
49+
generics::generic_filter::<<Self as HasTable>::Table, _, _, _>(
50+
conn,
51+
dsl::user_id.eq(user_id),
52+
None,
53+
None,
54+
Some(dsl::created_at.asc()),
55+
)
56+
.await
57+
}
58+
}

crates/diesel_models/src/schema.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -900,6 +900,51 @@ diesel::table! {
900900
}
901901
}
902902

903+
diesel::table! {
904+
use diesel::sql_types::*;
905+
use crate::enums::diesel_exports::*;
906+
907+
user_roles (id) {
908+
id -> Int4,
909+
#[max_length = 64]
910+
user_id -> Varchar,
911+
#[max_length = 64]
912+
merchant_id -> Varchar,
913+
#[max_length = 64]
914+
role_id -> Varchar,
915+
#[max_length = 64]
916+
org_id -> Varchar,
917+
#[max_length = 64]
918+
status -> Varchar,
919+
#[max_length = 64]
920+
created_by -> Varchar,
921+
#[max_length = 64]
922+
last_modified_by -> Varchar,
923+
created_at -> Timestamp,
924+
last_modified_at -> Timestamp,
925+
}
926+
}
927+
928+
diesel::table! {
929+
use diesel::sql_types::*;
930+
use crate::enums::diesel_exports::*;
931+
932+
users (id) {
933+
id -> Int4,
934+
#[max_length = 64]
935+
user_id -> Varchar,
936+
#[max_length = 255]
937+
email -> Varchar,
938+
#[max_length = 255]
939+
name -> Varchar,
940+
#[max_length = 255]
941+
password -> Varchar,
942+
is_verified -> Bool,
943+
created_at -> Timestamp,
944+
last_modified_at -> Timestamp,
945+
}
946+
}
947+
903948
diesel::allow_tables_to_appear_in_same_query!(
904949
address,
905950
api_keys,
@@ -929,4 +974,6 @@ diesel::allow_tables_to_appear_in_same_query!(
929974
refund,
930975
reverse_lookup,
931976
routing_algorithm,
977+
user_roles,
978+
users,
932979
);

crates/diesel_models/src/user.rs

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
use common_utils::pii;
2+
use diesel::{AsChangeset, Identifiable, Insertable, Queryable};
3+
use masking::Secret;
4+
use time::PrimitiveDateTime;
5+
6+
use crate::schema::users;
7+
8+
#[derive(Clone, Debug, Identifiable, Queryable)]
9+
#[diesel(table_name = users)]
10+
pub struct User {
11+
pub id: i32,
12+
pub user_id: String,
13+
pub email: pii::Email,
14+
pub name: Secret<String>,
15+
pub password: Secret<String>,
16+
pub is_verified: bool,
17+
pub created_at: PrimitiveDateTime,
18+
pub last_modified_at: PrimitiveDateTime,
19+
}
20+
21+
#[derive(
22+
router_derive::Setter, Clone, Debug, Default, Insertable, router_derive::DebugAsDisplay,
23+
)]
24+
#[diesel(table_name = users)]
25+
pub struct UserNew {
26+
pub user_id: String,
27+
pub email: pii::Email,
28+
pub name: Secret<String>,
29+
pub password: Secret<String>,
30+
pub is_verified: bool,
31+
pub created_at: Option<PrimitiveDateTime>,
32+
pub last_modified_at: Option<PrimitiveDateTime>,
33+
}
34+
35+
#[derive(Clone, Debug, AsChangeset, router_derive::DebugAsDisplay)]
36+
#[diesel(table_name = users)]
37+
pub struct UserUpdateInternal {
38+
name: Option<String>,
39+
password: Option<Secret<String>>,
40+
is_verified: Option<bool>,
41+
last_modified_at: PrimitiveDateTime,
42+
}
43+
44+
#[derive(Debug)]
45+
pub enum UserUpdate {
46+
VerifyUser,
47+
AccountUpdate {
48+
name: Option<String>,
49+
password: Option<Secret<String>>,
50+
is_verified: Option<bool>,
51+
},
52+
}
53+
54+
impl From<UserUpdate> for UserUpdateInternal {
55+
fn from(user_update: UserUpdate) -> Self {
56+
let last_modified_at = common_utils::date_time::now();
57+
match user_update {
58+
UserUpdate::VerifyUser => Self {
59+
name: None,
60+
password: None,
61+
is_verified: Some(true),
62+
last_modified_at,
63+
},
64+
UserUpdate::AccountUpdate {
65+
name,
66+
password,
67+
is_verified,
68+
} => Self {
69+
name,
70+
password,
71+
is_verified,
72+
last_modified_at,
73+
},
74+
}
75+
}
76+
}

crates/diesel_models/src/user_role.rs

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
use diesel::{AsChangeset, Identifiable, Insertable, Queryable};
2+
use time::PrimitiveDateTime;
3+
4+
use crate::{enums, schema::user_roles};
5+
6+
#[derive(Clone, Debug, Identifiable, Queryable)]
7+
#[diesel(table_name = user_roles)]
8+
pub struct UserRole {
9+
pub id: i32,
10+
pub user_id: String,
11+
pub merchant_id: String,
12+
pub role_id: String,
13+
pub org_id: String,
14+
pub status: enums::UserStatus,
15+
pub created_by: String,
16+
pub last_modified_by: String,
17+
pub created_at: PrimitiveDateTime,
18+
pub last_modified_at: PrimitiveDateTime,
19+
}
20+
21+
#[derive(router_derive::Setter, Clone, Debug, Insertable, router_derive::DebugAsDisplay)]
22+
#[diesel(table_name = user_roles)]
23+
pub struct UserRoleNew {
24+
pub user_id: String,
25+
pub merchant_id: String,
26+
pub role_id: String,
27+
pub org_id: String,
28+
pub status: enums::UserStatus,
29+
pub created_by: String,
30+
pub last_modified_by: String,
31+
pub created_at: PrimitiveDateTime,
32+
pub last_modified_at: PrimitiveDateTime,
33+
}
34+
35+
#[derive(Clone, Debug, AsChangeset, router_derive::DebugAsDisplay)]
36+
#[diesel(table_name = user_roles)]
37+
pub struct UserRoleUpdateInternal {
38+
role_id: Option<String>,
39+
status: Option<enums::UserStatus>,
40+
last_modified_by: Option<String>,
41+
last_modified_at: PrimitiveDateTime,
42+
}
43+
44+
pub enum UserRoleUpdate {
45+
UpdateStatus {
46+
status: enums::UserStatus,
47+
modified_by: String,
48+
},
49+
UpdateRole {
50+
role_id: String,
51+
modified_by: String,
52+
},
53+
}
54+
55+
impl From<UserRoleUpdate> for UserRoleUpdateInternal {
56+
fn from(value: UserRoleUpdate) -> Self {
57+
let last_modified_at = common_utils::date_time::now();
58+
match value {
59+
UserRoleUpdate::UpdateRole {
60+
role_id,
61+
modified_by,
62+
} => Self {
63+
role_id: Some(role_id),
64+
last_modified_by: Some(modified_by),
65+
status: None,
66+
last_modified_at,
67+
},
68+
UserRoleUpdate::UpdateStatus {
69+
status,
70+
modified_by,
71+
} => Self {
72+
status: Some(status),
73+
last_modified_at,
74+
last_modified_by: Some(modified_by),
75+
role_id: None,
76+
},
77+
}
78+
}
79+
}

crates/router/src/db.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ pub mod payouts;
2525
pub mod refund;
2626
pub mod reverse_lookup;
2727
pub mod routing_algorithm;
28+
pub mod user;
29+
pub mod user_role;
2830

2931
use data_models::payments::{
3032
payment_attempt::PaymentAttemptInterface, payment_intent::PaymentIntentInterface,
@@ -80,6 +82,8 @@ pub trait StorageInterface:
8082
+ organization::OrganizationInterface
8183
+ routing_algorithm::RoutingAlgorithmInterface
8284
+ gsm::GsmInterface
85+
+ user::UserInterface
86+
+ user_role::UserRoleInterface
8387
+ 'static
8488
{
8589
fn get_scheduler_db(&self) -> Box<dyn scheduler::SchedulerInterface>;

0 commit comments

Comments
 (0)