Something went wrong. Try again.
A simple to-do app focused on tasks that can be completed within a specific time span. taskline.tobinio.dev
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124use axum::{ Json, Router, extract::State, response::{IntoResponse, Response}, routing::{get, post},};use http::StatusCode;use services::{ User, organization::{OrganizationService, OrganizationServiceError},};use thiserror::Error;use tracing::warn;use types::organization::{JoinOrganization, Organization};
use crate::AppState;
#[derive(Error, Debug, PartialEq)]enum ApiError { #[error(transparent)] ServiceError(#[from] OrganizationServiceError),
#[error("organization already exists")] OrganizationAlreadyExists,
#[error("organization does not exists")] OrganizationDoesNotExists,
#[error("organization already exists")] OrganizationAlreadyJoined,
#[error("organization does not exists")] OrganizationNotJoined,}
impl IntoResponse for ApiError { fn into_response(self) -> Response { let status = match &self { ApiError::ServiceError(_) => StatusCode::INTERNAL_SERVER_ERROR, ApiError::OrganizationAlreadyExists | ApiError::OrganizationDoesNotExists | ApiError::OrganizationAlreadyJoined | ApiError::OrganizationNotJoined => StatusCode::BAD_REQUEST, };
warn!("{:?}", self); status.into_response() }}
pub fn routes(state: AppState) -> Router { Router::new() .route("/", get(get_organizations)) .route("/", post(add_organization)) .route("/join", post(join_organization)) .route("/leave", post(leave_organization)) .with_state(state)}
async fn get_organizations( state: State<AppState>, user: User,) -> Result<Json<Vec<Organization>>, ApiError> { let organizations = OrganizationService::get_all(&user, &state.db_connection).await?; Ok(Json(organizations))}
async fn add_organization( state: State<AppState>, user: User, Json(organization): Json<Organization>,) -> Result<Json<Organization>, ApiError> { let org_uuid = organization.uuid;
if OrganizationService::exists(&state.db_connection, org_uuid).await? { return Err(ApiError::OrganizationAlreadyExists); }
let new_organization = OrganizationService::create(&state.db_connection, organization).await?; OrganizationService::join(&user, &state.db_connection, org_uuid).await?;
Ok(Json(new_organization))}
async fn join_organization( state: State<AppState>, user: User, Json(organization): Json<JoinOrganization>,) -> Result<StatusCode, ApiError> { let org_uuid = organization.uuid;
if !OrganizationService::exists(&state.db_connection, org_uuid).await? { return Err(ApiError::OrganizationDoesNotExists); }
if OrganizationService::joined(&user, &state.db_connection, org_uuid).await? { return Err(ApiError::OrganizationAlreadyJoined); }
OrganizationService::join(&user, &state.db_connection, organization.uuid).await?;
Ok(StatusCode::OK)}
async fn leave_organization( state: State<AppState>, user: User, Json(organization): Json<JoinOrganization>,) -> Result<StatusCode, ApiError> { let org_uuid = organization.uuid;
if !OrganizationService::exists(&state.db_connection, org_uuid).await? { return Err(ApiError::OrganizationDoesNotExists); }
if !OrganizationService::joined(&user, &state.db_connection, org_uuid).await? { return Err(ApiError::OrganizationNotJoined); }
OrganizationService::leave(&user, &state.db_connection, organization.uuid).await?;
Ok(StatusCode::OK)}