Coverage for app/routers/teams.py: 91.49%
47 statements
« prev ^ index » next coverage.py v7.14.1, created at 2026-07-25 15:51 +0000
« prev ^ index » next coverage.py v7.14.1, created at 2026-07-25 15:51 +0000
1from uuid import UUID
3from fastapi import APIRouter, Depends, HTTPException, status
4from sqlalchemy.orm import Session
6from app.crud import teams as crud_teams
7from app.database import get_db
8from app.models import User
9from app.schemas import TeamCreate, TeamResponse, TeamUpdate, TeamWithMembers
10from app.utils.keycloak_auth import get_current_user_keycloak
11from app.utils.permissions import require_staff
13router = APIRouter()
16# ----------------------------------------------------------------
17# GET ALL TEAMS
18# ----------------------------------------------------------------
19@router.get("/", response_model=list[TeamResponse])
20def list_teams(
21 skip: int = 0,
22 limit: int = 100,
23 deployment_id: UUID | None = None,
24 db: Session = Depends(get_db),
25 current_user: User = Depends(get_current_user_keycloak)
26):
27 """
28 Get all teams, optionally filtered to a single deployment.
30 All authenticated users may list teams; per-team membership gating
31 happens at ``GET /teams/{team_id}``.
32 """
33 teams = crud_teams.get_teams(db, skip=skip, limit=limit, deployment_id=deployment_id)
34 return teams
37# ----------------------------------------------------------------
38# GET TEAM BY ID
39# ----------------------------------------------------------------
40@router.get("/{team_id}", response_model=TeamWithMembers)
41def get_team(
42 team_id: UUID,
43 db: Session = Depends(get_db),
44 current_user: User = Depends(get_current_user_keycloak)
45):
46 """Get team by ID with all members"""
47 team = crud_teams.get_team(db, team_id)
48 if not team:
49 raise HTTPException(
50 status_code=status.HTTP_404_NOT_FOUND,
51 detail="Team not found"
52 )
53 return team
56# ----------------------------------------------------------------
57# CREATE TEAM (TEACHER/ADMIN ONLY)
58# ----------------------------------------------------------------
59@router.post("/", response_model=TeamResponse, status_code=status.HTTP_201_CREATED)
60def create_team(
61 team: TeamCreate,
62 db: Session = Depends(get_db),
63 current_user: User = Depends(require_staff)
64):
65 """
66 Create a new team
67 - **Requires**: TEACHER or ADMIN role
68 """
69 return crud_teams.create_team(db, team)
72# ----------------------------------------------------------------
73# UPDATE TEAM (TEACHER/ADMIN ONLY)
74# ----------------------------------------------------------------
75@router.put("/{team_id}", response_model=TeamResponse)
76def update_team(
77 team_id: UUID,
78 team_update: TeamUpdate,
79 db: Session = Depends(get_db),
80 current_user: User = Depends(require_staff)
81):
82 """
83 Update a team
84 - **Requires**: TEACHER or ADMIN role
85 """
86 team = crud_teams.update_team(db, team_id, team_update)
87 if not team:
88 raise HTTPException(
89 status_code=status.HTTP_404_NOT_FOUND,
90 detail="Team not found"
91 )
92 return team
95# ----------------------------------------------------------------
96# DELETE TEAM (TEACHER/ADMIN ONLY)
97# ----------------------------------------------------------------
98@router.delete("/{team_id}", status_code=status.HTTP_204_NO_CONTENT)
99def delete_team(
100 team_id: UUID,
101 db: Session = Depends(get_db),
102 current_user: User = Depends(require_staff)
103):
104 """
105 Delete a team
106 - **Requires**: TEACHER or ADMIN role
107 """
108 success = crud_teams.delete_team(db, team_id)
109 if not success:
110 raise HTTPException(
111 status_code=status.HTTP_404_NOT_FOUND,
112 detail="Team not found"
113 )
114 return None
117# ----------------------------------------------------------------
118# ADD USER TO TEAM (TEACHER/ADMIN ONLY)
119# ----------------------------------------------------------------
120@router.post("/{team_id}/users/{user_id}", status_code=status.HTTP_204_NO_CONTENT)
121def add_user_to_team(
122 team_id: UUID,
123 user_id: UUID,
124 db: Session = Depends(get_db),
125 current_user: User = Depends(require_staff)
126):
127 """
128 Add a user to a team
129 - **Requires**: TEACHER or ADMIN role
130 """
131 success = crud_teams.add_user_to_team(db, team_id, user_id)
132 if not success:
133 raise HTTPException(
134 status_code=status.HTTP_400_BAD_REQUEST,
135 detail="User already in team or team not found"
136 )
137 return None
140# ----------------------------------------------------------------
141# REMOVE USER FROM TEAM (TEACHER/ADMIN ONLY)
142# ----------------------------------------------------------------
143@router.delete("/{team_id}/users/{user_id}", status_code=status.HTTP_204_NO_CONTENT)
144def remove_user_from_team(
145 team_id: UUID,
146 user_id: UUID,
147 db: Session = Depends(get_db),
148 current_user: User = Depends(require_staff)
149):
150 """
151 Remove a user from a team
152 - **Requires**: TEACHER or ADMIN role
153 """
154 success = crud_teams.remove_user_from_team(db, team_id, user_id)
155 if not success:
156 raise HTTPException(
157 status_code=status.HTTP_404_NOT_FOUND,
158 detail="User not in team or team not found"
159 )
160 return None