From e1bc336baa05ad5cf3a718c635e0e6613bbf66c4 Mon Sep 17 00:00:00 2001 From: maulanasdqn Date: Fri, 3 Apr 2026 01:22:38 +0700 Subject: [PATCH] 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 --- .../campaigns/infrastructure/http/handlers.rs | 57 +++++++++ .../qr/users/infrastructure/http/handlers.rs | 57 +++++++++ imphnen-gateway/src/docs/openapi.rs | 112 ++++++++++++++++++ .../src/admin/infrastructure/http/dto.rs | 4 +- .../src/admin/infrastructure/http/handlers.rs | 112 ++++++++++++++++++ .../infrastructure/http/handlers.rs | 10 ++ .../src/chat/infrastructure/http/handlers.rs | 35 ++++++ .../infrastructure/http/handlers.rs | 36 ++++++ .../infrastructure/http/handlers.rs | 47 ++++++++ .../storage/infrastructure/http/handlers.rs | 44 +++++++ .../infrastructure/http/handlers.rs | 69 +++++++++++ .../src/teams/infrastructure/http/dto.rs | 2 +- .../src/teams/infrastructure/http/handlers.rs | 91 ++++++++++++++ .../src/users/infrastructure/http/handlers.rs | 41 +++++++ .../winners/infrastructure/http/handlers.rs | 8 ++ 15 files changed, 722 insertions(+), 3 deletions(-) diff --git a/imphnen-cms/src/qr/campaigns/infrastructure/http/handlers.rs b/imphnen-cms/src/qr/campaigns/infrastructure/http/handlers.rs index d11b397..52912e2 100644 --- a/imphnen-cms/src/qr/campaigns/infrastructure/http/handlers.rs +++ b/imphnen-cms/src/qr/campaigns/infrastructure/http/handlers.rs @@ -15,6 +15,18 @@ use crate::qr::{ middleware::qr_auth::QrAuthUser, }; +#[utoipa::path( + post, + path = "/v1/qr/campaigns", + request_body = CreateCampaignRequest, + responses( + (status = 201, description = "Create a QR campaign"), + (status = 401, description = "Unauthorized"), + (status = 403, description = "Forbidden - admin only") + ), + tag = "QR - Campaigns", + security(("bearer_auth" = [])) +)] pub async fn create_campaign_handler( Extension(service): Extension>, Extension(auth_user): Extension, @@ -31,6 +43,17 @@ pub async fn create_campaign_handler( Ok(imphnen_utils::response_format::ApiCreated(campaign).into_response()) } +#[utoipa::path( + get, + path = "/v1/qr/campaigns", + responses( + (status = 200, description = "Admin: list all QR campaigns"), + (status = 401, description = "Unauthorized"), + (status = 403, description = "Forbidden - admin only") + ), + tag = "QR - Campaigns", + security(("bearer_auth" = [])) +)] pub async fn list_campaigns_handler( Extension(service): Extension>, Extension(auth_user): Extension, @@ -44,6 +67,18 @@ pub async fn list_campaigns_handler( Ok(ApiSuccess(campaigns).into_response()) } +#[utoipa::path( + put, + path = "/v1/qr/campaigns/{id}/activate", + params(("id" = Uuid, Path, description = "Campaign ID")), + responses( + (status = 200, description = "Admin: activate a campaign"), + (status = 401, description = "Unauthorized"), + (status = 403, description = "Forbidden - admin only") + ), + tag = "QR - Campaigns", + security(("bearer_auth" = [])) +)] pub async fn activate_campaign_handler( Extension(service): Extension>, Extension(auth_user): Extension, @@ -58,6 +93,18 @@ pub async fn activate_campaign_handler( Ok(ApiSuccess(campaign).into_response()) } +#[utoipa::path( + delete, + path = "/v1/qr/campaigns/{id}", + params(("id" = Uuid, Path, description = "Campaign ID")), + responses( + (status = 200, description = "Admin: delete a campaign"), + (status = 401, description = "Unauthorized"), + (status = 403, description = "Forbidden - admin only") + ), + tag = "QR - Campaigns", + security(("bearer_auth" = [])) +)] pub async fn delete_campaign_handler( Extension(service): Extension>, Extension(auth_user): Extension, @@ -75,6 +122,16 @@ pub async fn delete_campaign_handler( ) } +#[utoipa::path( + post, + path = "/v1/qr/campaigns/process-image", + responses( + (status = 200, description = "Process QR code image (multipart/form-data with 'file' field)"), + (status = 401, description = "Unauthorized") + ), + tag = "QR - Campaigns", + security(("bearer_auth" = [])) +)] pub async fn process_image_handler( Extension(service): Extension>, Extension(_auth_user): Extension, diff --git a/imphnen-cms/src/qr/users/infrastructure/http/handlers.rs b/imphnen-cms/src/qr/users/infrastructure/http/handlers.rs index 7d2a794..59be574 100644 --- a/imphnen-cms/src/qr/users/infrastructure/http/handlers.rs +++ b/imphnen-cms/src/qr/users/infrastructure/http/handlers.rs @@ -15,6 +15,16 @@ use crate::qr::{ }, }; +#[utoipa::path( + get, + path = "/v1/qr/users/me", + responses( + (status = 200, description = "Get my QR user profile"), + (status = 401, description = "Unauthorized") + ), + tag = "QR - Users", + security(("bearer_auth" = [])) +)] pub async fn get_me_handler( Extension(service): Extension>, Extension(auth_user): Extension, @@ -23,6 +33,17 @@ pub async fn get_me_handler( Ok(ApiSuccess(user).into_response()) } +#[utoipa::path( + put, + path = "/v1/qr/users/me", + request_body = UpdateProfileRequest, + responses( + (status = 200, description = "Update my QR user profile"), + (status = 401, description = "Unauthorized") + ), + tag = "QR - Users", + security(("bearer_auth" = [])) +)] pub async fn update_me_handler( Extension(service): Extension>, Extension(auth_user): Extension, @@ -36,6 +57,17 @@ pub async fn update_me_handler( Ok(ApiSuccess(user).into_response()) } +#[utoipa::path( + get, + path = "/v1/qr/users", + responses( + (status = 200, description = "Admin: list all QR users"), + (status = 401, description = "Unauthorized"), + (status = 403, description = "Forbidden - admin only") + ), + tag = "QR - Users", + security(("bearer_auth" = [])) +)] pub async fn list_users_handler( Extension(service): Extension>, Extension(auth_user): Extension, @@ -49,6 +81,19 @@ pub async fn list_users_handler( Ok(ApiSuccess(users).into_response()) } +#[utoipa::path( + put, + path = "/v1/qr/users/{id}/role", + params(("id" = Uuid, Path, description = "User ID")), + request_body = UpdateRoleRequest, + responses( + (status = 200, description = "Admin: update user role"), + (status = 401, description = "Unauthorized"), + (status = 403, description = "Forbidden - admin only") + ), + tag = "QR - Users", + security(("bearer_auth" = [])) +)] pub async fn update_role_handler( Extension(service): Extension>, Extension(auth_user): Extension, @@ -64,6 +109,18 @@ pub async fn update_role_handler( Ok(ApiSuccess(user).into_response()) } +#[utoipa::path( + delete, + path = "/v1/qr/users/{id}", + params(("id" = Uuid, Path, description = "User ID")), + responses( + (status = 200, description = "Admin: delete QR user"), + (status = 401, description = "Unauthorized"), + (status = 403, description = "Forbidden - admin only") + ), + tag = "QR - Users", + security(("bearer_auth" = [])) +)] pub async fn delete_user_handler( Extension(service): Extension>, Extension(auth_user): Extension, diff --git a/imphnen-gateway/src/docs/openapi.rs b/imphnen-gateway/src/docs/openapi.rs index fa70d47..fa65a49 100644 --- a/imphnen-gateway/src/docs/openapi.rs +++ b/imphnen-gateway/src/docs/openapi.rs @@ -3,6 +3,12 @@ use imphnen_cms::events::infrastructure::http::dto::{ EventsDetailItemDto, EventsListItemDto, }; use imphnen_cms::events::infrastructure::http::handlers as events_controller; +use imphnen_cms::qr::campaigns::infrastructure::http::dto::CreateCampaignRequest; +use imphnen_cms::qr::campaigns::infrastructure::http::handlers as qr_campaigns_controller; +use imphnen_cms::qr::users::infrastructure::http::dto::{ + UpdateProfileRequest, UpdateRoleRequest, +}; +use imphnen_cms::qr::users::infrastructure::http::handlers as qr_users_controller; use imphnen_cms::testimonials::infrastructure::http::dto::{ TestimonialsCreateRequestDto, TestimonialsDetailItemDto, TestimonialsListItemDto, TestimonialsUpdateRequestDto, @@ -41,6 +47,46 @@ use imphnen_gacha::gacha_rolls::infrastructure::http::dto::{ GachaRollCreateRequestDto, GachaRollItemDto, }; use imphnen_gacha::gacha_rolls::infrastructure::http::handlers as gacha_rolls_controller; +use imphnen_hackathon::admin::domain::entity::{ + AdminSubmissionRow, AdminTeamRow, AdminUserRow, WinnerRow, +}; +use imphnen_hackathon::admin::infrastructure::http::dto::{ + SetAdminRequest, SetWinnerRequest, +}; +use imphnen_hackathon::admin::infrastructure::http::handlers as hackathon_admin_controller; +use imphnen_hackathon::certificates::infrastructure::http::dto::CertificateResponse; +use imphnen_hackathon::certificates::infrastructure::http::handlers as hackathon_certificates_controller; +use imphnen_hackathon::chat::infrastructure::http::dto::{ + MessageResponse, SendMessageRequest, +}; +use imphnen_hackathon::chat::infrastructure::http::handlers as hackathon_chat_controller; +use imphnen_hackathon::invitations::infrastructure::http::dto::{ + CreateInvitationRequest, InvitationResponse, RespondToInvitationRequest, +}; +use imphnen_hackathon::invitations::infrastructure::http::handlers as hackathon_invitations_controller; +use imphnen_hackathon::join_requests::infrastructure::http::dto::{ + CreateJoinRequestRequest, JoinRequestResponse, RespondToJoinRequestRequest, +}; +use imphnen_hackathon::join_requests::infrastructure::http::handlers as hackathon_join_requests_controller; +use imphnen_hackathon::storage::infrastructure::http::dto::{ + UploadRequest, UploadResponse, +}; +use imphnen_hackathon::storage::infrastructure::http::handlers as hackathon_storage_controller; +use imphnen_hackathon::submissions::infrastructure::http::dto::{ + CreateSubmissionRequest, SubmissionResponse, UpdateSubmissionRequest, +}; +use imphnen_hackathon::submissions::infrastructure::http::handlers as hackathon_submissions_controller; +use imphnen_hackathon::teams::infrastructure::http::dto::{ + BrowseTeamsQuery, CreateTeamRequest, TeamListResponse, TeamMemberResponse, + TeamResponse, UpdateTeamRequest, UserInfoResponse, +}; +use imphnen_hackathon::teams::infrastructure::http::handlers as hackathon_teams_controller; +use imphnen_hackathon::users::infrastructure::http::dto::{ + UpdateUserRequest, UserResponse, +}; +use imphnen_hackathon::users::infrastructure::http::handlers as hackathon_users_controller; +use imphnen_hackathon::winners::infrastructure::http::dto::WinnerResponse; +use imphnen_hackathon::winners::infrastructure::http::handlers as hackathon_winners_controller; use imphnen_iam::auth::infrastructure::http::dto::{ AuthLoginRequestDto, AuthLoginResponsetDto, AuthNewPasswordRequestDto, AuthRefreshTokenRequestDto, AuthResendOtpRequestDto, AuthVerifyEmailRequestDto, @@ -102,6 +148,48 @@ use utoipa::OpenApi; sessions_controller::mutation_handlers::post_book_session, sessions_controller::query_handlers::get_mentor_sessions, sessions_controller::query_handlers::get_mentor_availability, sessions_controller::mutation_handlers::put_update_session_status, sessions_controller::mutation_handlers::post_submit_feedback, sessions_controller::query_handlers::get_my_sessions, + hackathon_users_controller::get_me_handler, hackathon_users_controller::update_me_handler, + hackathon_users_controller::get_user_handler, hackathon_users_controller::get_user_teams_handler, + hackathon_teams_controller::create_team_handler, hackathon_teams_controller::get_team_handler, + hackathon_teams_controller::browse_teams_handler, hackathon_teams_controller::get_my_teams_handler, + hackathon_teams_controller::update_team_handler, hackathon_teams_controller::delete_team_handler, + hackathon_teams_controller::leave_team_handler, hackathon_teams_controller::remove_member_handler, + hackathon_invitations_controller::get_my_invitations_handler, + hackathon_invitations_controller::respond_to_invitation_handler, + hackathon_invitations_controller::invite_team_member_handler, + hackathon_join_requests_controller::create_join_request_handler, + hackathon_join_requests_controller::get_my_join_requests_handler, + hackathon_join_requests_controller::get_team_join_requests_handler, + hackathon_join_requests_controller::respond_to_join_request_handler, + hackathon_submissions_controller::create_submission_handler, + hackathon_submissions_controller::get_team_submission_handler, + hackathon_submissions_controller::update_submission_handler, + hackathon_submissions_controller::submit_project_handler, + hackathon_submissions_controller::confirm_submission_handler, + hackathon_submissions_controller::cancel_submission_handler, + hackathon_certificates_controller::get_certificate_handler, + hackathon_winners_controller::list_winners_handler, + hackathon_admin_controller::admin_list_users, hackathon_admin_controller::admin_get_user, + hackathon_admin_controller::admin_set_admin, hackathon_admin_controller::admin_delete_user, + hackathon_admin_controller::admin_list_teams, hackathon_admin_controller::admin_delete_team, + hackathon_admin_controller::admin_list_submissions, + hackathon_admin_controller::admin_set_winner, hackathon_admin_controller::admin_remove_winner, + hackathon_admin_controller::admin_list_winners, + hackathon_chat_controller::get_team_messages_handler, + hackathon_chat_controller::send_message_handler, + hackathon_chat_controller::delete_message_handler, + hackathon_storage_controller::upload_file_handler, + hackathon_storage_controller::upload_avatar_handler, + hackathon_storage_controller::upload_team_handler, + hackathon_storage_controller::upload_submission_handler, + qr_users_controller::get_me_handler, qr_users_controller::update_me_handler, + qr_users_controller::list_users_handler, qr_users_controller::update_role_handler, + qr_users_controller::delete_user_handler, + qr_campaigns_controller::create_campaign_handler, + qr_campaigns_controller::list_campaigns_handler, + qr_campaigns_controller::activate_campaign_handler, + qr_campaigns_controller::delete_campaign_handler, + qr_campaigns_controller::process_image_handler, ), components(schemas( MessageResponseDto, AuthLoginRequestDto, AuthLoginResponsetDto, @@ -135,6 +223,18 @@ use utoipa::OpenApi; ResponseSuccessDto, ResponseSuccessDto, ResponseSuccessDto, ResponseSuccessDto, ResponseSuccessDto, + UserResponse, UpdateUserRequest, + TeamResponse, CreateTeamRequest, UpdateTeamRequest, BrowseTeamsQuery, + TeamListResponse, UserInfoResponse, TeamMemberResponse, + InvitationResponse, RespondToInvitationRequest, CreateInvitationRequest, + JoinRequestResponse, CreateJoinRequestRequest, RespondToJoinRequestRequest, + SubmissionResponse, CreateSubmissionRequest, UpdateSubmissionRequest, + CertificateResponse, WinnerResponse, + SetAdminRequest, SetWinnerRequest, + AdminUserRow, AdminTeamRow, AdminSubmissionRow, WinnerRow, + MessageResponse, SendMessageRequest, + UploadRequest, UploadResponse, + UpdateProfileRequest, UpdateRoleRequest, CreateCampaignRequest, )), info( title = "IMPHNEN Backend Service", @@ -155,6 +255,18 @@ use utoipa::OpenApi; (name = "Mentors - Admin", description = "Dimentorin — Mentor admin endpoints (/v1/dimentorin/mentors)"), (name = "sessions", description = "Dimentorin — Session management (/v1/dimentorin/sessions)"), (name = "Gacha", description = "Gacha system (/v1/gacha)"), + (name = "Hackathon - Users", description = "Hackathon — User profile (/v1/hackathon/users)"), + (name = "Hackathon - Teams", description = "Hackathon — Team management (/v1/hackathon/teams)"), + (name = "Hackathon - Invitations", description = "Hackathon — Team invitations (/v1/hackathon/invitations)"), + (name = "Hackathon - Join Requests", description = "Hackathon — Join requests (/v1/hackathon/join-requests)"), + (name = "Hackathon - Submissions", description = "Hackathon — Project submissions (/v1/hackathon/submissions)"), + (name = "Hackathon - Certificates", description = "Hackathon — Certificates (/v1/hackathon/certificates)"), + (name = "Hackathon - Winners", description = "Hackathon — Winners (/v1/hackathon/winners)"), + (name = "Hackathon - Admin", description = "Hackathon — Admin management (/v1/hackathon/admin)"), + (name = "Hackathon - Chat", description = "Hackathon — Team chat (/v1/hackathon/chat)"), + (name = "Hackathon - Storage", description = "Hackathon — File uploads (/v1/hackathon/upload)"), + (name = "QR - Users", description = "QR — User management (/v1/qr/users)"), + (name = "QR - Campaigns", description = "QR — Campaign management (/v1/qr/campaigns)"), ) )] pub struct ApiDoc; diff --git a/imphnen-hackathon/src/admin/infrastructure/http/dto.rs b/imphnen-hackathon/src/admin/infrastructure/http/dto.rs index 32bca6a..050a5c3 100644 --- a/imphnen-hackathon/src/admin/infrastructure/http/dto.rs +++ b/imphnen-hackathon/src/admin/infrastructure/http/dto.rs @@ -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, diff --git a/imphnen-hackathon/src/admin/infrastructure/http/handlers.rs b/imphnen-hackathon/src/admin/infrastructure/http/handlers.rs index 802a9ff..bc6ed32 100644 --- a/imphnen-hackathon/src/admin/infrastructure/http/handlers.rs +++ b/imphnen-hackathon/src/admin/infrastructure/http/handlers.rs @@ -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>, Query(q): Query, @@ -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>, Path(user_id): Path, @@ -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>, Path(user_id): Path, @@ -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>, Path(user_id): Path, @@ -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>, Query(q): Query, @@ -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>, Path(team_id): Path, @@ -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>, Query(q): Query, @@ -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>, Json(body): Json, @@ -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>, Path(team_id): Path, @@ -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>, ) -> Result { diff --git a/imphnen-hackathon/src/certificates/infrastructure/http/handlers.rs b/imphnen-hackathon/src/certificates/infrastructure/http/handlers.rs index 38e0cec..fd8c8de 100644 --- a/imphnen-hackathon/src/certificates/infrastructure/http/handlers.rs +++ b/imphnen-hackathon/src/certificates/infrastructure/http/handlers.rs @@ -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>, Path(user_id): Path, diff --git a/imphnen-hackathon/src/chat/infrastructure/http/handlers.rs b/imphnen-hackathon/src/chat/infrastructure/http/handlers.rs index 0f6161e..48b6836 100644 --- a/imphnen-hackathon/src/chat/infrastructure/http/handlers.rs +++ b/imphnen-hackathon/src/chat/infrastructure/http/handlers.rs @@ -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>, Extension(auth): Extension, @@ -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>, Extension(auth): Extension, @@ -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>, Extension(auth): Extension, diff --git a/imphnen-hackathon/src/invitations/infrastructure/http/handlers.rs b/imphnen-hackathon/src/invitations/infrastructure/http/handlers.rs index ddbdb6e..d3ad89f 100644 --- a/imphnen-hackathon/src/invitations/infrastructure/http/handlers.rs +++ b/imphnen-hackathon/src/invitations/infrastructure/http/handlers.rs @@ -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>, Extension(auth): Extension, @@ -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>, Extension(auth): Extension, @@ -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>, Extension(auth): Extension, diff --git a/imphnen-hackathon/src/join_requests/infrastructure/http/handlers.rs b/imphnen-hackathon/src/join_requests/infrastructure/http/handlers.rs index 8aa1282..49471ff 100644 --- a/imphnen-hackathon/src/join_requests/infrastructure/http/handlers.rs +++ b/imphnen-hackathon/src/join_requests/infrastructure/http/handlers.rs @@ -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>, Extension(auth): Extension, @@ -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>, Extension(auth): Extension, @@ -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>, Extension(auth): Extension, @@ -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>, Extension(auth): Extension, diff --git a/imphnen-hackathon/src/storage/infrastructure/http/handlers.rs b/imphnen-hackathon/src/storage/infrastructure/http/handlers.rs index 48c17d0..13fa616 100644 --- a/imphnen-hackathon/src/storage/infrastructure/http/handlers.rs +++ b/imphnen-hackathon/src/storage/infrastructure/http/handlers.rs @@ -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>, Extension(auth): Extension, @@ -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>, Extension(auth): Extension, @@ -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>, Extension(auth): Extension, @@ -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>, Extension(auth): Extension, diff --git a/imphnen-hackathon/src/submissions/infrastructure/http/handlers.rs b/imphnen-hackathon/src/submissions/infrastructure/http/handlers.rs index 974d47a..536ded1 100644 --- a/imphnen-hackathon/src/submissions/infrastructure/http/handlers.rs +++ b/imphnen-hackathon/src/submissions/infrastructure/http/handlers.rs @@ -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>, Extension(auth): Extension, @@ -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>, Extension(auth): Extension, @@ -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>, Extension(auth): Extension, @@ -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>, Extension(auth): Extension, @@ -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>, Extension(auth): Extension, @@ -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>, Extension(auth): Extension, diff --git a/imphnen-hackathon/src/teams/infrastructure/http/dto.rs b/imphnen-hackathon/src/teams/infrastructure/http/dto.rs index f46fc0c..5640a74 100644 --- a/imphnen-hackathon/src/teams/infrastructure/http/dto.rs +++ b/imphnen-hackathon/src/teams/infrastructure/http/dto.rs @@ -145,7 +145,7 @@ impl From for UpdateTeamInput { } } -#[derive(Debug, Deserialize, ToSchema)] +#[derive(Debug, Deserialize, ToSchema, utoipa::IntoParams)] pub struct BrowseTeamsQuery { pub search: Option, pub city: Option, diff --git a/imphnen-hackathon/src/teams/infrastructure/http/handlers.rs b/imphnen-hackathon/src/teams/infrastructure/http/handlers.rs index 342dc4a..b359cb6 100644 --- a/imphnen-hackathon/src/teams/infrastructure/http/handlers.rs +++ b/imphnen-hackathon/src/teams/infrastructure/http/handlers.rs @@ -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>, Extension(auth): Extension, @@ -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>, Path(team_id): Path, @@ -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>, Query(query): Query, @@ -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>, Extension(auth): Extension, @@ -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>, Extension(auth): Extension, @@ -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>, Extension(auth): Extension, @@ -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>, Extension(auth): Extension, @@ -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>, Extension(auth): Extension, diff --git a/imphnen-hackathon/src/users/infrastructure/http/handlers.rs b/imphnen-hackathon/src/users/infrastructure/http/handlers.rs index 7bf8bf6..fb8a951 100644 --- a/imphnen-hackathon/src/users/infrastructure/http/handlers.rs +++ b/imphnen-hackathon/src/users/infrastructure/http/handlers.rs @@ -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>, Extension(auth): Extension, @@ -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>, Extension(auth): Extension, @@ -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>, Path(user_id): Path, @@ -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>, Path(user_id): Path, diff --git a/imphnen-hackathon/src/winners/infrastructure/http/handlers.rs b/imphnen-hackathon/src/winners/infrastructure/http/handlers.rs index c872cbb..8828090 100644 --- a/imphnen-hackathon/src/winners/infrastructure/http/handlers.rs +++ b/imphnen-hackathon/src/winners/infrastructure/http/handlers.rs @@ -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>, ) -> Result {