feat: add utoipa path annotations to hackathon and QR handlers, register in swagger

All hackathon endpoints (/v1/hackathon/*) and QR endpoints (/v1/qr/*)
are now visible in the Swagger UI at /docs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
maulanasdqn
2026-04-03 01:22:38 +07:00
co-authored by Claude Sonnet 4.6
parent 8144ab40e9
commit e1bc336baa
15 changed files with 722 additions and 3 deletions
@@ -1,8 +1,8 @@
use serde::{Deserialize, Serialize};
use utoipa::ToSchema;
use utoipa::{IntoParams, ToSchema};
use uuid::Uuid;
#[derive(Deserialize)]
#[derive(Deserialize, IntoParams)]
pub struct PageQuery {
#[serde(default = "default_page")]
pub page: i64,
@@ -12,6 +12,18 @@ use imphnen_utils::{
use std::sync::Arc;
use uuid::Uuid;
#[utoipa::path(
get,
path = "/v1/hackathon/admin/users",
params(PageQuery),
responses(
(status = 200, description = "Admin: list all users"),
(status = 401, description = "Unauthorized"),
(status = 403, description = "Forbidden - admin only")
),
tag = "Hackathon - Admin",
security(("bearer_auth" = []))
)]
pub async fn admin_list_users(
Extension(service): Extension<Arc<dyn AdminService>>,
Query(q): Query<PageQuery>,
@@ -28,6 +40,18 @@ pub async fn admin_list_users(
)
}
#[utoipa::path(
get,
path = "/v1/hackathon/admin/users/{user_id}",
params(("user_id" = Uuid, Path, description = "User ID")),
responses(
(status = 200, description = "Admin: get user by ID"),
(status = 403, description = "Forbidden - admin only"),
(status = 404, description = "User not found")
),
tag = "Hackathon - Admin",
security(("bearer_auth" = []))
)]
pub async fn admin_get_user(
Extension(service): Extension<Arc<dyn AdminService>>,
Path(user_id): Path<Uuid>,
@@ -36,6 +60,18 @@ pub async fn admin_get_user(
Ok(ApiSuccess(user).into_response())
}
#[utoipa::path(
post,
path = "/v1/hackathon/admin/users/{user_id}/set-admin",
params(("user_id" = Uuid, Path, description = "User ID")),
request_body = SetAdminRequest,
responses(
(status = 200, description = "Admin: set user admin status"),
(status = 403, description = "Forbidden - admin only")
),
tag = "Hackathon - Admin",
security(("bearer_auth" = []))
)]
pub async fn admin_set_admin(
Extension(service): Extension<Arc<dyn AdminService>>,
Path(user_id): Path<Uuid>,
@@ -45,6 +81,17 @@ pub async fn admin_set_admin(
Ok(ApiMessage::ok("User admin status updated"))
}
#[utoipa::path(
delete,
path = "/v1/hackathon/admin/users/{user_id}",
params(("user_id" = Uuid, Path, description = "User ID")),
responses(
(status = 200, description = "Admin: delete user"),
(status = 403, description = "Forbidden - admin only")
),
tag = "Hackathon - Admin",
security(("bearer_auth" = []))
)]
pub async fn admin_delete_user(
Extension(service): Extension<Arc<dyn AdminService>>,
Path(user_id): Path<Uuid>,
@@ -53,6 +100,17 @@ pub async fn admin_delete_user(
Ok(ApiMessage::ok("User deleted"))
}
#[utoipa::path(
get,
path = "/v1/hackathon/admin/teams",
params(PageQuery),
responses(
(status = 200, description = "Admin: list all teams"),
(status = 403, description = "Forbidden - admin only")
),
tag = "Hackathon - Admin",
security(("bearer_auth" = []))
)]
pub async fn admin_list_teams(
Extension(service): Extension<Arc<dyn AdminService>>,
Query(q): Query<PageQuery>,
@@ -69,6 +127,17 @@ pub async fn admin_list_teams(
)
}
#[utoipa::path(
delete,
path = "/v1/hackathon/admin/teams/{team_id}",
params(("team_id" = Uuid, Path, description = "Team ID")),
responses(
(status = 200, description = "Admin: delete team"),
(status = 403, description = "Forbidden - admin only")
),
tag = "Hackathon - Admin",
security(("bearer_auth" = []))
)]
pub async fn admin_delete_team(
Extension(service): Extension<Arc<dyn AdminService>>,
Path(team_id): Path<Uuid>,
@@ -77,6 +146,17 @@ pub async fn admin_delete_team(
Ok(ApiMessage::ok("Team deleted"))
}
#[utoipa::path(
get,
path = "/v1/hackathon/admin/submissions",
params(PageQuery),
responses(
(status = 200, description = "Admin: list all submissions"),
(status = 403, description = "Forbidden - admin only")
),
tag = "Hackathon - Admin",
security(("bearer_auth" = []))
)]
pub async fn admin_list_submissions(
Extension(service): Extension<Arc<dyn AdminService>>,
Query(q): Query<PageQuery>,
@@ -93,6 +173,17 @@ pub async fn admin_list_submissions(
)
}
#[utoipa::path(
post,
path = "/v1/hackathon/admin/winners",
request_body = SetWinnerRequest,
responses(
(status = 200, description = "Admin: set winner"),
(status = 403, description = "Forbidden - admin only")
),
tag = "Hackathon - Admin",
security(("bearer_auth" = []))
)]
pub async fn admin_set_winner(
Extension(service): Extension<Arc<dyn AdminService>>,
Json(body): Json<SetWinnerRequest>,
@@ -103,6 +194,17 @@ pub async fn admin_set_winner(
Ok(ApiMessage::ok("Winner set"))
}
#[utoipa::path(
delete,
path = "/v1/hackathon/admin/winners/{team_id}",
params(("team_id" = Uuid, Path, description = "Team ID")),
responses(
(status = 200, description = "Admin: remove winner"),
(status = 403, description = "Forbidden - admin only")
),
tag = "Hackathon - Admin",
security(("bearer_auth" = []))
)]
pub async fn admin_remove_winner(
Extension(service): Extension<Arc<dyn AdminService>>,
Path(team_id): Path<Uuid>,
@@ -111,6 +213,16 @@ pub async fn admin_remove_winner(
Ok(ApiMessage::ok("Winner removed"))
}
#[utoipa::path(
get,
path = "/v1/hackathon/admin/winners",
responses(
(status = 200, description = "Admin: list winners"),
(status = 403, description = "Forbidden - admin only")
),
tag = "Hackathon - Admin",
security(("bearer_auth" = []))
)]
pub async fn admin_list_winners(
Extension(service): Extension<Arc<dyn AdminService>>,
) -> Result<axum::response::Response, AppError> {
@@ -5,6 +5,16 @@ use imphnen_utils::{errors::AppError, response_format::ApiSuccess};
use std::sync::Arc;
use uuid::Uuid;
#[utoipa::path(
get,
path = "/v1/hackathon/certificates/{user_id}",
params(("user_id" = Uuid, Path, description = "User ID")),
responses(
(status = 200, description = "Get certificate for user"),
(status = 404, description = "Certificate not found")
),
tag = "Hackathon - Certificates"
)]
pub async fn get_certificate_handler(
Extension(service): Extension<Arc<dyn CertificateService>>,
Path(user_id): Path<Uuid>,
@@ -9,6 +9,17 @@ use imphnen_utils::{
use std::sync::Arc;
use uuid::Uuid;
#[utoipa::path(
get,
path = "/v1/hackathon/chat/teams/{team_id}",
params(("team_id" = Uuid, Path, description = "Team ID")),
responses(
(status = 200, description = "Get team chat messages"),
(status = 401, description = "Unauthorized")
),
tag = "Hackathon - Chat",
security(("bearer_auth" = []))
)]
pub async fn get_team_messages_handler(
Extension(service): Extension<Arc<dyn ChatService>>,
Extension(auth): Extension<HackathonAuthUser>,
@@ -20,6 +31,18 @@ pub async fn get_team_messages_handler(
Ok(ApiSuccess(response).into_response())
}
#[utoipa::path(
post,
path = "/v1/hackathon/chat/teams/{team_id}",
params(("team_id" = Uuid, Path, description = "Team ID")),
request_body = SendMessageRequest,
responses(
(status = 200, description = "Send a message to team chat"),
(status = 401, description = "Unauthorized")
),
tag = "Hackathon - Chat",
security(("bearer_auth" = []))
)]
pub async fn send_message_handler(
Extension(service): Extension<Arc<dyn ChatService>>,
Extension(auth): Extension<HackathonAuthUser>,
@@ -32,6 +55,18 @@ pub async fn send_message_handler(
Ok(ApiSuccess(MessageResponse::from(message)).into_response())
}
#[utoipa::path(
delete,
path = "/v1/hackathon/chat/messages/{message_id}",
params(("message_id" = Uuid, Path, description = "Message ID")),
responses(
(status = 200, description = "Delete a chat message"),
(status = 401, description = "Unauthorized"),
(status = 403, description = "Forbidden")
),
tag = "Hackathon - Chat",
security(("bearer_auth" = []))
)]
pub async fn delete_message_handler(
Extension(service): Extension<Arc<dyn ChatService>>,
Extension(auth): Extension<HackathonAuthUser>,
@@ -9,6 +9,16 @@ use imphnen_utils::{
use std::sync::Arc;
use uuid::Uuid;
#[utoipa::path(
get,
path = "/v1/hackathon/invitations/my",
responses(
(status = 200, description = "Get my invitations"),
(status = 401, description = "Unauthorized")
),
tag = "Hackathon - Invitations",
security(("bearer_auth" = []))
)]
pub async fn get_my_invitations_handler(
Extension(service): Extension<Arc<dyn InvitationService>>,
Extension(auth): Extension<HackathonAuthUser>,
@@ -19,6 +29,19 @@ pub async fn get_my_invitations_handler(
Ok(ApiSuccess(response).into_response())
}
#[utoipa::path(
post,
path = "/v1/hackathon/invitations/{invitation_id}/respond",
params(("invitation_id" = Uuid, Path, description = "Invitation ID")),
request_body = RespondToInvitationRequest,
responses(
(status = 200, description = "Respond to invitation"),
(status = 401, description = "Unauthorized"),
(status = 404, description = "Invitation not found")
),
tag = "Hackathon - Invitations",
security(("bearer_auth" = []))
)]
pub async fn respond_to_invitation_handler(
Extension(service): Extension<Arc<dyn InvitationService>>,
Extension(auth): Extension<HackathonAuthUser>,
@@ -36,6 +59,19 @@ pub async fn respond_to_invitation_handler(
Ok(ApiMessage::ok(msg).into_response())
}
#[utoipa::path(
post,
path = "/v1/hackathon/invitations/teams/{team_id}/invite",
params(("team_id" = Uuid, Path, description = "Team ID")),
request_body = CreateInvitationRequest,
responses(
(status = 200, description = "Invite a member to team"),
(status = 401, description = "Unauthorized"),
(status = 403, description = "Forbidden")
),
tag = "Hackathon - Invitations",
security(("bearer_auth" = []))
)]
pub async fn invite_team_member_handler(
Extension(service): Extension<Arc<dyn InvitationService>>,
Extension(auth): Extension<HackathonAuthUser>,
@@ -9,6 +9,18 @@ use imphnen_utils::{
use std::sync::Arc;
use uuid::Uuid;
#[utoipa::path(
post,
path = "/v1/hackathon/join-requests/teams/{team_id}",
params(("team_id" = Uuid, Path, description = "Team ID")),
request_body = CreateJoinRequestRequest,
responses(
(status = 200, description = "Create a join request"),
(status = 401, description = "Unauthorized")
),
tag = "Hackathon - Join Requests",
security(("bearer_auth" = []))
)]
pub async fn create_join_request_handler(
Extension(service): Extension<Arc<dyn JoinRequestService>>,
Extension(auth): Extension<HackathonAuthUser>,
@@ -21,6 +33,16 @@ pub async fn create_join_request_handler(
Ok(ApiSuccess(JoinRequestResponse::from(request)).into_response())
}
#[utoipa::path(
get,
path = "/v1/hackathon/join-requests/my",
responses(
(status = 200, description = "Get my join requests"),
(status = 401, description = "Unauthorized")
),
tag = "Hackathon - Join Requests",
security(("bearer_auth" = []))
)]
pub async fn get_my_join_requests_handler(
Extension(service): Extension<Arc<dyn JoinRequestService>>,
Extension(auth): Extension<HackathonAuthUser>,
@@ -31,6 +53,18 @@ pub async fn get_my_join_requests_handler(
Ok(ApiSuccess(response).into_response())
}
#[utoipa::path(
get,
path = "/v1/hackathon/join-requests/teams/{team_id}/pending",
params(("team_id" = Uuid, Path, description = "Team ID")),
responses(
(status = 200, description = "Get pending join requests for team"),
(status = 401, description = "Unauthorized"),
(status = 403, description = "Forbidden")
),
tag = "Hackathon - Join Requests",
security(("bearer_auth" = []))
)]
pub async fn get_team_join_requests_handler(
Extension(service): Extension<Arc<dyn JoinRequestService>>,
Extension(auth): Extension<HackathonAuthUser>,
@@ -44,6 +78,19 @@ pub async fn get_team_join_requests_handler(
Ok(ApiSuccess(response).into_response())
}
#[utoipa::path(
post,
path = "/v1/hackathon/join-requests/{request_id}/respond",
params(("request_id" = Uuid, Path, description = "Join request ID")),
request_body = RespondToJoinRequestRequest,
responses(
(status = 200, description = "Respond to join request"),
(status = 401, description = "Unauthorized"),
(status = 403, description = "Forbidden")
),
tag = "Hackathon - Join Requests",
security(("bearer_auth" = []))
)]
pub async fn respond_to_join_request_handler(
Extension(service): Extension<Arc<dyn JoinRequestService>>,
Extension(auth): Extension<HackathonAuthUser>,
@@ -5,6 +5,17 @@ use axum::{Extension, Json, response::IntoResponse};
use imphnen_utils::{errors::AppError, response_format::ApiSuccess};
use std::sync::Arc;
#[utoipa::path(
post,
path = "/v1/hackathon/upload",
request_body = UploadRequest,
responses(
(status = 200, description = "Upload a file"),
(status = 401, description = "Unauthorized")
),
tag = "Hackathon - Storage",
security(("bearer_auth" = []))
)]
pub async fn upload_file_handler(
Extension(service): Extension<Arc<dyn StorageService>>,
Extension(auth): Extension<HackathonAuthUser>,
@@ -22,6 +33,17 @@ pub async fn upload_file_handler(
Ok(ApiSuccess(UploadResponse { url }).into_response())
}
#[utoipa::path(
post,
path = "/v1/hackathon/upload/avatar",
request_body = UploadRequest,
responses(
(status = 200, description = "Upload avatar image"),
(status = 401, description = "Unauthorized")
),
tag = "Hackathon - Storage",
security(("bearer_auth" = []))
)]
pub async fn upload_avatar_handler(
Extension(service): Extension<Arc<dyn StorageService>>,
Extension(auth): Extension<HackathonAuthUser>,
@@ -39,6 +61,17 @@ pub async fn upload_avatar_handler(
Ok(ApiSuccess(UploadResponse { url }).into_response())
}
#[utoipa::path(
post,
path = "/v1/hackathon/upload/team",
request_body = UploadRequest,
responses(
(status = 200, description = "Upload team image"),
(status = 401, description = "Unauthorized")
),
tag = "Hackathon - Storage",
security(("bearer_auth" = []))
)]
pub async fn upload_team_handler(
Extension(service): Extension<Arc<dyn StorageService>>,
Extension(auth): Extension<HackathonAuthUser>,
@@ -56,6 +89,17 @@ pub async fn upload_team_handler(
Ok(ApiSuccess(UploadResponse { url }).into_response())
}
#[utoipa::path(
post,
path = "/v1/hackathon/upload/submission",
request_body = UploadRequest,
responses(
(status = 200, description = "Upload submission file"),
(status = 401, description = "Unauthorized")
),
tag = "Hackathon - Storage",
security(("bearer_auth" = []))
)]
pub async fn upload_submission_handler(
Extension(service): Extension<Arc<dyn StorageService>>,
Extension(auth): Extension<HackathonAuthUser>,
@@ -6,6 +6,18 @@ use imphnen_utils::{errors::AppError, response_format::ApiSuccess};
use std::sync::Arc;
use uuid::Uuid;
#[utoipa::path(
post,
path = "/v1/hackathon/submissions/teams/{team_id}",
params(("team_id" = Uuid, Path, description = "Team ID")),
request_body = CreateSubmissionRequest,
responses(
(status = 200, description = "Create submission for team"),
(status = 401, description = "Unauthorized")
),
tag = "Hackathon - Submissions",
security(("bearer_auth" = []))
)]
pub async fn create_submission_handler(
Extension(service): Extension<Arc<dyn SubmissionService>>,
Extension(auth): Extension<HackathonAuthUser>,
@@ -18,6 +30,18 @@ pub async fn create_submission_handler(
Ok(ApiSuccess(SubmissionResponse::from(sub)).into_response())
}
#[utoipa::path(
get,
path = "/v1/hackathon/submissions/teams/{team_id}",
params(("team_id" = Uuid, Path, description = "Team ID")),
responses(
(status = 200, description = "Get team submission"),
(status = 401, description = "Unauthorized"),
(status = 404, description = "Not found")
),
tag = "Hackathon - Submissions",
security(("bearer_auth" = []))
)]
pub async fn get_team_submission_handler(
Extension(service): Extension<Arc<dyn SubmissionService>>,
Extension(auth): Extension<HackathonAuthUser>,
@@ -27,6 +51,18 @@ pub async fn get_team_submission_handler(
Ok(ApiSuccess(SubmissionResponse::from(sub)).into_response())
}
#[utoipa::path(
put,
path = "/v1/hackathon/submissions/{submission_id}",
params(("submission_id" = Uuid, Path, description = "Submission ID")),
request_body = UpdateSubmissionRequest,
responses(
(status = 200, description = "Update submission"),
(status = 401, description = "Unauthorized")
),
tag = "Hackathon - Submissions",
security(("bearer_auth" = []))
)]
pub async fn update_submission_handler(
Extension(service): Extension<Arc<dyn SubmissionService>>,
Extension(auth): Extension<HackathonAuthUser>,
@@ -39,6 +75,17 @@ pub async fn update_submission_handler(
Ok(ApiSuccess(SubmissionResponse::from(sub)).into_response())
}
#[utoipa::path(
post,
path = "/v1/hackathon/submissions/{submission_id}/submit",
params(("submission_id" = Uuid, Path, description = "Submission ID")),
responses(
(status = 200, description = "Submit project"),
(status = 401, description = "Unauthorized")
),
tag = "Hackathon - Submissions",
security(("bearer_auth" = []))
)]
pub async fn submit_project_handler(
Extension(service): Extension<Arc<dyn SubmissionService>>,
Extension(auth): Extension<HackathonAuthUser>,
@@ -48,6 +95,17 @@ pub async fn submit_project_handler(
Ok(ApiSuccess(SubmissionResponse::from(sub)).into_response())
}
#[utoipa::path(
post,
path = "/v1/hackathon/submissions/{submission_id}/confirm",
params(("submission_id" = Uuid, Path, description = "Submission ID")),
responses(
(status = 200, description = "Confirm submission"),
(status = 401, description = "Unauthorized")
),
tag = "Hackathon - Submissions",
security(("bearer_auth" = []))
)]
pub async fn confirm_submission_handler(
Extension(service): Extension<Arc<dyn SubmissionService>>,
Extension(auth): Extension<HackathonAuthUser>,
@@ -59,6 +117,17 @@ pub async fn confirm_submission_handler(
Ok(ApiSuccess(SubmissionResponse::from(sub)).into_response())
}
#[utoipa::path(
post,
path = "/v1/hackathon/submissions/{submission_id}/cancel",
params(("submission_id" = Uuid, Path, description = "Submission ID")),
responses(
(status = 200, description = "Cancel submission"),
(status = 401, description = "Unauthorized")
),
tag = "Hackathon - Submissions",
security(("bearer_auth" = []))
)]
pub async fn cancel_submission_handler(
Extension(service): Extension<Arc<dyn SubmissionService>>,
Extension(auth): Extension<HackathonAuthUser>,
@@ -145,7 +145,7 @@ impl From<UpdateTeamRequest> for UpdateTeamInput {
}
}
#[derive(Debug, Deserialize, ToSchema)]
#[derive(Debug, Deserialize, ToSchema, utoipa::IntoParams)]
pub struct BrowseTeamsQuery {
pub search: Option<String>,
pub city: Option<String>,
@@ -13,6 +13,17 @@ use imphnen_utils::{
use std::sync::Arc;
use uuid::Uuid;
#[utoipa::path(
post,
path = "/v1/hackathon/teams",
request_body = CreateTeamRequest,
responses(
(status = 200, description = "Create a new team"),
(status = 401, description = "Unauthorized")
),
tag = "Hackathon - Teams",
security(("bearer_auth" = []))
)]
pub async fn create_team_handler(
Extension(service): Extension<Arc<dyn TeamService>>,
Extension(auth): Extension<HackathonAuthUser>,
@@ -22,6 +33,16 @@ pub async fn create_team_handler(
Ok(ApiSuccess(TeamResponse::from(team)).into_response())
}
#[utoipa::path(
get,
path = "/v1/hackathon/teams/{team_id}",
params(("team_id" = Uuid, Path, description = "Team ID")),
responses(
(status = 200, description = "Get team by ID"),
(status = 404, description = "Team not found")
),
tag = "Hackathon - Teams"
)]
pub async fn get_team_handler(
Extension(service): Extension<Arc<dyn TeamService>>,
Path(team_id): Path<Uuid>,
@@ -30,6 +51,15 @@ pub async fn get_team_handler(
Ok(ApiSuccess(TeamResponse::from(team)).into_response())
}
#[utoipa::path(
get,
path = "/v1/hackathon/teams/browse",
params(BrowseTeamsQuery),
responses(
(status = 200, description = "Browse teams with filters")
),
tag = "Hackathon - Teams"
)]
pub async fn browse_teams_handler(
Extension(service): Extension<Arc<dyn TeamService>>,
Query(query): Query<BrowseTeamsQuery>,
@@ -46,6 +76,16 @@ pub async fn browse_teams_handler(
)
}
#[utoipa::path(
get,
path = "/v1/hackathon/teams/my",
responses(
(status = 200, description = "Get my teams"),
(status = 401, description = "Unauthorized")
),
tag = "Hackathon - Teams",
security(("bearer_auth" = []))
)]
pub async fn get_my_teams_handler(
Extension(service): Extension<Arc<dyn TeamService>>,
Extension(auth): Extension<HackathonAuthUser>,
@@ -62,6 +102,19 @@ pub async fn get_my_teams_handler(
)
}
#[utoipa::path(
put,
path = "/v1/hackathon/teams/{team_id}",
params(("team_id" = Uuid, Path, description = "Team ID")),
request_body = UpdateTeamRequest,
responses(
(status = 200, description = "Update team"),
(status = 401, description = "Unauthorized"),
(status = 403, description = "Forbidden")
),
tag = "Hackathon - Teams",
security(("bearer_auth" = []))
)]
pub async fn update_team_handler(
Extension(service): Extension<Arc<dyn TeamService>>,
Extension(auth): Extension<HackathonAuthUser>,
@@ -74,6 +127,18 @@ pub async fn update_team_handler(
Ok(ApiSuccess(TeamResponse::from(team)).into_response())
}
#[utoipa::path(
delete,
path = "/v1/hackathon/teams/{team_id}",
params(("team_id" = Uuid, Path, description = "Team ID")),
responses(
(status = 200, description = "Delete team"),
(status = 401, description = "Unauthorized"),
(status = 403, description = "Forbidden")
),
tag = "Hackathon - Teams",
security(("bearer_auth" = []))
)]
pub async fn delete_team_handler(
Extension(service): Extension<Arc<dyn TeamService>>,
Extension(auth): Extension<HackathonAuthUser>,
@@ -83,6 +148,17 @@ pub async fn delete_team_handler(
Ok(ApiMessage::ok("Team deleted successfully").into_response())
}
#[utoipa::path(
post,
path = "/v1/hackathon/teams/{team_id}/leave",
params(("team_id" = Uuid, Path, description = "Team ID")),
responses(
(status = 200, description = "Leave team"),
(status = 401, description = "Unauthorized")
),
tag = "Hackathon - Teams",
security(("bearer_auth" = []))
)]
pub async fn leave_team_handler(
Extension(service): Extension<Arc<dyn TeamService>>,
Extension(auth): Extension<HackathonAuthUser>,
@@ -92,6 +168,21 @@ pub async fn leave_team_handler(
Ok(ApiMessage::ok("Left team successfully").into_response())
}
#[utoipa::path(
delete,
path = "/v1/hackathon/teams/{team_id}/members/{member_id}",
params(
("team_id" = Uuid, Path, description = "Team ID"),
("member_id" = Uuid, Path, description = "Member user ID")
),
responses(
(status = 200, description = "Remove team member"),
(status = 401, description = "Unauthorized"),
(status = 403, description = "Forbidden")
),
tag = "Hackathon - Teams",
security(("bearer_auth" = []))
)]
pub async fn remove_member_handler(
Extension(service): Extension<Arc<dyn TeamService>>,
Extension(auth): Extension<HackathonAuthUser>,
@@ -6,6 +6,16 @@ use imphnen_utils::{errors::AppError, response_format::ApiSuccess};
use std::sync::Arc;
use uuid::Uuid;
#[utoipa::path(
get,
path = "/v1/hackathon/users/me",
responses(
(status = 200, description = "Get my hackathon user profile"),
(status = 401, description = "Unauthorized")
),
tag = "Hackathon - Users",
security(("bearer_auth" = []))
)]
pub async fn get_me_handler(
Extension(service): Extension<Arc<dyn HackathonUserService>>,
Extension(auth): Extension<HackathonAuthUser>,
@@ -14,6 +24,17 @@ pub async fn get_me_handler(
Ok(ApiSuccess(UserResponse::from(user)).into_response())
}
#[utoipa::path(
put,
path = "/v1/hackathon/users/me",
request_body = UpdateUserRequest,
responses(
(status = 200, description = "Update my hackathon user profile"),
(status = 401, description = "Unauthorized")
),
tag = "Hackathon - Users",
security(("bearer_auth" = []))
)]
pub async fn update_me_handler(
Extension(service): Extension<Arc<dyn HackathonUserService>>,
Extension(auth): Extension<HackathonAuthUser>,
@@ -23,6 +44,16 @@ pub async fn update_me_handler(
Ok(ApiSuccess(UserResponse::from(user)).into_response())
}
#[utoipa::path(
get,
path = "/v1/hackathon/users/{user_id}",
params(("user_id" = Uuid, Path, description = "User ID")),
responses(
(status = 200, description = "Get hackathon user by ID"),
(status = 404, description = "User not found")
),
tag = "Hackathon - Users"
)]
pub async fn get_user_handler(
Extension(service): Extension<Arc<dyn HackathonUserService>>,
Path(user_id): Path<Uuid>,
@@ -31,6 +62,16 @@ pub async fn get_user_handler(
Ok(ApiSuccess(UserResponse::from(user)).into_response())
}
#[utoipa::path(
get,
path = "/v1/hackathon/users/{user_id}/teams",
params(("user_id" = Uuid, Path, description = "User ID")),
responses(
(status = 200, description = "Get teams for a hackathon user"),
(status = 404, description = "User not found")
),
tag = "Hackathon - Users"
)]
pub async fn get_user_teams_handler(
Extension(service): Extension<Arc<dyn HackathonUserService>>,
Path(user_id): Path<Uuid>,
@@ -4,6 +4,14 @@ use axum::{Extension, response::IntoResponse};
use imphnen_utils::{errors::AppError, response_format::ApiSuccess};
use std::sync::Arc;
#[utoipa::path(
get,
path = "/v1/hackathon/winners",
responses(
(status = 200, description = "List hackathon winners")
),
tag = "Hackathon - Winners"
)]
pub async fn list_winners_handler(
Extension(service): Extension<Arc<dyn WinnerService>>,
) -> Result<axum::response::Response, AppError> {