Skip to content

Commit

Permalink
feat: added more api yaml documentation, added handler for create and…
Browse files Browse the repository at this point in the history
… get all roles in a campaign, added get all in roles in a campagin in model
  • Loading branch information
Alex_Miao_WSL committed Jul 18, 2024
1 parent 11e8f01 commit 919c2e5
Show file tree
Hide file tree
Showing 4 changed files with 196 additions and 22 deletions.
145 changes: 139 additions & 6 deletions backend/api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -850,6 +850,7 @@ paths:
example: Chief Mouser
description:
type: string
required: False
example: Larry the cat is dead, now we need someone else to handle the rat issues at 10th Downing st.
min_available:
type: int32
Expand Down Expand Up @@ -880,6 +881,49 @@ paths:
error:
type: string
example: Unauthorized

/campaign/{id}/roles:
get:
operationId: getRolesByCampaignId
parameters:
- name: id
in: path
description: Campaign ID
required: true
schema:
type: integer
format: int64
description: Returns info about all roles in a campaign
tags:
- Campaign
responses:
'200':
description: OK
content:
application/json:
schema:
properties:
campaigns:
type: array
items:
type: object
properties:
name:
type: string
example: Chief Mouser
description:
type: string
example: Larry the cat gone missing! now we need someone else to handle the rat issues at 10th Downing st.
min_available:
type: int32
example: 1
max_available:
type: int32
example: 3
finalised:
type: boolean
description: Whether this role has been finalised (e.g. max avaliable number)
example: False
/role/{id}:
get:
operationId: getRoleById
Expand All @@ -901,12 +945,58 @@ paths:
application/json:
schema:
properties:
name:
type: string
example: Chief Mouser
description:
type: string
example: Larry the cat gone missing! now we need someone else to handle the rat issues at 10th Downing st.
min_available:
type: int32
example: 1
max_available:
type: int32
example: 3
finalised:
type: boolean
description: Whether this role has been finalised (e.g. max avaliable number)
example: False
'401':
description: Not logged in.
content:
application/json:
schema:
properties:
error:
type: string
example: Not logged in.

put:
operationId: updateRoleById
parameters:
- name: id
in: path
description: Role ID
required: true
schema:
type: integer
format: int32
description: Update a role given the role id.
tags:
- Role
requestBody:
required: true
content:
application/json:
schema:
properties:
name:
type: string
example: Chief Mouser
example: Chief Whip
description:
type: string
example: Larry the cat is dead, now we need someone else to handle the rat issues at 10th Downing st.
required: False
example: Put a bit of stick about!
min_available:
type: int32
example: 1
Expand All @@ -916,13 +1006,56 @@ paths:
finalised:
type: boolean
description: Whether this role has been finalised (e.g. max avaliable number)
example: False
'401':
description: Not logged in.
example: true
responses:
'200':
description: OK
content:
application/json:
schema:
properties:
message:
type: string
example: Successfully update organisation.
'403':
description: User is not a Campaign Admin.
content:
application/json:
schema:
properties:
error:
type: string
example: Unauthorized

delete:
operationId: deleteRoleById
parameters:
- name: id
in: path
description: Role ID
required: true
schema:
type: integer
format: int32
description: Deletes specified role.
tags:
- Role
responses:
'200':
description: OK
content:
application/json:
schema:
properties:
message:
type: string
example: Successfully deleted role.
'403':
description: User is not an admin of role's Campaign.
content:
application/json:
schema:
properties:
error:
type: string
example: Not logged in.
example: Unauthorized
27 changes: 20 additions & 7 deletions backend/server/src/handler/role.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
use crate::models;
use crate::models::app::AppState;
use crate::models::auth::SuperUser;
use crate::models::auth::{AuthUser, OrganisationAdmin};
use crate::models::error::ChaosError;
use crate::models::role::{Role, RoleUpdate};
use crate::models::transaction::DBTransaction;
use crate::service;
use axum::extract::{Json, Path, State};
use axum::http::StatusCode;
use axum::response::IntoResponse;

pub struct RoleHandler;

impl RoleHandler {
pub async fn create(
State(state): State<AppState>,
Path(id): Path<i64>,
_admin: OrganisationAdmin,
Json(data): Json<RoleUpdate>,
) -> Result<impl IntoResponse, ChaosError> {
Role::create(id, data, &state.db).await?;
Ok((StatusCode::OK, "Successfully created role"))
}
pub async fn get(
State(state): State<AppState>,
Path(id): Path<i32>,
Expand All @@ -35,11 +40,19 @@ impl RoleHandler {
State(state): State<AppState>,
Path(id): Path<i32>,
_admin: OrganisationAdmin,
mut transaction: DBTransaction<'_>,
Json(data): Json<RoleUpdate>,
) -> Result<impl IntoResponse, ChaosError> {
Role::update(id, data, &mut transaction.tx,).await?;
transaction.tx.commit().await?;
Role::update(id, data, &state.db).await?;
Ok((StatusCode::OK, "Successfully updated role"))
}

pub async fn get_roles(
State(state): State<AppState>,
Path(id): Path<i64>,
_user: AuthUser,
) -> Result<impl IntoResponse, ChaosError> {
let roles = Role::get_all_in_campaign(id, &state.db).await?;

Ok((StatusCode::OK, Json(roles)))
}
}
8 changes: 8 additions & 0 deletions backend/server/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,14 @@ async fn main() -> Result<()> {
.put(OrganisationHandler::update_admins)
.delete(OrganisationHandler::remove_admin),
)
.route(
"/api/v1/campaign/:id/role",
post(RoleHandler::create)
)
.route(
"/api/v1/campaign/:id/roles",
get(RoleHandler::get_roles)
)
.route(
"/api/v1/role/:id",
get(RoleHandler::get)
Expand Down
38 changes: 29 additions & 9 deletions backend/server/src/models/role.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use crate::models::error::ChaosError;
use sqlx::{FromRow, Pool, Postgres, Transaction};
use std::ops::DerefMut;

use super::campaign;
use sqlx::{FromRow, Pool, Postgres};

#[derive(Deserialize, Serialize, Clone, FromRow, Debug)]
pub struct Role {
pub id: i32,
pub campaign_id: i64,
pub name: String,
pub name: Option<String>,
pub description: String,
pub min_available: i32,
pub max_avaliable: i32,
Expand All @@ -37,11 +34,12 @@ pub struct RoleDetails {
pub finalised: bool,
}


impl Role {
pub async fn create(
campaign_id: i64,
role_data: RoleUpdate,
transaction: &mut Transaction<'_, Postgres>,
pool: &Pool<Postgres>
) -> Result<(), ChaosError> {

sqlx::query!(
Expand All @@ -56,7 +54,7 @@ impl Role {
role_data.max_avaliable,
role_data.finalised
)
.execute(transaction.deref_mut())
.fetch_one(pool)
.await?;

Ok(())
Expand Down Expand Up @@ -94,7 +92,7 @@ impl Role {
pub async fn update(
id: i32,
role_data: RoleUpdate,
transaction: &mut Transaction<'_, Postgres>,
pool: &Pool<Postgres>
) -> Result<(), ChaosError> {
sqlx::query!(
"
Expand All @@ -109,11 +107,33 @@ impl Role {
role_data.max_avaliable,
role_data.finalised
)
.execute(transaction.deref_mut())
.fetch_one(pool)
.await?;

Ok(())
}

/*
Given a campaign id, return all existing roles in this campaign
*/
pub async fn get_all_in_campaign(
campaign_id: i64,
pool: &Pool<Postgres>
) -> Result<Vec<RoleDetails>, ChaosError> {
let roles = sqlx::query_as!(
RoleDetails,
"
SELECT name, description, min_available, max_available, finalised
FROM campaign_roles
WHERE campaign_id = $1
",
campaign_id
)
.fetch_all(pool)
.await?;

Ok(roles)
}


}

0 comments on commit 919c2e5

Please sign in to comment.