- New model: minimum_workloads table with JSON config column (per-user) - Schemas: MinimumWorkloadConfig, MinimumWorkloadUpdate, MinimumWorkloadResponse - Service: CRUD operations + check_workload_warnings() entry point for BE-CAL-007 - API: GET/PUT/PATCH /calendar/workload-config (self + admin routes) - Migration: auto-create minimum_workloads table on startup - Registered calendar router in main.py
148 lines
4.7 KiB
Python
148 lines
4.7 KiB
Python
"""Calendar API router.
|
|
|
|
BE-CAL-004: MinimumWorkload CRUD endpoints.
|
|
Future tasks (BE-CAL-API-*) will add slot/plan endpoints here.
|
|
"""
|
|
|
|
from fastapi import APIRouter, Depends, HTTPException
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.api.deps import get_current_user
|
|
from app.core.config import get_db
|
|
from app.models.models import User
|
|
from app.schemas.calendar import (
|
|
MinimumWorkloadConfig,
|
|
MinimumWorkloadResponse,
|
|
MinimumWorkloadUpdate,
|
|
)
|
|
from app.services.minimum_workload import (
|
|
get_workload_config,
|
|
replace_workload_config,
|
|
upsert_workload_config,
|
|
)
|
|
|
|
router = APIRouter(prefix="/calendar", tags=["Calendar"])
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# MinimumWorkload
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@router.get(
|
|
"/workload-config",
|
|
response_model=MinimumWorkloadResponse,
|
|
summary="Get current user's minimum workload configuration",
|
|
)
|
|
def get_my_workload_config(
|
|
db: Session = Depends(get_db),
|
|
current_user: User = Depends(get_current_user),
|
|
):
|
|
"""Return the workload thresholds for the authenticated user.
|
|
|
|
If no configuration has been saved yet, returns default (all-zero)
|
|
thresholds.
|
|
"""
|
|
cfg = get_workload_config(db, current_user.id)
|
|
return MinimumWorkloadResponse(user_id=current_user.id, config=cfg)
|
|
|
|
|
|
@router.put(
|
|
"/workload-config",
|
|
response_model=MinimumWorkloadResponse,
|
|
summary="Replace the current user's minimum workload configuration",
|
|
)
|
|
def put_my_workload_config(
|
|
payload: MinimumWorkloadConfig,
|
|
db: Session = Depends(get_db),
|
|
current_user: User = Depends(get_current_user),
|
|
):
|
|
"""Full replacement of the workload configuration."""
|
|
row = replace_workload_config(db, current_user.id, payload)
|
|
db.commit()
|
|
db.refresh(row)
|
|
return MinimumWorkloadResponse(user_id=current_user.id, config=row.config)
|
|
|
|
|
|
@router.patch(
|
|
"/workload-config",
|
|
response_model=MinimumWorkloadResponse,
|
|
summary="Partially update the current user's minimum workload configuration",
|
|
)
|
|
def patch_my_workload_config(
|
|
payload: MinimumWorkloadUpdate,
|
|
db: Session = Depends(get_db),
|
|
current_user: User = Depends(get_current_user),
|
|
):
|
|
"""Partial update — only the provided periods are overwritten."""
|
|
row = upsert_workload_config(db, current_user.id, payload)
|
|
db.commit()
|
|
db.refresh(row)
|
|
return MinimumWorkloadResponse(user_id=current_user.id, config=row.config)
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Admin: manage another user's workload config
|
|
# ---------------------------------------------------------------------------
|
|
|
|
def _require_admin(current_user: User = Depends(get_current_user)):
|
|
if not current_user.is_admin:
|
|
raise HTTPException(status_code=403, detail="Admin required")
|
|
return current_user
|
|
|
|
|
|
@router.get(
|
|
"/workload-config/{user_id}",
|
|
response_model=MinimumWorkloadResponse,
|
|
summary="[Admin] Get a specific user's minimum workload configuration",
|
|
)
|
|
def get_user_workload_config(
|
|
user_id: int,
|
|
db: Session = Depends(get_db),
|
|
_admin: User = Depends(_require_admin),
|
|
):
|
|
user = db.query(User).filter(User.id == user_id).first()
|
|
if not user:
|
|
raise HTTPException(status_code=404, detail="User not found")
|
|
cfg = get_workload_config(db, user_id)
|
|
return MinimumWorkloadResponse(user_id=user_id, config=cfg)
|
|
|
|
|
|
@router.put(
|
|
"/workload-config/{user_id}",
|
|
response_model=MinimumWorkloadResponse,
|
|
summary="[Admin] Replace a specific user's minimum workload configuration",
|
|
)
|
|
def put_user_workload_config(
|
|
user_id: int,
|
|
payload: MinimumWorkloadConfig,
|
|
db: Session = Depends(get_db),
|
|
_admin: User = Depends(_require_admin),
|
|
):
|
|
user = db.query(User).filter(User.id == user_id).first()
|
|
if not user:
|
|
raise HTTPException(status_code=404, detail="User not found")
|
|
row = replace_workload_config(db, user_id, payload)
|
|
db.commit()
|
|
db.refresh(row)
|
|
return MinimumWorkloadResponse(user_id=user_id, config=row.config)
|
|
|
|
|
|
@router.patch(
|
|
"/workload-config/{user_id}",
|
|
response_model=MinimumWorkloadResponse,
|
|
summary="[Admin] Partially update a specific user's minimum workload configuration",
|
|
)
|
|
def patch_user_workload_config(
|
|
user_id: int,
|
|
payload: MinimumWorkloadUpdate,
|
|
db: Session = Depends(get_db),
|
|
_admin: User = Depends(_require_admin),
|
|
):
|
|
user = db.query(User).filter(User.id == user_id).first()
|
|
if not user:
|
|
raise HTTPException(status_code=404, detail="User not found")
|
|
row = upsert_workload_config(db, user_id, payload)
|
|
db.commit()
|
|
db.refresh(row)
|
|
return MinimumWorkloadResponse(user_id=user_id, config=row.config)
|