feat: add gacha

This commit is contained in:
Maulana Sodiqin
2025-04-01 20:00:00 +07:00
parent 4b8da68df4
commit 8d2f720de1
15 changed files with 377 additions and 120 deletions
+1 -1
View File
@@ -41,7 +41,7 @@ jobs:
username: ${{ secrets.VPS_USER }} username: ${{ secrets.VPS_USER }}
key: ${{ secrets.VPS_SSH_KEY }} key: ${{ secrets.VPS_SSH_KEY }}
port: ${{ secrets.VPS_PORT }} port: ${{ secrets.VPS_PORT }}
source: ./target/release/imphnen-backend-service source: ./target/release/*
target: /opt/imphnen-backend-service/imphnen-backend-service target: /opt/imphnen-backend-service/imphnen-backend-service
rm: true rm: true
overwrite: true overwrite: true
+1 -1
View File
@@ -120,7 +120,7 @@ impl AuthService {
let auth_repo = AuthRepository::new(state); let auth_repo = AuthRepository::new(state);
let role_repo = RolesRepository::new(state); let role_repo = RolesRepository::new(state);
let role = match role_repo let role = match role_repo
.query_role_by_name(RolesEnum::Student.to_string()) .query_role_by_name(RolesEnum::User.to_string())
.await .await
{ {
Ok(role) => role, Ok(role) => role,
+91
View File
@@ -0,0 +1,91 @@
use serde::{Deserialize, Serialize};
use surrealdb::sql::Thing;
use utoipa::ToSchema;
use validator::Validate;
#[derive(Clone, Debug, Serialize, Deserialize, ToSchema, Validate)]
pub struct GachaItemRequestDto {
#[validate(length(min = 1, message = "Item name must not be empty"))]
pub name: String,
}
#[derive(Clone, Debug, Serialize, Deserialize, ToSchema, Validate)]
pub struct GachaClaimRequestDto {
#[validate(length(min = 1, message = "User ID must not be empty"))]
pub user_id: String,
#[validate(length(min = 1, message = "Item ID must not be empty"))]
pub item_id: String,
}
#[derive(Clone, Debug, Serialize, Deserialize, ToSchema, Validate)]
pub struct GachaRollRequestDto {
#[validate(length(min = 1, message = "Item ID must not be empty"))]
pub item_id: String,
#[validate(range(min = 1, message = "Weight must be greater than zero"))]
pub weight: f32,
#[validate(range(min = 1, message = "Quantity must be at least 1"))]
pub quantity: i32,
}
#[derive(Clone, Debug, Serialize, Deserialize, ToSchema)]
pub struct GachaItemDto {
pub id: String,
pub name: String,
pub is_deleted: bool,
pub created_at: Option<String>,
pub updated_at: Option<String>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct GachaItemDtoRaw {
pub id: Thing,
pub name: String,
pub is_deleted: bool,
pub created_at: Option<String>,
pub updated_at: Option<String>,
}
#[derive(Clone, Debug, Serialize, Deserialize, ToSchema)]
pub struct GachaClaimDto {
pub id: String,
pub user: String,
pub item: String,
pub is_deleted: bool,
pub created_at: Option<String>,
pub updated_at: Option<String>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct GachaClaimDtoRaw {
pub id: Thing,
pub user: Thing,
pub item: Thing,
pub is_deleted: bool,
pub created_at: Option<String>,
pub updated_at: Option<String>,
}
#[derive(Clone, Debug, Serialize, Deserialize, ToSchema)]
pub struct GachaRollDto {
pub id: String,
pub item: String,
pub weight: String,
pub quantity: i32,
pub is_deleted: bool,
pub created_at: Option<String>,
pub updated_at: Option<String>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct GachaRollDtoRaw {
pub id: Thing,
pub item: Thing,
pub weight: String,
pub quantity: i32,
pub is_deleted: bool,
pub created_at: Option<String>,
pub updated_at: Option<String>,
}
+155
View File
@@ -0,0 +1,155 @@
use super::{GachaClaimSchema, GachaItemSchema, GachaRollSchema};
use crate::{
get_id, make_thing, query_list_with_meta, AppState, MetaRequestDto, ResourceEnum,
ResponseListSuccessDto,
};
use anyhow::{bail, Result};
pub struct GachaRepository<'a> {
state: &'a AppState,
}
impl<'a> GachaRepository<'a> {
pub fn new(state: &'a AppState) -> Self {
Self { state }
}
pub async fn query_gacha_item_list(
&self,
meta: MetaRequestDto,
) -> Result<ResponseListSuccessDto<Vec<GachaItemSchema>>> {
let mut conditions = vec!["is_deleted = false".into()];
if meta.search.is_some() {
conditions.push("string::contains(name, $search)".into());
}
query_list_with_meta(
&self.state.surrealdb_ws,
&ResourceEnum::GachaItems.to_string(),
&meta,
conditions,
None,
)
.await
}
pub async fn query_gacha_item_by_id(&self, id: String) -> Result<GachaItemSchema> {
let db = &self.state.surrealdb_ws;
let result: Option<GachaItemSchema> = db
.select((ResourceEnum::GachaItems.to_string(), id.clone()))
.await?;
match result {
Some(item) if !item.is_deleted => Ok(item),
_ => bail!("Gacha Item not found"),
}
}
pub async fn query_create_gacha_item(
&self,
data: GachaItemSchema,
) -> Result<String> {
let db = &self.state.surrealdb_ws;
let record: Option<GachaItemSchema> = db
.create(ResourceEnum::GachaItems.to_string())
.content(data)
.await?;
match record {
Some(_) => Ok("Success create Gacha Item".into()),
None => bail!("Failed to create Gacha Item"),
}
}
pub async fn query_update_gacha_item(
&self,
data: GachaItemSchema,
) -> Result<String> {
let db = &self.state.surrealdb_ws;
let record_key = get_id(&data.id)?;
let existing = self.query_gacha_item_by_id(data.id.id.to_raw()).await?;
if existing.is_deleted {
bail!("Gacha Item already deleted");
}
let merged = GachaItemSchema {
created_at: existing.created_at,
..data.clone()
};
let record: Option<GachaItemSchema> =
db.update(record_key).merge(merged).await?;
match record {
Some(_) => Ok("Success update Gacha Item".into()),
None => bail!("Failed to update Gacha Item"),
}
}
pub async fn query_delete_gacha_item(&self, id: String) -> Result<String> {
let db = &self.state.surrealdb_ws;
let item_id = make_thing(&ResourceEnum::GachaItems.to_string(), &id);
let item = self.query_gacha_item_by_id(item_id.id.to_raw()).await?;
if item.is_deleted {
bail!("Gacha Item already deleted");
}
let record_key = get_id(&item.id)?;
let record: Option<GachaItemSchema> = db
.update(record_key)
.merge(serde_json::json!({ "is_deleted": true }))
.await?;
match record {
Some(_) => Ok("Success delete Gacha Item".into()),
None => bail!("Failed to delete Gacha Item"),
}
}
pub async fn query_gacha_claim_by_id(
&self,
id: String,
) -> Result<GachaClaimSchema> {
let db = &self.state.surrealdb_ws;
let result: Option<GachaClaimSchema> = db
.select((ResourceEnum::GachaClaims.to_string(), id.clone()))
.await?;
match result {
Some(claim) if !claim.is_deleted => Ok(claim),
_ => bail!("Gacha Claim not found"),
}
}
pub async fn query_create_gacha_claim(
&self,
data: GachaClaimSchema,
) -> Result<String> {
let db = &self.state.surrealdb_ws;
let record: Option<GachaClaimSchema> = db
.create(ResourceEnum::GachaClaims.to_string())
.content(data)
.await?;
match record {
Some(_) => Ok("Success create Gacha Claim".into()),
None => bail!("Failed to create Gacha Claim"),
}
}
pub async fn query_gacha_roll_by_id(&self, id: String) -> Result<GachaRollSchema> {
let db = &self.state.surrealdb_ws;
let result: Option<GachaRollSchema> = db
.select((ResourceEnum::GachaRolls.to_string(), id.clone()))
.await?;
match result {
Some(roll) if !roll.is_deleted => Ok(roll),
_ => bail!("Gacha Roll not found"),
}
}
pub async fn query_create_gacha_roll(
&self,
data: GachaRollSchema,
) -> Result<String> {
let db = &self.state.surrealdb_ws;
let record: Option<GachaRollSchema> = db
.create(ResourceEnum::GachaRolls.to_string())
.content(data)
.await?;
match record {
Some(_) => Ok("Success create Gacha Roll".into()),
None => bail!("Failed to create Gacha Roll"),
}
}
}
+90
View File
@@ -0,0 +1,90 @@
use crate::{make_thing, ResourceEnum};
use serde::{Deserialize, Serialize};
use surrealdb::{sql::Thing, Uuid};
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct GachaItemSchema {
pub id: Thing,
pub name: String,
pub is_deleted: bool,
pub created_at: Option<String>,
pub updated_at: Option<String>,
}
impl Default for GachaItemSchema {
fn default() -> Self {
GachaItemSchema {
id: make_thing(
&ResourceEnum::GachaItems.to_string(),
&Uuid::new_v4().to_string(),
),
name: String::new(),
is_deleted: false,
created_at: None,
updated_at: None,
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct GachaClaimSchema {
pub id: Thing,
pub user: Thing,
pub item: Thing,
pub is_deleted: bool,
pub created_at: Option<String>,
pub updated_at: Option<String>,
}
impl Default for GachaClaimSchema {
fn default() -> Self {
GachaClaimSchema {
id: make_thing(
&ResourceEnum::GachaClaims.to_string(),
&Uuid::new_v4().to_string(),
),
user: make_thing(
&ResourceEnum::Users.to_string(),
&Uuid::new_v4().to_string(),
),
item: make_thing(
&ResourceEnum::GachaItems.to_string(),
&Uuid::new_v4().to_string(),
),
is_deleted: false,
created_at: None,
updated_at: None,
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct GachaRollSchema {
pub id: Thing,
pub item: Thing,
pub weight: f32,
pub quantity: i32,
pub is_deleted: bool,
pub created_at: Option<String>,
pub updated_at: Option<String>,
}
impl Default for GachaRollSchema {
fn default() -> Self {
GachaRollSchema {
id: make_thing(
&ResourceEnum::GachaClaims.to_string(),
&Uuid::new_v4().to_string(),
),
item: make_thing(
&ResourceEnum::GachaRolls.to_string(),
&Uuid::new_v4().to_string(),
),
weight: 0.2,
quantity: 2,
is_deleted: false,
created_at: None,
updated_at: None,
}
}
}
+6
View File
@@ -0,0 +1,6 @@
pub mod gacha_dto;
pub mod gacha_repository;
pub mod gacha_schema;
pub use gacha_repository::*;
pub use gacha_schema::*;
+1
View File
@@ -1,6 +1,7 @@
use axum::{middleware::from_fn, Router}; use axum::{middleware::from_fn, Router};
pub mod auth; pub mod auth;
pub mod docs; pub mod docs;
pub mod gacha;
pub mod permissions; pub mod permissions;
pub mod roles; pub mod roles;
pub mod users; pub mod users;
@@ -17,16 +17,6 @@ pub enum PermissionsEnum {
CreatePermissions, CreatePermissions,
DeletePermissions, DeletePermissions,
UpdatePermissions, UpdatePermissions,
ReadListSessions,
ReadDetailSessions,
CreateSessions,
UpdateSessions,
DeleteSessions,
ReadListTests,
ReadDetailTests,
CreateTests,
UpdateTests,
DeleteTests,
} }
impl fmt::Display for PermissionsEnum { impl fmt::Display for PermissionsEnum {
@@ -47,16 +37,6 @@ impl fmt::Display for PermissionsEnum {
PermissionsEnum::CreatePermissions => "Create Permissions", PermissionsEnum::CreatePermissions => "Create Permissions",
PermissionsEnum::DeletePermissions => "Delete Permissions", PermissionsEnum::DeletePermissions => "Delete Permissions",
PermissionsEnum::UpdatePermissions => "Update Permissions", PermissionsEnum::UpdatePermissions => "Update Permissions",
PermissionsEnum::ReadListSessions => "Read List Sessions",
PermissionsEnum::ReadDetailSessions => "Read Detail Sessions",
PermissionsEnum::CreateSessions => "Create Sessions",
PermissionsEnum::UpdateSessions => "Update Sessions",
PermissionsEnum::DeleteSessions => "Delete Sessions",
PermissionsEnum::ReadListTests => "Read List Tests",
PermissionsEnum::ReadDetailTests => "Read Detail Tests",
PermissionsEnum::CreateTests => "Create Tests",
PermissionsEnum::UpdateTests => "Update Tests",
PermissionsEnum::DeleteTests => "Delete Tests",
}; };
write!(f, "{}", permission_str) write!(f, "{}", permission_str)
} }
@@ -1,9 +1,6 @@
use crate::ResourceEnum; use crate::{make_thing, ResourceEnum};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use surrealdb::{ use surrealdb::{sql::Thing, Uuid};
sql::{Id, Thing},
Uuid,
};
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
pub struct PermissionsSchema { pub struct PermissionsSchema {
@@ -17,10 +14,10 @@ pub struct PermissionsSchema {
impl Default for PermissionsSchema { impl Default for PermissionsSchema {
fn default() -> Self { fn default() -> Self {
PermissionsSchema { PermissionsSchema {
id: Thing::from(( id: make_thing(
ResourceEnum::Permissions.to_string(), &ResourceEnum::Permissions.to_string(),
Id::String(Uuid::new_v4().to_string()), &Uuid::new_v4().to_string(),
)), ),
name: String::new(), name: String::new(),
is_deleted: false, is_deleted: false,
created_at: None, created_at: None,
+2 -2
View File
@@ -3,7 +3,7 @@ use std::fmt;
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
pub enum RolesEnum { pub enum RolesEnum {
Admin, Admin,
Student, User,
Staf, Staf,
} }
@@ -11,7 +11,7 @@ impl fmt::Display for RolesEnum {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let roles_str = match self { let roles_str = match self {
RolesEnum::Admin => "Admin", RolesEnum::Admin => "Admin",
RolesEnum::Student => "Student", RolesEnum::User => "User",
RolesEnum::Staf => "Staf", RolesEnum::Staf => "Staf",
}; };
write!(f, "{}", roles_str) write!(f, "{}", roles_str)
+10 -13
View File
@@ -1,10 +1,7 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use surrealdb::{ use surrealdb::{sql::Thing, Uuid};
sql::{Id, Thing},
Uuid,
};
use crate::ResourceEnum; use crate::{make_thing, ResourceEnum};
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
pub struct RolesSchema { pub struct RolesSchema {
@@ -19,14 +16,14 @@ pub struct RolesSchema {
impl Default for RolesSchema { impl Default for RolesSchema {
fn default() -> Self { fn default() -> Self {
RolesSchema { RolesSchema {
id: Thing::from(( id: make_thing(
ResourceEnum::Roles.to_string(), &ResourceEnum::Roles.to_string(),
Id::String(Uuid::new_v4().to_string()), &Uuid::new_v4().to_string(),
)), ),
permissions: vec![Thing::from(( permissions: vec![make_thing(
ResourceEnum::Permissions.to_string(), &ResourceEnum::Permissions.to_string(),
Id::String(Uuid::new_v4().to_string()), &Uuid::new_v4().to_string(),
))], )],
name: String::new(), name: String::new(),
is_deleted: false, is_deleted: false,
created_at: None, created_at: None,
+11 -11
View File
@@ -106,7 +106,7 @@ async fn test_create_user_should_return_201() {
let state = create_mock_app_state().await; let state = create_mock_app_state().await;
let role_repo = RolesRepository::new(&state); let role_repo = RolesRepository::new(&state);
let role = role_repo let role = role_repo
.query_role_by_name(RolesEnum::Student.to_string()) .query_role_by_name(RolesEnum::User.to_string())
.await .await
.unwrap(); .unwrap();
let role_id = role.id; let role_id = role.id;
@@ -131,7 +131,7 @@ async fn test_get_user_detail_should_return_200() {
let state = create_mock_app_state().await; let state = create_mock_app_state().await;
let role_repo = RolesRepository::new(&state); let role_repo = RolesRepository::new(&state);
let role = role_repo let role = role_repo
.query_role_by_name(RolesEnum::Student.to_string()) .query_role_by_name(RolesEnum::User.to_string())
.await .await
.unwrap(); .unwrap();
let role_id = role.id; let role_id = role.id;
@@ -160,7 +160,7 @@ async fn test_delete_user_should_return_200() {
let state = create_mock_app_state().await; let state = create_mock_app_state().await;
let role_repo = RolesRepository::new(&state); let role_repo = RolesRepository::new(&state);
let role = role_repo let role = role_repo
.query_role_by_name(RolesEnum::Student.to_string()) .query_role_by_name(RolesEnum::User.to_string())
.await .await
.expect("Failed to get role"); .expect("Failed to get role");
let repo = UsersRepository::new(&state); let repo = UsersRepository::new(&state);
@@ -193,7 +193,7 @@ async fn test_activate_user_should_return_200() {
let state = create_mock_app_state().await; let state = create_mock_app_state().await;
let role_repo = RolesRepository::new(&state); let role_repo = RolesRepository::new(&state);
let role = role_repo let role = role_repo
.query_role_by_name(RolesEnum::Student.to_string()) .query_role_by_name(RolesEnum::User.to_string())
.await .await
.unwrap(); .unwrap();
let role_id = role.id; let role_id = role.id;
@@ -228,7 +228,7 @@ async fn test_update_user_should_return_200() {
let state = create_mock_app_state().await; let state = create_mock_app_state().await;
let role_repo = RolesRepository::new(&state); let role_repo = RolesRepository::new(&state);
let role = role_repo let role = role_repo
.query_role_by_name(RolesEnum::Student.to_string()) .query_role_by_name(RolesEnum::User.to_string())
.await .await
.unwrap(); .unwrap();
let role_id = role.id.clone(); let role_id = role.id.clone();
@@ -274,7 +274,7 @@ async fn test_create_user_should_fail_if_email_taken() {
let state = create_mock_app_state().await; let state = create_mock_app_state().await;
let role_repo = RolesRepository::new(&state); let role_repo = RolesRepository::new(&state);
let role = role_repo let role = role_repo
.query_role_by_name(RolesEnum::Student.to_string()) .query_role_by_name(RolesEnum::User.to_string())
.await .await
.unwrap(); .unwrap();
let role_id = role.id.clone(); let role_id = role.id.clone();
@@ -317,7 +317,7 @@ async fn test_delete_user_should_fail_if_already_deleted() {
let state = create_mock_app_state().await; let state = create_mock_app_state().await;
let role_repo = RolesRepository::new(&state); let role_repo = RolesRepository::new(&state);
let role = role_repo let role = role_repo
.query_role_by_name(RolesEnum::Student.to_string()) .query_role_by_name(RolesEnum::User.to_string())
.await .await
.unwrap(); .unwrap();
let role_id = role.id.clone(); let role_id = role.id.clone();
@@ -350,7 +350,7 @@ async fn test_update_user_should_fail_if_user_not_found() {
let state = create_mock_app_state().await; let state = create_mock_app_state().await;
let role_repo = RolesRepository::new(&state); let role_repo = RolesRepository::new(&state);
let role = role_repo let role = role_repo
.query_role_by_name(RolesEnum::Student.to_string()) .query_role_by_name(RolesEnum::User.to_string())
.await .await
.unwrap(); .unwrap();
let role_id = role.id.clone(); let role_id = role.id.clone();
@@ -481,7 +481,7 @@ async fn test_user_detail_should_fail_if_user_is_soft_deleted() {
let state = create_mock_app_state().await; let state = create_mock_app_state().await;
let role_repo = RolesRepository::new(&state); let role_repo = RolesRepository::new(&state);
let role = role_repo let role = role_repo
.query_role_by_name(RolesEnum::Student.to_string()) .query_role_by_name(RolesEnum::User.to_string())
.await .await
.unwrap(); .unwrap();
let role_id = role.id.clone(); let role_id = role.id.clone();
@@ -514,7 +514,7 @@ async fn test_update_user_should_fail_if_user_is_deleted() {
let state = create_mock_app_state().await; let state = create_mock_app_state().await;
let role_repo = RolesRepository::new(&state); let role_repo = RolesRepository::new(&state);
let role = role_repo let role = role_repo
.query_role_by_name(RolesEnum::Student.to_string()) .query_role_by_name(RolesEnum::User.to_string())
.await .await
.unwrap(); .unwrap();
let role_id = role.id.clone(); let role_id = role.id.clone();
@@ -559,7 +559,7 @@ async fn test_update_user_should_fail_if_payload_invalid() {
let state = create_mock_app_state().await; let state = create_mock_app_state().await;
let role_repo = RolesRepository::new(&state); let role_repo = RolesRepository::new(&state);
let role = role_repo let role = role_repo
.query_role_by_name(RolesEnum::Student.to_string()) .query_role_by_name(RolesEnum::User.to_string())
.await .await
.unwrap(); .unwrap();
let role_id = role.id.clone(); let role_id = role.id.clone();
-48
View File
@@ -58,24 +58,12 @@ async fn main() -> Result<(), Box<dyn Error>> {
Some("2025-02-01T12:38:09.741726+00"), Some("2025-02-01T12:38:09.741726+00"),
Some("2025-02-01T12:38:09.741727+00"), Some("2025-02-01T12:38:09.741727+00"),
), ),
(
"529fe4da-7e20-4c76-8bc1-d7f7c121218f",
"Create Tests",
Some("2025-02-24T16:52:27.316909+00"),
Some("2025-02-24T16:52:27.316918+00"),
),
( (
"73888d18-b3e9-4f62-95a5-ba2c0d69fccb", "73888d18-b3e9-4f62-95a5-ba2c0d69fccb",
"Read Detail Roles", "Read Detail Roles",
Some("2025-01-29T05:13:06.445925+00"), Some("2025-01-29T05:13:06.445925+00"),
Some("2025-01-29T10:31:46.408564+00"), Some("2025-01-29T10:31:46.408564+00"),
), ),
(
"79dfe6dc-748c-4b9c-9535-b896b391d676",
"Delete Tests",
Some("2025-02-24T16:52:27.455878+00"),
Some("2025-02-24T16:52:27.455888+00"),
),
( (
"7c15e31d-36e2-49f9-97db-138c03fb0cf6", "7c15e31d-36e2-49f9-97db-138c03fb0cf6",
"Read List Users", "Read List Users",
@@ -88,12 +76,6 @@ async fn main() -> Result<(), Box<dyn Error>> {
Some("2025-02-24T16:52:26.886664+00"), Some("2025-02-24T16:52:26.886664+00"),
Some("2025-02-24T16:52:26.886673+00"), Some("2025-02-24T16:52:26.886673+00"),
), ),
(
"811d386b-e5f0-4e00-a164-f3d885197e30",
"Update Tests",
Some("2025-02-24T16:52:27.385216+00"),
Some("2025-02-24T16:52:27.385225+00"),
),
( (
"8195eeb8-e64f-4172-aa57-596492c84a72", "8195eeb8-e64f-4172-aa57-596492c84a72",
"Read List Permissions", "Read List Permissions",
@@ -106,12 +88,6 @@ async fn main() -> Result<(), Box<dyn Error>> {
Some("2025-02-24T16:52:27.179542+00"), Some("2025-02-24T16:52:27.179542+00"),
Some("2025-02-24T16:52:27.179551+00"), Some("2025-02-24T16:52:27.179551+00"),
), ),
(
"8cfd3b4d-0a41-456d-88e5-6c21cef1766a",
"Delete Sessions",
Some("2025-02-24T16:52:27.111123+00"),
Some("2025-02-24T16:52:27.111132+00"),
),
( (
"9164ca6e-c7e3-4238-a15f-f36ab9577e7e", "9164ca6e-c7e3-4238-a15f-f36ab9577e7e",
"Read List Roles", "Read List Roles",
@@ -142,36 +118,12 @@ async fn main() -> Result<(), Box<dyn Error>> {
Some("2025-01-29T05:14:22.511084+00"), Some("2025-01-29T05:14:22.511084+00"),
Some("2025-01-29T05:14:22.511085+00"), Some("2025-01-29T05:14:22.511085+00"),
), ),
(
"b70733db-b1c8-4aa3-a10f-b7cf773d896b",
"Create Sessions",
Some("2025-02-24T16:52:26.974279+00"),
Some("2025-02-24T16:52:26.97429+00"),
),
(
"c0a31b2c-3f0c-4e82-b018-e60ba8674112",
"Update Sessions",
Some("2025-02-24T16:52:27.042858+00"),
Some("2025-02-24T16:52:27.042866+00"),
),
(
"cab6aff5-e9c6-4ed3-afe9-93ef927e1f92",
"Read List Sessions",
Some("2025-02-22T15:38:09.521014+00"),
Some("2025-02-22T15:38:25.964821+00"),
),
( (
"dad435cf-042c-41bd-a946-cea61ed2ffbc", "dad435cf-042c-41bd-a946-cea61ed2ffbc",
"Read Detail Permissions", "Read Detail Permissions",
Some("2025-01-28T15:07:10.990214+00"), Some("2025-01-28T15:07:10.990214+00"),
Some("2025-01-28T15:07:10.990214+00"), Some("2025-01-28T15:07:10.990214+00"),
), ),
(
"f768aff5-8011-4439-b901-d8793c60d841",
"Read Detail Tests",
Some("2025-02-24T16:52:27.2483+00"),
Some("2025-02-24T16:52:27.248308+00"),
),
]; ];
for (id, name, _created_at, _updated_at) in permissions { for (id, name, _created_at, _updated_at) in permissions {
db.query("CREATE type::thing('app_permissions', $id) CONTENT $data") db.query("CREATE type::thing('app_permissions', $id) CONTENT $data")
+1 -13
View File
@@ -25,7 +25,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
), ),
( (
"5713cb37-dc02-4e87-8048-d7a41d352059", "5713cb37-dc02-4e87-8048-d7a41d352059",
"Student", "User",
None, None,
Some("2025-02-28T14:53:58.576688+00"), Some("2025-02-28T14:53:58.576688+00"),
), ),
@@ -41,18 +41,6 @@ async fn main() -> Result<(), Box<dyn Error>> {
Some("2025-01-29T05:39:28.562667+00"), Some("2025-01-29T05:39:28.562667+00"),
Some("2025-03-12T22:56:29.597416+00"), Some("2025-03-12T22:56:29.597416+00"),
), ),
(
"aec758fc-3d54-4c6f-8bcb-44368dd81c07",
"Admin Management Soal",
Some("2025-01-29T11:03:40.308934+00"),
Some("2025-01-29T11:03:40.308935+00"),
),
(
"de29943b-ed94-451e-a91f-bcf496bd1849",
"Admin Penilaian",
Some("2025-01-29T11:04:03.499272+00"),
Some("2025-01-29T16:14:09.715234+00"),
),
( (
"f6b03f25-e416-4893-ac88-caaa690afb07", "f6b03f25-e416-4893-ac88-caaa690afb07",
"Admin", "Admin",
+2 -2
View File
@@ -54,8 +54,8 @@ async fn main() -> Result<(), Box<dyn Error>> {
), ),
( (
"d5e89c12-72af-4b1a-abc3-ff1234567890", "d5e89c12-72af-4b1a-abc3-ff1234567890",
"student@example.com", "user@example.com",
"Student", "User",
"5713cb37-dc02-4e87-8048-d7a41d352059", "5713cb37-dc02-4e87-8048-d7a41d352059",
), ),
]; ];