artifacts-dashboard/backend/app/api/events.py
Paweł Orzech 75313b83c0
Add multi-user workflows/pipelines and error tracking
Add multi-user automation features and per-user error tracking.

- Database migrations: add workflow_configs/workflow_runs (004), app_errors (005), pipeline_configs/pipeline_runs (006), and add user_token_hash to app_errors (007).
- Backend: introduce per-request token handling (X-API-Token) via app.api.deps and update many API routes (auth, automations, bank, characters, dashboard, events, exchange, logs) to use user-scoped Artifacts client and character scoping. Auth endpoints no longer store tokens server-side (validate-only); clear is a no-op on server.
- New Errors API and services: endpoint to list, filter, resolve, and report errors scoped to the requesting user; add error models, schemas, middleware/error handler and error_service for recording/hashing tokens.
- Pipelines & Workflows: add API routers, models, schemas and engine modules (pipeline/worker/coordinator, workflow runner/conditions) and action_executor updates to support workflow/pipeline execution.
- Logs: logs endpoint now prefers fetching recent action logs from the game API (with fallback to local DB), supports paging and filtering, and scopes results to the user.
- Frontend: add pipeline/workflow builders, lists, progress components and hooks (use-errors, use-pipelines, use-workflows), sentry client config, and updates to API client/constants/types.
- Misc: add middleware error handler, various engine strategy tweaks, tests adjusted.

Overall this change enables per-user API tokens, scopes DB queries to each user, introduces pipelines/workflows runtime support, and centralizes application error tracking.
2026-03-01 23:02:34 +01:00

72 lines
2.3 KiB
Python

"""Game events API router."""
import logging
from typing import Any
from fastapi import APIRouter, HTTPException, Query, Request
from httpx import HTTPStatusError
from sqlalchemy import select
from app.api.deps import get_user_client
from app.database import async_session_factory
from app.models.event_log import EventLog
logger = logging.getLogger(__name__)
router = APIRouter(prefix="/api/events", tags=["events"])
@router.get("/")
async def get_active_events(request: Request) -> dict[str, Any]:
"""Get currently active game events from the Artifacts API."""
client = get_user_client(request)
try:
events = await client.get_events()
except HTTPStatusError as exc:
raise HTTPException(
status_code=exc.response.status_code,
detail=f"Artifacts API error: {exc.response.text}",
) from exc
return {"events": events}
@router.get("/history")
async def get_event_history(
request: Request,
event_type: str | None = Query(default=None, description="Filter by event type"),
character_name: str | None = Query(default=None, description="Filter by character"),
limit: int = Query(default=100, ge=1, le=500, description="Max entries to return"),
offset: int = Query(default=0, ge=0, description="Offset for pagination"),
) -> dict[str, Any]:
"""Get historical events from the event log database."""
async with async_session_factory() as db:
stmt = select(EventLog).order_by(EventLog.created_at.desc())
if event_type:
stmt = stmt.where(EventLog.event_type == event_type)
if character_name:
stmt = stmt.where(EventLog.character_name == character_name)
stmt = stmt.offset(offset).limit(limit)
result = await db.execute(stmt)
logs = result.scalars().all()
return {
"events": [
{
"id": log.id,
"event_type": log.event_type,
"event_data": log.event_data,
"character_name": log.character_name,
"map_x": log.map_x,
"map_y": log.map_y,
"created_at": log.created_at.isoformat() if log.created_at else None,
}
for log in logs
],
"limit": limit,
"offset": offset,
}