mirror of
https://github.com/TronoSfera/Law.git
synced 2026-05-18 18:13:46 +03:00
120 lines
3.7 KiB
Python
120 lines
3.7 KiB
Python
from __future__ import annotations
|
|
|
|
import uuid
|
|
|
|
from fastapi import APIRouter, Depends, HTTPException, Query
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.core.deps import require_role
|
|
from app.db.session import get_db
|
|
from app.schemas.admin import NotificationsReadAll
|
|
from app.services.notifications import (
|
|
get_admin_notification,
|
|
list_admin_notifications,
|
|
mark_admin_notifications_read,
|
|
serialize_notification,
|
|
)
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
def _actor_uuid_or_401(admin: dict) -> uuid.UUID:
|
|
try:
|
|
return uuid.UUID(str(admin.get("sub") or ""))
|
|
except ValueError:
|
|
raise HTTPException(status_code=401, detail="Некорректный токен")
|
|
|
|
|
|
def _optional_uuid_or_400(raw: str | None, field_name: str) -> uuid.UUID | None:
|
|
if raw is None:
|
|
return None
|
|
value = str(raw).strip()
|
|
if not value:
|
|
return None
|
|
try:
|
|
return uuid.UUID(value)
|
|
except ValueError:
|
|
raise HTTPException(status_code=400, detail=f'Некорректный "{field_name}"')
|
|
|
|
|
|
@router.get("")
|
|
def list_notifications(
|
|
unread_only: bool = Query(default=False),
|
|
limit: int = Query(default=50, ge=1, le=200),
|
|
offset: int = Query(default=0, ge=0),
|
|
request_id: str | None = Query(default=None),
|
|
db: Session = Depends(get_db),
|
|
admin: dict = Depends(require_role("ADMIN", "LAWYER")),
|
|
):
|
|
actor_id = _actor_uuid_or_401(admin)
|
|
request_uuid = _optional_uuid_or_400(request_id, "request_id")
|
|
rows, total = list_admin_notifications(
|
|
db,
|
|
admin_user_id=actor_id,
|
|
unread_only=unread_only,
|
|
request_id=request_uuid,
|
|
limit=limit,
|
|
offset=offset,
|
|
)
|
|
_, unread_total = list_admin_notifications(
|
|
db,
|
|
admin_user_id=actor_id,
|
|
unread_only=True,
|
|
request_id=request_uuid,
|
|
limit=1,
|
|
offset=0,
|
|
)
|
|
return {
|
|
"rows": [serialize_notification(row) for row in rows],
|
|
"total": total,
|
|
"unread_total": int(unread_total),
|
|
}
|
|
|
|
|
|
@router.post("/{notification_id}/read")
|
|
def read_single_notification(
|
|
notification_id: str,
|
|
db: Session = Depends(get_db),
|
|
admin: dict = Depends(require_role("ADMIN", "LAWYER")),
|
|
):
|
|
actor_id = _actor_uuid_or_401(admin)
|
|
try:
|
|
notification_uuid = uuid.UUID(str(notification_id))
|
|
except ValueError:
|
|
raise HTTPException(status_code=400, detail="Некорректный notification_id")
|
|
|
|
row = get_admin_notification(db, admin_user_id=actor_id, notification_id=notification_uuid)
|
|
if row is None:
|
|
raise HTTPException(status_code=404, detail="Уведомление не найдено")
|
|
|
|
changed = mark_admin_notifications_read(
|
|
db,
|
|
admin_user_id=actor_id,
|
|
notification_id=notification_uuid,
|
|
responsible=str(admin.get("email") or "").strip() or "Администратор системы",
|
|
)
|
|
db.commit()
|
|
refreshed = get_admin_notification(db, admin_user_id=actor_id, notification_id=notification_uuid)
|
|
return {
|
|
"status": "ok",
|
|
"changed": int(changed),
|
|
"notification": serialize_notification(refreshed) if refreshed else None,
|
|
}
|
|
|
|
|
|
@router.post("/read-all")
|
|
def read_all_notifications(
|
|
payload: NotificationsReadAll,
|
|
db: Session = Depends(get_db),
|
|
admin: dict = Depends(require_role("ADMIN", "LAWYER")),
|
|
):
|
|
actor_id = _actor_uuid_or_401(admin)
|
|
request_uuid = _optional_uuid_or_400(payload.request_id, "request_id")
|
|
changed = mark_admin_notifications_read(
|
|
db,
|
|
admin_user_id=actor_id,
|
|
request_id=request_uuid,
|
|
responsible=str(admin.get("email") or "").strip() or "Администратор системы",
|
|
)
|
|
db.commit()
|
|
return {"status": "ok", "changed": int(changed)}
|