feat: Add endpoint to retrieve the current user's team and corresponding service logic

This commit is contained in:
MythEclipse
2025-10-27 17:44:13 +07:00
parent e77797d7bb
commit cb6eef2054
3 changed files with 53 additions and 0 deletions
@@ -390,6 +390,26 @@ pub async fn post_leave_current_team(
authenticated(headers, Extension(state), |claims, state| TeamsService::leave_current_team(&state, claims)).await authenticated(headers, Extension(state), |claims, state| TeamsService::leave_current_team(&state, claims)).await
} }
#[utoipa::path(
get,
security(
("Bearer" = [])
),
path = "/v1/teams/me",
responses(
(status = 200, description = "[AUTH] Get my team", body = ResponseSuccessDto<PublicTeamsDetailItemDto>),
(status = 401, description = "[AUTH] Unauthorized"),
(status = 404, description = "[AUTH] User is not a member of any team")
),
tag = "Teams"
)]
pub async fn get_my_team(
headers: HeaderMap,
Extension(state): Extension<AppState>,
) -> impl IntoResponse {
authenticated(headers, Extension(state), |claims, state| TeamsService::get_my_team(&state, claims)).await
}
#[utoipa::path( #[utoipa::path(
get, get,
security( security(
@@ -486,4 +506,5 @@ pub fn teams_router() -> Router {
.route("/{id}/members/{user_id}", axum::routing::delete(delete_remove_team_member)) .route("/{id}/members/{user_id}", axum::routing::delete(delete_remove_team_member))
.route("/{id}/leave", axum::routing::post(post_leave_team)) .route("/{id}/leave", axum::routing::post(post_leave_team))
.route("/leave-me", axum::routing::post(post_leave_current_team)) .route("/leave-me", axum::routing::post(post_leave_current_team))
.route("/me", axum::routing::get(get_my_team))
} }
+29
View File
@@ -38,6 +38,7 @@ pub trait TeamsServiceTrait: Send + Sync + 'static {
fn get_team_members(state: &AppState, claims: imphnen_libs::jsonwebtoken::Claims, team_id: String) -> Pin<Box<dyn Future<Output = Response> + Send>>; fn get_team_members(state: &AppState, claims: imphnen_libs::jsonwebtoken::Claims, team_id: String) -> Pin<Box<dyn Future<Output = Response> + Send>>;
fn leave_team(state: &AppState, claims: imphnen_libs::jsonwebtoken::Claims, team_id: String) -> Pin<Box<dyn Future<Output = Response> + Send>>; fn leave_team(state: &AppState, claims: imphnen_libs::jsonwebtoken::Claims, team_id: String) -> Pin<Box<dyn Future<Output = Response> + Send>>;
fn leave_current_team(state: &AppState, claims: imphnen_libs::jsonwebtoken::Claims) -> Pin<Box<dyn Future<Output = Response> + Send>>; fn leave_current_team(state: &AppState, claims: imphnen_libs::jsonwebtoken::Claims) -> Pin<Box<dyn Future<Output = Response> + Send>>;
fn get_my_team(state: &AppState, claims: imphnen_libs::jsonwebtoken::Claims) -> Pin<Box<dyn Future<Output = Response> + Send>>;
fn search_teams(state: &AppState, search_params: TeamsSearchQueryDto) -> Pin<Box<dyn Future<Output = Response> + Send>>; fn search_teams(state: &AppState, search_params: TeamsSearchQueryDto) -> Pin<Box<dyn Future<Output = Response> + Send>>;
fn get_admin_team_list(state: &AppState, meta: MetaRequestDto) -> Pin<Box<dyn Future<Output = Response> + Send>>; fn get_admin_team_list(state: &AppState, meta: MetaRequestDto) -> Pin<Box<dyn Future<Output = Response> + Send>>;
fn get_admin_team_by_id(state: &AppState, id: String) -> Pin<Box<dyn Future<Output = Response> + Send>>; fn get_admin_team_by_id(state: &AppState, id: String) -> Pin<Box<dyn Future<Output = Response> + Send>>;
@@ -1058,4 +1059,32 @@ impl TeamsServiceTrait for TeamsService {
} }
}) })
} }
fn get_my_team(state: &AppState, claims: imphnen_libs::jsonwebtoken::Claims) -> Pin<Box<dyn Future<Output = Response> + Send>> {
let state = state.to_owned();
Box::pin(async move {
let repo = TeamsRepository::new(&state);
let user_thing = make_thing_from_enum(ResourceEnum::Users, &claims.user_id);
// Find the teams that the user is a member of
let teams = match repo.query_teams_by_user(&user_thing).await {
Ok(teams) => teams,
Err(e) => {
error!("Failed to query user teams: {}", e);
return common_response(StatusCode::INTERNAL_SERVER_ERROR, "Failed to retrieve user teams")
},
};
if teams.is_empty() {
return common_response(StatusCode::NOT_FOUND, "User is not a member of any team");
}
// Return the first team (most common case - user is in one team)
let team = &teams[0];
let team_id = team.id.id.to_raw();
// Get full team details
Self::get_public_team_by_id(&state, team_id).await
})
}
} }
+3
View File
@@ -84,6 +84,9 @@ test_team_endpoints() {
# test_api_endpoint "POST Leave Team" "POST" "/v1/teams/$created_team_id/leave" 200 "" true # test_api_endpoint "POST Leave Team" "POST" "/v1/teams/$created_team_id/leave" 200 "" true
# test_api_endpoint "POST Leave Current Team" "POST" "/v1/teams/leave-me" 200 "" true # test_api_endpoint "POST Leave Current Team" "POST" "/v1/teams/leave-me" 200 "" true
# === Get My Team ===
test_api_endpoint "GET My Team" "GET" "/v1/teams/me" 200 "" true
# Delete team (cleanup) # Delete team (cleanup)
test_api_endpoint "DELETE Team" "DELETE" "/v1/teams/delete/$created_team_id" 200 "" true test_api_endpoint "DELETE Team" "DELETE" "/v1/teams/delete/$created_team_id" 200 "" true
fi fi