FastAPI + SQLAlchemy/Alembic + MariaDB backend with Jinja2/htmx/Alpine server-rendered frontend. Multi-user via Google OAuth, daily habit tracking, monthly/weekly history views, Web Push reminders via APScheduler, and PWA support (manifest, service worker, offline caching). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
47 lines
1.4 KiB
Python
47 lines
1.4 KiB
Python
from fastapi import APIRouter, Depends, Request
|
|
from pydantic import BaseModel
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.config import settings
|
|
from app.database import get_db
|
|
from app.models.user import User
|
|
from app.schemas.push import PushSubscribeRequest
|
|
from app.security import require_login
|
|
from app.services import push_service
|
|
|
|
router = APIRouter(prefix="/api/push", tags=["push"], dependencies=[Depends(require_login)])
|
|
|
|
|
|
class UnsubscribeRequest(BaseModel):
|
|
endpoint: str
|
|
|
|
|
|
@router.get("/vapid-public-key")
|
|
def get_vapid_public_key():
|
|
return {"publicKey": settings.vapid_public_key}
|
|
|
|
|
|
@router.post("/subscribe")
|
|
def subscribe(
|
|
data: PushSubscribeRequest,
|
|
request: Request,
|
|
db: Session = Depends(get_db),
|
|
current_user: User = Depends(require_login),
|
|
):
|
|
push_service.save_subscription(db, current_user.id, data, user_agent=request.headers.get("user-agent"))
|
|
return {"ok": True}
|
|
|
|
|
|
@router.post("/unsubscribe")
|
|
def unsubscribe(
|
|
data: UnsubscribeRequest, db: Session = Depends(get_db), current_user: User = Depends(require_login)
|
|
):
|
|
push_service.delete_subscription(db, data.endpoint)
|
|
return {"ok": True}
|
|
|
|
|
|
@router.post("/test")
|
|
def send_test(db: Session = Depends(get_db), current_user: User = Depends(require_login)):
|
|
sent = push_service.send_to_user(db, current_user.id, title="습관 트래커", body="테스트 알림입니다.")
|
|
return {"sent": sent}
|