news: clamp free + anonymous to last 6h; paid keeps 24h

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Giorgio Gilestro 2026-05-25 22:49:21 +02:00
parent a7d657e1b4
commit 671faed707
4 changed files with 96 additions and 3 deletions

View file

@ -19,7 +19,7 @@ from collections import defaultdict
import httpx
from pydantic import BaseModel, Field
from app.auth import require_token
from app.auth import require_token, maybe_current_user, CurrentUser
from app.config import get_settings
from app.db import get_session, utcnow
from app.services.openrouter import (
@ -228,11 +228,18 @@ async def news_list(
limit: int = Query(50, ge=1, le=500),
tags: str | None = Query(None, description="comma-separated include list"),
exclude_tags: str | None = Query(None, description="comma-separated exclude list"),
principal: CurrentUser | None = Depends(maybe_current_user),
as_: str | None = Query(default=None, alias="as"),
):
from app.services.news_tagging import TAG_LABELS, TAG_VOCABULARY
from app.services.access import FREE_NEWS_WINDOW_HOURS, is_paid_active
cutoff = utcnow() - timedelta(hours=since_hours)
effective_hours = since_hours
capped = not is_paid_active(principal)
if capped:
effective_hours = min(since_hours, FREE_NEWS_WINDOW_HOURS)
cutoff = utcnow() - timedelta(hours=effective_hours)
stmt = select(Headline).where(Headline.published_at >= cutoff)
if category:
stmt = stmt.where(Headline.category == category)
@ -275,7 +282,9 @@ async def news_list(
"tag_vocabulary": TAG_VOCABULARY,
"tag_labels": TAG_LABELS,
"active_include": sorted(include),
"active_exclude": sorted(exclude)},
"active_exclude": sorted(exclude),
"capped": capped,
"window_hours": effective_hours},
)
return [HeadlineOut.model_validate(r, from_attributes=True) for r in filtered]