"""Schemas for Forgejo issue operations.""" from __future__ import annotations from datetime import datetime from typing import Any, Literal from uuid import UUID from sqlmodel import SQLModel class ForgejoIssueBase(SQLModel): """Shared issue fields used across create/read payloads.""" forgejo_issue_number: int title: str body: str | None = None body_preview: str | None = None state: str is_pull_request: bool labels: list[dict[str, Any]] = [] assignees: list[dict[str, Any]] = [] milestone: dict[str, Any] | None = None author: str html_url: str forgejo_created_at: datetime forgejo_updated_at: datetime forgejo_closed_at: datetime | None = None class ForgejoIssueCreate(ForgejoIssueBase): """Payload for creating a Forgejo issue record.""" class ForgejoIssueRead(ForgejoIssueBase): """Issue payload returned from read endpoints.""" id: UUID organization_id: UUID repository_id: UUID created_at: datetime updated_at: datetime class ForgejoIssueDetailRead(ForgejoIssueRead): """Issue detail payload including full cached Forgejo source payload.""" forgejo_payload: dict[str, Any] | None = None forgejo_comments_payload: list[dict[str, Any]] = [] forgejo_timeline_payload: list[dict[str, Any]] = [] forgejo_reactions_payload: list[dict[str, Any]] = [] class ForgejoIssueListResponse(SQLModel): """Paginated list response for issues.""" items: list[ForgejoIssueRead] total: int page: int limit: int class ForgejoIssueUpsertResponse(SQLModel): """Response for issue sync operations.""" created: int = 0 updated: int = 0 open: int = 0 closed: int = 0 total: int = 0 class CloseIssueResponse(SQLModel): """Response for issue close operations.""" success: bool issue_id: UUID forgejo_issue_number: int state: str forgejo_closed_at: str | None = None last_synced_at: str class CreateIssueRequest(SQLModel): """Request body for creating a new Forgejo issue.""" repository_id: UUID title: str body: str class CreateIssueResponse(SQLModel): """Response for issue creation.""" success: bool issue_id: UUID forgejo_issue_number: int html_url: str repository_id: UUID class PostCommentRequest(SQLModel): """Request body for posting a comment on an issue.""" body: str class PostCommentResponse(SQLModel): """Response for comment post operations.""" success: bool issue_id: UUID comment_id: int | str | None = None body: str created_at: str class EditIssueRequest(SQLModel): """Request body for editing an issue. All fields are optional.""" title: str | None = None body: str | None = None state: str | None = None class EditIssueResponse(SQLModel): """Response for issue edit operations.""" success: bool issue_id: UUID forgejo_issue_number: int title: str body: str | None = None state: str forgejo_updated_at: str class ForgejoIssueTaskRequest(SQLModel): """Request to create or update a Pipeline task for a Forgejo issue.""" board_id: UUID | None = None assigned_agent_id: UUID | None = None priority: str = "medium" status: Literal["inbox", "in_progress"] | None = None start_immediately: bool = True instructions: str | None = None class ForgejoIssueTaskResponse(SQLModel): """Response for creating or finding a Pipeline task from a Forgejo issue.""" success: bool created: bool issue_id: UUID task_id: UUID board_id: UUID assigned_agent_id: UUID | None = None status: str title: str