artifacts-dashboard/backend/app/api/deps.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

47 lines
1.6 KiB
Python

"""Shared FastAPI dependencies for API endpoints."""
import hashlib
from fastapi import HTTPException, Request
from app.services.artifacts_client import ArtifactsClient
def get_user_client(request: Request) -> ArtifactsClient:
"""Return an ArtifactsClient scoped to the requesting user's token.
Reads the ``X-API-Token`` header sent by the frontend and creates a
lightweight clone of the global client that uses that token. Falls
back to the global client when no per-request token is provided (e.g.
for public / unauthenticated endpoints).
"""
token = request.headers.get("X-API-Token")
base_client: ArtifactsClient = request.app.state.artifacts_client
if token:
return base_client.with_token(token)
# No per-request token — use the global client if it has a token
if base_client.has_token:
return base_client
raise HTTPException(status_code=401, detail="No API token provided")
async def get_user_character_names(request: Request) -> list[str]:
"""Return the character names belonging to the requesting user.
Calls the Artifacts API with the user's token to get their characters,
then returns just the names. Used to scope DB queries to a single user.
"""
client = get_user_client(request)
characters = await client.get_characters()
return [c.name for c in characters]
def get_token_hash(request: Request) -> str | None:
"""Return a SHA-256 hash of the user's API token, or None."""
token = request.headers.get("X-API-Token")
if token:
return hashlib.sha256(token.encode()).hexdigest()
return None