import uuid from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.ext.asyncio import AsyncSession from app.core.deps import get_current_user, get_db_session from app.schemas.notification import ( DesktopNotificationAckRequest, DesktopNotificationClaimRequest, DesktopNotificationClaimResponse, DesktopNotificationSubscriptionRead, DesktopNotificationSubscriptionUpdate, ) from app.services import desktop_notification_service router = APIRouter() @router.get("/subscription", response_model=DesktopNotificationSubscriptionRead) async def read_subscription( db: AsyncSession = Depends(get_db_session), current_user=Depends(get_current_user), ) -> DesktopNotificationSubscriptionRead: subscription = await desktop_notification_service.get_subscription(db, current_user.id) return DesktopNotificationSubscriptionRead( enabled=bool(subscription and subscription.enabled), enabled_at=subscription.enabled_at if subscription else None, ) @router.put("/subscription", response_model=DesktopNotificationSubscriptionRead) async def update_subscription( payload: DesktopNotificationSubscriptionUpdate, db: AsyncSession = Depends(get_db_session), current_user=Depends(get_current_user), ) -> DesktopNotificationSubscriptionRead: subscription = await desktop_notification_service.set_subscription( db, current_user.id, payload.enabled ) return DesktopNotificationSubscriptionRead( enabled=subscription.enabled, enabled_at=subscription.enabled_at, ) @router.post("/claim", response_model=DesktopNotificationClaimResponse) async def claim_notifications( payload: DesktopNotificationClaimRequest, db: AsyncSession = Depends(get_db_session), current_user=Depends(get_current_user), ) -> DesktopNotificationClaimResponse: if payload.limit < 1 or payload.limit > 50: raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail="limit 必须在 1 到 50 之间") claim_token, lease_expires_at, items = await desktop_notification_service.claim_notifications( db, current_user.id, payload.limit ) return DesktopNotificationClaimResponse( claim_token=claim_token, lease_expires_at=lease_expires_at, items=items, ) @router.post("/ack", status_code=status.HTTP_204_NO_CONTENT) async def acknowledge_notifications( payload: DesktopNotificationAckRequest, db: AsyncSession = Depends(get_db_session), current_user=Depends(get_current_user), ) -> None: await desktop_notification_service.acknowledge_notifications( db, current_user.id, payload.claim_token, payload.delivered_ids, ) @router.post("/{distribution_id}/read", status_code=status.HTTP_204_NO_CONTENT) async def mark_notification_read( distribution_id: uuid.UUID, db: AsyncSession = Depends(get_db_session), current_user=Depends(get_current_user), ) -> None: await desktop_notification_service.mark_notification_read( db, current_user.id, distribution_id )