""" api/push.py -- Web Push (VAPID) subscribe/unsubscribe for the signed-in user's own device. Mirrors api/notifications.py's "scoped to the caller" posture: no login, no subscription (nothing to scope it to). """ from __future__ import annotations from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.orm import Session from app.api.deps import get_current_user, get_db from app.config import settings from app.crud import push as crud from app.models import User from app.schemas.push import PushSubscribeInput, PushUnsubscribeInput, VapidPublicKeyOut router = APIRouter(tags=["push"]) @router.get("/push/vapid-public-key", response_model=VapidPublicKeyOut) def vapid_public_key(): return VapidPublicKeyOut(key=settings.vapid_public_key) @router.post("/push/subscribe") def subscribe( body: PushSubscribeInput, db: Session = Depends(get_db), user: User | None = Depends(get_current_user), ): if user is None: raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Please sign in.") crud.save_subscription(db, user_id=user.id, endpoint=body.endpoint, p256dh=body.p256dh, auth=body.auth) return {"ok": True} @router.post("/push/unsubscribe") def unsubscribe( body: PushUnsubscribeInput, db: Session = Depends(get_db), user: User | None = Depends(get_current_user), ): if user is None: raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Please sign in.") crud.remove_subscription(db, user_id=user.id, endpoint=body.endpoint) return {"ok": True}