from datetime import datetime, timezone from fastapi import APIRouter, Depends, Query from sqlalchemy import select, and_ from sqlalchemy.ext.asyncio import AsyncSession from app.core.deps import get_db from app.models.promotion import Promotion from app.schemas.promotion import PromotionClick, PromotionOut router = APIRouter() @router.get("/", response_model=list[PromotionOut]) async def list_promotions( position: str = Query(default="home_banner"), db: AsyncSession = Depends(get_db), ): now = datetime.now(timezone.utc) result = await db.execute( select(Promotion).where( and_( Promotion.is_active == True, Promotion.position == position, (Promotion.start_time == None) | (Promotion.start_time <= now), (Promotion.end_time == None) | (Promotion.end_time >= now), ) ).order_by(Promotion.sort_order.asc()) ) items = result.scalars().all() for item in items: item.impressions += 1 await db.commit() return items @router.post("/click") async def record_click( payload: PromotionClick, db: AsyncSession = Depends(get_db), ): result = await db.execute( select(Promotion).where(Promotion.id == payload.promotion_id) ) promo = result.scalar_one_or_none() if promo: promo.clicks += 1 await db.commit() return {"code": 0, "message": "ok"}