59 lines
1.9 KiB
Python
59 lines
1.9 KiB
Python
from fastapi import APIRouter, Depends, Query
|
|
from sqlalchemy import and_, or_, select
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from ..cursors import decode, decode_datetime, encode
|
|
from ..db import get_session
|
|
from ..models import NotificationOutbox
|
|
from ..schemas import NotificationOutboxItem, OutboxPage
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
@router.get("/notifiers/outbox", response_model=OutboxPage)
|
|
async def list_outbox(
|
|
state: str | None = Query(default=None),
|
|
cursor: str | None = Query(default=None, max_length=512),
|
|
limit: int = Query(default=100, ge=1, le=500),
|
|
session: AsyncSession = Depends(get_session),
|
|
) -> OutboxPage:
|
|
stmt = select(NotificationOutbox).order_by(
|
|
NotificationOutbox.created_at.desc(), NotificationOutbox.id.desc()
|
|
)
|
|
if state is not None:
|
|
stmt = stmt.where(NotificationOutbox.state == state)
|
|
if cursor is not None:
|
|
ts_str, last_id = decode(cursor, 2)
|
|
ts = decode_datetime(ts_str)
|
|
stmt = stmt.where(
|
|
or_(
|
|
NotificationOutbox.created_at < ts,
|
|
and_(
|
|
NotificationOutbox.created_at == ts,
|
|
NotificationOutbox.id < last_id,
|
|
),
|
|
)
|
|
)
|
|
rows = (await session.execute(stmt.limit(limit + 1))).scalars().all()
|
|
next_cursor = None
|
|
if len(rows) > limit:
|
|
rows = rows[:limit]
|
|
next_cursor = encode(rows[-1].created_at.isoformat(), rows[-1].id)
|
|
return OutboxPage(
|
|
items=[
|
|
NotificationOutboxItem(
|
|
id=str(r.id),
|
|
notifier=r.notifier,
|
|
state=r.state,
|
|
incident_id=str(r.incident_id),
|
|
event_type=r.event_type,
|
|
attempts=r.attempts,
|
|
next_attempt_at=r.next_attempt_at,
|
|
last_error=r.last_error,
|
|
updated_at=r.updated_at,
|
|
)
|
|
for r in rows
|
|
],
|
|
next_cursor=next_cursor,
|
|
)
|