""" Pydantic schemas for the issue-core REST API. The TaskIngestionRequest schema matches activity-core's IssueSink TaskSpec payload exactly. See: - SCOPE.md "TaskSpec payload" section - activity-core docs/adr/adr-001-event-bridge-architecture.md """ from typing import List, Literal, Optional from uuid import UUID from pydantic import BaseModel, ConfigDict, Field SourceType = Literal["rule", "instruction"] Priority = Literal["high", "medium", "low"] BackendName = Literal["gitea", "sqlite", "github"] class TaskIngestionRequest(BaseModel): """TaskSpec payload from activity-core's IssueSink (POST /issues/).""" model_config = ConfigDict(extra="forbid") title: str = Field(..., min_length=1, max_length=500) description: str = "" target_repo: str = Field(..., min_length=1) priority: Priority = "medium" labels: List[str] = Field(default_factory=list) due_in_days: Optional[int] = Field(default=None, ge=0) source_type: SourceType source_id: str = Field(..., min_length=1) triggering_event_id: UUID activity_definition_id: str = Field(..., min_length=1) class TaskIngestionResponse(BaseModel): """Response returned to the emitter after a successful ingestion.""" issue_id: str issue_url: Optional[str] = None backend: BackendName class ErrorResponse(BaseModel): """Uniform error envelope.""" error: str detail: Optional[str] = None