Olympus/backend/hermes/app/api/repairs.py
2026-07-04 11:46:58 +02:00

142 lines
4.9 KiB
Python

from fastapi import APIRouter, Depends, Header, HTTPException, Query, status
from sqlalchemy.orm import Session
from starlette.requests import Request
from typing import cast
from app.core.config import settings
from app.core.rbac import require_permission
from app.db.database import get_db
from app.models.repair import Repair
from app.models.user import User
from app.repositories.repair_repository import RepairRepository
from app.schemas.repair import (
RepairCreate,
RepairIntakePayload,
RepairIntakeResponse,
RepairListResponse,
RepairResponse,
RepairStatus,
RepairStatusHistoryResponse,
RepairStatusUpdate,
RepairUpdate,
)
from app.services.repair_service import RepairService
router = APIRouter(tags=["Repairs"])
def get_repair_or_404(db: Session, repair_id: int) -> Repair:
repair = RepairRepository.get_by_id(db, repair_id)
if repair is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Reparatur nicht gefunden")
return repair
@router.get("/repairs", response_model=RepairListResponse)
@router.get("/repairs/", response_model=RepairListResponse, include_in_schema=False)
def get_repairs(
status_filter: str | None = Query(default=None, alias="status"),
q: str | None = None,
customer_id: int | None = None,
source: str | None = None,
priority: str | None = None,
limit: int = Query(default=50, ge=1, le=100),
offset: int = Query(default=0, ge=0),
db: Session = Depends(get_db),
current_user: User = Depends(require_permission("repairs.read")),
):
items, total = RepairRepository.list(
db,
status=status_filter,
q=q,
customer_id=customer_id,
source=source,
priority=priority,
limit=limit,
offset=offset,
)
return RepairListResponse(items=items, total=total, limit=limit, offset=offset)
@router.get("/repairs/{repair_id}", response_model=RepairResponse)
def get_repair(
repair_id: int,
db: Session = Depends(get_db),
current_user: User = Depends(require_permission("repairs.read")),
):
return get_repair_or_404(db, repair_id)
@router.post("/repairs", response_model=RepairResponse, status_code=status.HTTP_201_CREATED)
@router.post("/repairs/", response_model=RepairResponse, status_code=status.HTTP_201_CREATED, include_in_schema=False)
def create_repair(
repair: RepairCreate,
request: Request,
db: Session = Depends(get_db),
current_user: User = Depends(require_permission("repairs.create")),
):
return RepairService.create(db, repair, actor=current_user, request=request)
@router.put("/repairs/{repair_id}", response_model=RepairResponse)
def update_repair(
repair_id: int,
repair: RepairUpdate,
request: Request,
db: Session = Depends(get_db),
current_user: User = Depends(require_permission("repairs.update")),
):
db_repair = get_repair_or_404(db, repair_id)
return RepairService.update(db, db_repair, repair, actor=current_user, request=request)
@router.delete("/repairs/{repair_id}", response_model=RepairResponse)
def delete_repair(
repair_id: int,
request: Request,
db: Session = Depends(get_db),
current_user: User = Depends(require_permission("repairs.delete")),
):
db_repair = get_repair_or_404(db, repair_id)
return RepairService.cancel(db, db_repair, actor=current_user, request=request)
@router.put("/repairs/{repair_id}/status", response_model=RepairResponse)
def update_repair_status(
repair_id: int,
payload: RepairStatusUpdate,
request: Request,
db: Session = Depends(get_db),
current_user: User = Depends(require_permission("repairs.status.update")),
):
db_repair = get_repair_or_404(db, repair_id)
return RepairService.update_status(db, db_repair, payload, actor=current_user, request=request)
@router.get("/repairs/{repair_id}/history", response_model=list[RepairStatusHistoryResponse])
def get_repair_history(
repair_id: int,
db: Session = Depends(get_db),
current_user: User = Depends(require_permission("repairs.read")),
):
get_repair_or_404(db, repair_id)
return RepairRepository.get_history(db, repair_id)
@router.post("/public/repair-intake", response_model=RepairIntakeResponse, status_code=status.HTTP_201_CREATED)
def create_repair_intake(
payload: RepairIntakePayload,
request: Request,
x_olympus_intake_token: str | None = Header(default=None, alias="X-Olympus-Intake-Token"),
db: Session = Depends(get_db),
):
expected_token = settings.olympus_repair_intake_token
if not expected_token or not x_olympus_intake_token or x_olympus_intake_token != expected_token:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Nicht autorisiert")
repair = RepairService.create_from_intake(db, payload, request=request)
return RepairIntakeResponse(
repair_number=repair.repair_number,
status=cast(RepairStatus, repair.status),
message="Reparaturanfrage übernommen",
)