PMFlow/backend/app/schemas/sstc.py

115 lines
2.6 KiB
Python

"""SSTC 看板 schema"""
from __future__ import annotations
from enum import Enum
from typing import Any, Literal, Optional
from pydantic import BaseModel, Field
class SSTCStageKey(str, Enum):
SIGNAL = "signal"
CHARTER = "charter"
TASK = "task"
EXECUTION = "execution"
RELEASE = "release"
REVIEW = "review"
class StageStatus(str, Enum):
# signal
SIGNAL_PENDING = "待处理"
SIGNAL_SYNCED = "已同步"
# charter
CHARTER_DRAFT = "草稿"
CHARTER_ALIGNING = "对齐中"
CHARTER_ALIGNED = "已对齐"
CHARTER_ARCHIVED = "已归档"
# task
TASK_LOCKED = "未解锁"
TASK_PENDING = "待确认"
TASK_CONFIRMED = "已确认"
# execution
EXEC_NOT_STARTED = "未开始"
EXEC_IN_PROGRESS = "进行中"
EXEC_DONE = "已完成"
# release
RELEASE_LOCKED = "未解锁"
RELEASE_PENDING = "待发布"
RELEASE_LIVE = "已上线"
RELEASE_VERIFIED = "已验证"
# review
REVIEW_LOCKED = "未解锁"
REVIEW_DRAFT = "草稿"
REVIEW_ARCHIVED = "已归档"
class StageNode(BaseModel):
key: SSTCStageKey
label: str
status: str
summary: str = ""
locked: bool = False
editable: bool = True
risk_count: int = 0
class ProjectOverview(BaseModel):
project: dict[str, Any]
chain_id: Optional[str] = None
alignment_score: float = 0
pending_alignment_nodes: int = 0
unresolved_conflicts: int = 0
task_progress: dict[str, Any]
workload_health: dict[str, Any]
class BoardOverviewResponse(BaseModel):
overview: ProjectOverview
stages: list[StageNode]
risks: dict[str, Any]
class CharterUpdateRequest(BaseModel):
title: Optional[str] = None
content: Optional[dict[str, Any]] = None
force_new_version: bool = True
class AlignmentStartRequest(BaseModel):
note: Optional[str] = None
class AlignmentConfirmRequest(BaseModel):
score: int = Field(default=80, ge=0, le=100)
confirmed: bool = True
comments: Optional[str] = None
class TaskStatusPatchRequest(BaseModel):
status: Literal["todo", "in_progress", "blocked", "review", "done", "completed"]
class ReleaseCreateRequest(BaseModel):
title: str
charter_id: int
task_ids: list[int] = Field(default_factory=list)
planned_at: Optional[str] = None
class ReleaseStatusPatchRequest(BaseModel):
status: Literal["pending", "releasing", "online", "rolled_back", "verified"]
note: Optional[str] = None
class ReviewCreateRequest(BaseModel):
title: str
release_node_id: int
content: dict[str, Any] = Field(default_factory=dict)
class ReviewArchiveRequest(BaseModel):
archive: bool = True
note: Optional[str] = None