from fastapi import APIRouter, HTTPException from pydantic import BaseModel from typing import Optional, List from api.db.subscription import ( create_subscription, get_subscription_by_user, get_subscription_by_uuid, update_subscription, delete_subscription, list_subscriptions, extend_subscription_by_user, ) import uuid from datetime import datetime, timedelta router = APIRouter(prefix="/subscription", tags=["subscription"]) class SubscriptionInfo(BaseModel): user_id: str uuid: str until: datetime active: bool subscription_link: Optional[str] = None connect_link: Optional[str] = None class SubscriptionCreate(BaseModel): user_id: str months: int subscription_link: Optional[str] = None connect_link: Optional[str] = None class SubscriptionUpdate(BaseModel): until: Optional[datetime] user_id: Optional[str] active: Optional[bool] = None subscription_link: Optional[str] = None connect_link: Optional[str] = None @router.get("/{user_id}", response_model=Optional[SubscriptionInfo]) async def get_user_subscription(user_id: str): sub = await get_subscription_by_user(user_id) if not sub: return None return SubscriptionInfo(user_id=sub.user_id, uuid=sub.uuid, until=sub.until) @router.post("/new", response_model=SubscriptionInfo) async def create_subscription_endpoint(data: SubscriptionCreate): sub_id = str(uuid.uuid4()) until = datetime.now() + timedelta(days=30 * data.months) sub = await create_subscription(data.user_id, sub_id, until, subscription_link=data.subscription_link, connect_link=data.connect_link, active=True) return SubscriptionInfo(user_id=sub.user_id, uuid=sub.uuid, until=sub.until) @router.post("/extend", response_model=SubscriptionInfo) async def extend_user_subscription(data: SubscriptionCreate): sub = await extend_subscription_by_user(data.user_id, data.months) if not sub: raise HTTPException(status_code=404, detail="Subscription not found") return SubscriptionInfo(user_id=sub.user_id, uuid=sub.uuid, until=sub.until, active=sub.active, subscription_link=sub.subscription_link, connect_link=sub.connect_link) @router.get("/by-uuid/{sub_uuid}", response_model=Optional[SubscriptionInfo]) async def get_subscription_uuid(sub_uuid: str): sub = await get_subscription_by_uuid(sub_uuid) if not sub: raise HTTPException(status_code=404, detail="Subscription not found") return SubscriptionInfo(user_id=sub.user_id, uuid=sub.uuid, until=sub.until, active=sub.active, subscription_link=sub.subscription_link, connect_link=sub.connect_link) @router.patch("/{sub_uuid}", response_model=SubscriptionInfo) async def update_subscription_endpoint(sub_uuid: str, data: SubscriptionUpdate): sub = await update_subscription(sub_uuid, until=data.until, user_id=data.user_id, active=data.active, subscription_link=data.subscription_link, connect_link=data.connect_link) if not sub: raise HTTPException(status_code=404, detail="Subscription not found") return SubscriptionInfo(user_id=sub.user_id, uuid=sub.uuid, until=sub.until, active=sub.active, subscription_link=sub.subscription_link, connect_link=sub.connect_link) @router.delete("/{sub_uuid}") async def delete_subscription_endpoint(sub_uuid: str): ok = await delete_subscription(sub_uuid) if not ok: raise HTTPException(status_code=404, detail="Subscription not found") return {"ok": True} @router.get("/", response_model=List[SubscriptionInfo]) async def list_all_subscriptions(): subs = await list_subscriptions() return [SubscriptionInfo(user_id=s.user_id, uuid=s.uuid, until=s.until) for s in subs]