"""Settings management endpoints.""" from typing import Annotated from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.orm import Session from app.core.deps import get_current_admin, get_db from app.models.settings import Settings from app.models.user import User from app.schemas.settings import SettingsResponse, SettingsUpdate from app.services.audit_service import log_action router = APIRouter(prefix="/admin/settings", tags=["admin"]) @router.get("", response_model=SettingsResponse) def get_settings( db: Annotated[Session, Depends(get_db)], _: Annotated[User, Depends(get_current_admin)], ) -> Settings: """ Get global settings (admin only). Returns the current global booking rules. """ settings = db.query(Settings).filter(Settings.id == 1).first() if not settings: # Create default settings if not exist settings = Settings( id=1, min_duration_minutes=30, max_duration_minutes=480, working_hours_start=8, working_hours_end=20, max_bookings_per_day_per_user=3, min_hours_before_cancel=2, ) db.add(settings) db.commit() db.refresh(settings) return settings @router.put("", response_model=SettingsResponse) def update_settings( settings_data: SettingsUpdate, db: Annotated[Session, Depends(get_db)], current_admin: Annotated[User, Depends(get_current_admin)], ) -> Settings: """ Update global settings (admin only). All booking rules are validated on the client side and applied to all new booking requests. """ settings = db.query(Settings).filter(Settings.id == 1).first() if not settings: # Create if not exist settings = Settings(id=1) db.add(settings) # Validate: min_duration <= max_duration if settings_data.min_duration_minutes > settings_data.max_duration_minutes: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Minimum duration cannot be greater than maximum duration", ) # Validate: working_hours_start < working_hours_end if settings_data.working_hours_start >= settings_data.working_hours_end: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Working hours start must be before working hours end", ) # Track which fields changed changed_fields = {} if settings.min_duration_minutes != settings_data.min_duration_minutes: changed_fields["min_duration_minutes"] = { "old": settings.min_duration_minutes, "new": settings_data.min_duration_minutes } if settings.max_duration_minutes != settings_data.max_duration_minutes: changed_fields["max_duration_minutes"] = { "old": settings.max_duration_minutes, "new": settings_data.max_duration_minutes } if settings.working_hours_start != settings_data.working_hours_start: changed_fields["working_hours_start"] = { "old": settings.working_hours_start, "new": settings_data.working_hours_start } if settings.working_hours_end != settings_data.working_hours_end: changed_fields["working_hours_end"] = { "old": settings.working_hours_end, "new": settings_data.working_hours_end } if settings.max_bookings_per_day_per_user != settings_data.max_bookings_per_day_per_user: changed_fields["max_bookings_per_day_per_user"] = { "old": settings.max_bookings_per_day_per_user, "new": settings_data.max_bookings_per_day_per_user } if settings.min_hours_before_cancel != settings_data.min_hours_before_cancel: changed_fields["min_hours_before_cancel"] = { "old": settings.min_hours_before_cancel, "new": settings_data.min_hours_before_cancel } # Update all fields setattr(settings, "min_duration_minutes", settings_data.min_duration_minutes) setattr(settings, "max_duration_minutes", settings_data.max_duration_minutes) setattr(settings, "working_hours_start", settings_data.working_hours_start) setattr(settings, "working_hours_end", settings_data.working_hours_end) setattr(settings, "max_bookings_per_day_per_user", settings_data.max_bookings_per_day_per_user) setattr(settings, "min_hours_before_cancel", settings_data.min_hours_before_cancel) db.commit() db.refresh(settings) # Log the action log_action( db=db, action="settings_updated", user_id=current_admin.id, target_type="settings", target_id=1, # Settings ID is always 1 (singleton) details={"changed_fields": changed_fields} ) return settings