Arag / app /admin /routers /dashboard.py
AuthorBot
Refactor admin API into service and repository layers.
d6061d6
Raw
History Blame Contribute Delete
4.57 kB
"""admin/routers/dashboard.py — Sessions, transcripts, and message moderation.
Routes:
GET /{slug}/dashboard
GET /{slug}/sessions
GET /{slug}/sessions/search
POST /{slug}/sessions/{id}/block
POST /{slug}/sessions/{id}/unblock
GET /{slug}/sessions/{id}/transcript
POST /{slug}/sessions/{id}/messages/{mid}/annotate
POST /{slug}/sessions/{id}/messages/{mid}/flag
"""
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.ext.asyncio import AsyncSession
from app.dependencies import get_db, get_current_author_scoped
from app.schemas.admin import AnnotateRequest, FlagRequest
from app.services.dashboard_service import DashboardService
router = APIRouter()
@router.get("/{author_slug}/dashboard")
async def dashboard(
author_slug: str,
current_user=Depends(get_current_author_scoped),
db: AsyncSession = Depends(get_db),
):
"""Return high-level dashboard stats for the author."""
return await DashboardService(db).get_dashboard_stats(current_user.id)
@router.get("/{author_slug}/sessions")
async def list_sessions(
author_slug: str,
limit: int = Query(50, ge=1, le=200),
offset: int = 0,
current_user=Depends(get_current_author_scoped),
db: AsyncSession = Depends(get_db),
):
"""List reader sessions with pagination."""
return await DashboardService(db).list_sessions(current_user.id, limit, offset)
@router.get("/{author_slug}/sessions/search")
async def search_sessions(
author_slug: str,
q: str = Query("", min_length=0, max_length=200),
page: int = Query(1, ge=1),
per_page: int = Query(20, ge=1, le=100),
current_user=Depends(get_current_author_scoped),
db: AsyncSession = Depends(get_db),
):
"""Full-text search across chat messages for the author."""
return await DashboardService(db).search_sessions(current_user.id, q, page, per_page)
@router.post("/{author_slug}/sessions/{session_id}/block")
async def block_session(
author_slug: str,
session_id: str,
current_user=Depends(get_current_author_scoped),
db: AsyncSession = Depends(get_db),
):
"""Block a visitor session."""
if not await DashboardService(db).block_session(current_user.id, session_id):
raise HTTPException(404, "Session not found")
return {"message": "Session blocked"}
@router.post("/{author_slug}/sessions/{session_id}/unblock")
async def unblock_session(
author_slug: str,
session_id: str,
current_user=Depends(get_current_author_scoped),
db: AsyncSession = Depends(get_db),
):
"""Unblock a visitor session."""
if not await DashboardService(db).unblock_session(current_user.id, session_id):
raise HTTPException(404, "Session not found")
return {"message": "Session unblocked"}
@router.get("/{author_slug}/sessions/{session_id}/transcript")
async def get_transcript(
author_slug: str,
session_id: str,
page: int = Query(1, ge=1),
per_page: int = Query(50, ge=1, le=200),
current_user=Depends(get_current_author_scoped),
db: AsyncSession = Depends(get_db),
):
"""Return paginated message transcript for a session."""
result = await DashboardService(db).get_transcript(
current_user.id, session_id, page, per_page,
)
if result is None:
raise HTTPException(404, "Session not found")
return result
@router.post("/{author_slug}/sessions/{session_id}/messages/{message_id}/annotate")
async def annotate_message(
author_slug: str,
session_id: str,
message_id: str,
body: AnnotateRequest,
current_user=Depends(get_current_author_scoped),
db: AsyncSession = Depends(get_db),
):
"""Add admin annotation to a chat message (append-only). R-029: Schema validated."""
result = await DashboardService(db).annotate_message(
current_user.id, session_id, message_id, body.annotation,
)
if result is None:
raise HTTPException(404, "Message not found")
return result
@router.post("/{author_slug}/sessions/{session_id}/messages/{message_id}/flag")
async def flag_message(
author_slug: str,
session_id: str,
message_id: str,
body: FlagRequest,
current_user=Depends(get_current_author_scoped),
db: AsyncSession = Depends(get_db),
):
"""Flag a message as spam, quality issue, or escalation. R-029: Schema validated."""
result = await DashboardService(db).flag_message(
current_user.id, session_id, message_id, body.flag_type,
)
if result is None:
raise HTTPException(404, "Message not found")
return result