added vibecoded swagger documentation with utoipa
This commit is contained in:
+176
-6
@@ -10,10 +10,11 @@ use uuid::Uuid;
|
||||
use crate::{MAX_ROOM_NAME_LENGTH, auth::verify_jwt, db::room_id_from_uuid, errors::APIError};
|
||||
use crate::{
|
||||
db::{id_from_username, room_name_from_uuid, user_id_from_uuid, username_from_id},
|
||||
errors::ErrorResponse,
|
||||
routes::users::UserProfile,
|
||||
};
|
||||
|
||||
#[derive(sqlx::FromRow, serde::Serialize, serde::Deserialize)]
|
||||
#[derive(sqlx::FromRow, serde::Serialize, serde::Deserialize, utoipa::ToSchema)]
|
||||
pub struct Room {
|
||||
pub uuid: Uuid,
|
||||
pub name: String,
|
||||
@@ -23,13 +24,13 @@ pub struct Room {
|
||||
pub unread_count: i64,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize)]
|
||||
#[derive(serde::Deserialize, utoipa::ToSchema)]
|
||||
pub struct NewRoomPayload {
|
||||
pub name: String,
|
||||
pub global: bool,
|
||||
}
|
||||
|
||||
#[derive(sqlx::FromRow, serde::Serialize)]
|
||||
#[derive(sqlx::FromRow, serde::Serialize, utoipa::ToSchema)]
|
||||
pub struct RoomInvite {
|
||||
pub room_uuid: Uuid,
|
||||
pub room_name: String,
|
||||
@@ -37,19 +38,19 @@ pub struct RoomInvite {
|
||||
pub sender_username: String,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize)]
|
||||
#[derive(serde::Deserialize, utoipa::ToSchema)]
|
||||
pub struct SendRoomInvitePayload {
|
||||
pub room_uuid: Uuid,
|
||||
pub receiver_username: String,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize)]
|
||||
#[derive(serde::Deserialize, utoipa::ToSchema)]
|
||||
pub struct AcceptRoomInvitePayload {
|
||||
pub room_uuid: Uuid,
|
||||
pub sender_uuid: Uuid,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize)]
|
||||
#[derive(serde::Deserialize, utoipa::ToSchema)]
|
||||
pub struct TransferOwnershipPayload {
|
||||
pub room_uuid: Uuid,
|
||||
pub new_owner_uuid: Uuid,
|
||||
@@ -90,6 +91,19 @@ pub async fn is_member(user_id: i32, room_id: i32, db: &Pool<Postgres>) -> bool
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/rooms",
|
||||
responses(
|
||||
(status = 200, description = "Successfully listed rooms", body = [Room]),
|
||||
(status = 401, description = "Missing authentication header or Invalid or expired token", body = ErrorResponse),
|
||||
(status = 404, description = "User not found", body = ErrorResponse),
|
||||
(status = 500, description = "Database error", body = ErrorResponse)
|
||||
),
|
||||
security(
|
||||
("bearer_auth" = [])
|
||||
)
|
||||
)]
|
||||
async fn list_rooms(
|
||||
headers: HeaderMap,
|
||||
Extension(db): Extension<PgPool>,
|
||||
@@ -130,6 +144,21 @@ async fn list_rooms(
|
||||
Ok(Json(rooms))
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
post,
|
||||
path = "/rooms",
|
||||
request_body = NewRoomPayload,
|
||||
responses(
|
||||
(status = 201, description = "Room successfully created", body = Room),
|
||||
(status = 400, description = "Room name must be 0-35 characters long", body = ErrorResponse),
|
||||
(status = 401, description = "Missing authentication header or Invalid or expired token", body = ErrorResponse),
|
||||
(status = 404, description = "User not found or Room not found", body = ErrorResponse),
|
||||
(status = 500, description = "Database error", body = ErrorResponse)
|
||||
),
|
||||
security(
|
||||
("bearer_auth" = [])
|
||||
)
|
||||
)]
|
||||
async fn create_room(
|
||||
Extension(db): Extension<PgPool>,
|
||||
headers: HeaderMap,
|
||||
@@ -184,6 +213,23 @@ async fn create_room(
|
||||
))
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/rooms/{room_uuid}",
|
||||
params(
|
||||
("room_uuid" = Uuid, Path, description = "UUID of the room to retrieve")
|
||||
),
|
||||
responses(
|
||||
(status = 200, description = "Room successfully retrieved", body = Room),
|
||||
(status = 401, description = "Missing authentication header or Invalid or expired token", body = ErrorResponse),
|
||||
(status = 403, description = "You are not a member of this room", body = ErrorResponse),
|
||||
(status = 404, description = "User not found or Room not found", body = ErrorResponse),
|
||||
(status = 500, description = "Database error", body = ErrorResponse)
|
||||
),
|
||||
security(
|
||||
("bearer_auth" = [])
|
||||
)
|
||||
)]
|
||||
async fn get_room(
|
||||
Path(room_uuid): Path<Uuid>,
|
||||
headers: HeaderMap,
|
||||
@@ -246,6 +292,19 @@ async fn get_room(
|
||||
}))
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/rooms/invites",
|
||||
responses(
|
||||
(status = 200, description = "List of room invites successfully retrieved", body = [RoomInvite]),
|
||||
(status = 401, description = "Missing authentication header or Invalid or expired token", body = ErrorResponse),
|
||||
(status = 404, description = "User not found", body = ErrorResponse),
|
||||
(status = 500, description = "Database error", body = ErrorResponse)
|
||||
),
|
||||
security(
|
||||
("bearer_auth" = [])
|
||||
)
|
||||
)]
|
||||
async fn list_invites(
|
||||
headers: HeaderMap,
|
||||
Extension(db): Extension<PgPool>,
|
||||
@@ -273,6 +332,22 @@ async fn list_invites(
|
||||
Ok(Json(requests))
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
post,
|
||||
path = "/rooms/invite",
|
||||
request_body = SendRoomInvitePayload,
|
||||
responses(
|
||||
(status = 201, description = "Room invite successfully sent", body = RoomInvite),
|
||||
(status = 400, description = "Cannot invite yourself", body = ErrorResponse),
|
||||
(status = 401, description = "Missing authentication header or Invalid or expired token", body = ErrorResponse),
|
||||
(status = 404, description = "User not found or Room not found", body = ErrorResponse),
|
||||
(status = 409, description = "User is already a member or Invite already sent", body = ErrorResponse),
|
||||
(status = 500, description = "Database error", body = ErrorResponse)
|
||||
),
|
||||
security(
|
||||
("bearer_auth" = [])
|
||||
)
|
||||
)]
|
||||
async fn send_invite(
|
||||
headers: HeaderMap,
|
||||
Extension(db): Extension<PgPool>,
|
||||
@@ -327,6 +402,21 @@ async fn send_invite(
|
||||
))
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
post,
|
||||
path = "/rooms/join",
|
||||
request_body = AcceptRoomInvitePayload,
|
||||
responses(
|
||||
(status = 201, description = "Room invite successfully accepted", body = Room),
|
||||
(status = 401, description = "Missing authentication header or Invalid or expired token", body = ErrorResponse),
|
||||
(status = 404, description = "User not found, Room not found, or Invite not found", body = ErrorResponse),
|
||||
(status = 409, description = "User is already a member", body = ErrorResponse),
|
||||
(status = 500, description = "Database error", body = ErrorResponse)
|
||||
),
|
||||
security(
|
||||
("bearer_auth" = [])
|
||||
)
|
||||
)]
|
||||
async fn accept_request(
|
||||
headers: HeaderMap,
|
||||
Extension(db): Extension<PgPool>,
|
||||
@@ -399,6 +489,20 @@ async fn accept_request(
|
||||
))
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
post,
|
||||
path = "/rooms/decline",
|
||||
request_body = AcceptRoomInvitePayload,
|
||||
responses(
|
||||
(status = 201, description = "Room invite successfully declined"),
|
||||
(status = 401, description = "Missing authentication header or Invalid or expired token", body = ErrorResponse),
|
||||
(status = 404, description = "User not found or Invite not found", body = ErrorResponse),
|
||||
(status = 500, description = "Database error", body = ErrorResponse)
|
||||
),
|
||||
security(
|
||||
("bearer_auth" = [])
|
||||
)
|
||||
)]
|
||||
async fn decline_request(
|
||||
headers: HeaderMap,
|
||||
Extension(db): Extension<PgPool>,
|
||||
@@ -428,6 +532,23 @@ async fn decline_request(
|
||||
Ok(StatusCode::CREATED)
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
post,
|
||||
path = "/rooms/{room_uuid}/leave",
|
||||
params(
|
||||
("room_uuid" = Uuid, Path, description = "UUID of the room to leave")
|
||||
),
|
||||
responses(
|
||||
(status = 200, description = "Successfully left the room"),
|
||||
(status = 401, description = "Missing authentication header or Invalid or expired token", body = ErrorResponse),
|
||||
(status = 403, description = "You are not a member of this room or Owner cannot leave the room without transferring ownership", body = ErrorResponse),
|
||||
(status = 404, description = "User not found or Room not found", body = ErrorResponse),
|
||||
(status = 500, description = "Database error", body = ErrorResponse)
|
||||
),
|
||||
security(
|
||||
("bearer_auth" = [])
|
||||
)
|
||||
)]
|
||||
async fn leave_room(
|
||||
headers: HeaderMap,
|
||||
Path(room_uuid): Path<Uuid>,
|
||||
@@ -469,6 +590,21 @@ async fn leave_room(
|
||||
Ok(StatusCode::OK)
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
post,
|
||||
path = "/rooms/transfer-ownership",
|
||||
request_body = TransferOwnershipPayload,
|
||||
responses(
|
||||
(status = 200, description = "Room ownership successfully transferred"),
|
||||
(status = 401, description = "Missing authentication header or Invalid or expired token", body = ErrorResponse),
|
||||
(status = 403, description = "You are not a member of this room", body = ErrorResponse),
|
||||
(status = 404, description = "User not found or Room not found", body = ErrorResponse),
|
||||
(status = 500, description = "Database error", body = ErrorResponse)
|
||||
),
|
||||
security(
|
||||
("bearer_auth" = [])
|
||||
)
|
||||
)]
|
||||
async fn transfer_ownership(
|
||||
headers: HeaderMap,
|
||||
Extension(db): Extension<PgPool>,
|
||||
@@ -515,6 +651,23 @@ async fn transfer_ownership(
|
||||
Ok(StatusCode::OK)
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/rooms/{room_uuid}/members",
|
||||
params(
|
||||
("room_uuid" = Uuid, Path, description = "UUID of the room to list members of")
|
||||
),
|
||||
responses(
|
||||
(status = 200, description = "Room members successfully retrieved", body = [UserProfile]),
|
||||
(status = 401, description = "Missing authentication header or Invalid or expired token", body = ErrorResponse),
|
||||
(status = 403, description = "You are not a member of this room or Cannot list members for global rooms", body = ErrorResponse),
|
||||
(status = 404, description = "User not found or Room not found", body = ErrorResponse),
|
||||
(status = 500, description = "Database error", body = ErrorResponse)
|
||||
),
|
||||
security(
|
||||
("bearer_auth" = [])
|
||||
)
|
||||
)]
|
||||
async fn list_members(
|
||||
headers: HeaderMap,
|
||||
Path(room_uuid): Path<Uuid>,
|
||||
@@ -554,6 +707,23 @@ async fn list_members(
|
||||
Ok((StatusCode::OK, Json(members)))
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
delete,
|
||||
path = "/rooms/{room_uuid}/delete",
|
||||
params(
|
||||
("room_uuid" = Uuid, Path, description = "UUID of the room to delete")
|
||||
),
|
||||
responses(
|
||||
(status = 200, description = "Room successfully deleted"),
|
||||
(status = 401, description = "Missing authentication header or Invalid or expired token", body = ErrorResponse),
|
||||
(status = 403, description = "You are not a member of this room", body = ErrorResponse),
|
||||
(status = 404, description = "User not found or Room not found", body = ErrorResponse),
|
||||
(status = 500, description = "Database error", body = ErrorResponse)
|
||||
),
|
||||
security(
|
||||
("bearer_auth" = [])
|
||||
)
|
||||
)]
|
||||
async fn delete_room(
|
||||
headers: HeaderMap,
|
||||
Path(room_uuid): Path<Uuid>,
|
||||
|
||||
Reference in New Issue
Block a user