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.
127 lines
3.9 KiB
Python
127 lines
3.9 KiB
Python
from datetime import datetime
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
from app.schemas.workflow import TransitionConditionSchema
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Character step within a stage
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
class CharacterStepSchema(BaseModel):
|
|
"""A single character's work within a pipeline stage."""
|
|
|
|
id: str = Field(..., description="Unique step identifier (e.g. 'cs_1a')")
|
|
character_name: str = Field(..., min_length=1, max_length=100)
|
|
strategy_type: str = Field(
|
|
...,
|
|
description="Strategy type: combat, gathering, crafting, trading, task, leveling",
|
|
)
|
|
config: dict = Field(default_factory=dict, description="Strategy-specific configuration")
|
|
transition: TransitionConditionSchema | None = Field(
|
|
default=None,
|
|
description="Condition for this character-step to be considered done",
|
|
)
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Pipeline stage
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
class PipelineStageSchema(BaseModel):
|
|
"""A stage in the pipeline — character steps within it run in parallel."""
|
|
|
|
id: str = Field(..., description="Unique stage identifier (e.g. 'stage_1')")
|
|
name: str = Field(..., min_length=1, max_length=100)
|
|
character_steps: list[CharacterStepSchema] = Field(..., min_length=1)
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Request schemas
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
class PipelineConfigCreate(BaseModel):
|
|
name: str = Field(..., min_length=1, max_length=100)
|
|
description: str = Field(default="")
|
|
stages: list[PipelineStageSchema] = Field(..., min_length=1)
|
|
loop: bool = Field(default=False)
|
|
max_loops: int = Field(default=0, ge=0)
|
|
|
|
|
|
class PipelineConfigUpdate(BaseModel):
|
|
name: str | None = Field(default=None, min_length=1, max_length=100)
|
|
description: str | None = None
|
|
stages: list[PipelineStageSchema] | None = Field(default=None, min_length=1)
|
|
loop: bool | None = None
|
|
max_loops: int | None = Field(default=None, ge=0)
|
|
enabled: bool | None = None
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Response schemas
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
class PipelineConfigResponse(BaseModel):
|
|
id: int
|
|
name: str
|
|
description: str
|
|
stages: list[dict]
|
|
loop: bool
|
|
max_loops: int
|
|
enabled: bool
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
|
|
model_config = {"from_attributes": True}
|
|
|
|
|
|
class PipelineRunResponse(BaseModel):
|
|
id: int
|
|
pipeline_id: int
|
|
status: str
|
|
current_stage_index: int
|
|
current_stage_id: str
|
|
loop_count: int
|
|
total_actions_count: int
|
|
character_states: dict
|
|
stage_history: list[dict] = Field(default_factory=list)
|
|
started_at: datetime
|
|
stopped_at: datetime | None = None
|
|
error_message: str | None = None
|
|
|
|
model_config = {"from_attributes": True}
|
|
|
|
|
|
class CharacterStateResponse(BaseModel):
|
|
"""Status of a single character within an active pipeline."""
|
|
|
|
character_name: str
|
|
status: str # running, completed, error, idle
|
|
step_id: str = ""
|
|
actions_count: int = 0
|
|
strategy_state: str = ""
|
|
error: str | None = None
|
|
|
|
|
|
class PipelineStatusResponse(BaseModel):
|
|
pipeline_id: int
|
|
status: str
|
|
run_id: int | None = None
|
|
current_stage_index: int = 0
|
|
current_stage_id: str = ""
|
|
total_stages: int = 0
|
|
loop_count: int = 0
|
|
total_actions_count: int = 0
|
|
character_states: list[CharacterStateResponse] = Field(default_factory=list)
|
|
|
|
|
|
class PipelineConfigDetailResponse(BaseModel):
|
|
"""Pipeline config with its run history."""
|
|
|
|
config: PipelineConfigResponse
|
|
runs: list[PipelineRunResponse] = Field(default_factory=list)
|