Files
2026-07-13 13:32:32 +08:00

68 lines
2.7 KiB
Python

"""Todo 模型 — 结构化子任务。
遵循 Edict Architecture §4 Todo JSON Schema。
支持层级结构(parent_id)和 checkpoint 跟踪。
"""
import uuid
from datetime import datetime, timezone
from sqlalchemy import Column, DateTime, Float, Index, String, Text
from sqlalchemy.dialects.postgresql import JSONB, UUID
from ..db import Base
class Todo(Base):
"""结构化子任务表。"""
__tablename__ = "todos"
todo_id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
trace_id = Column(String(32), nullable=False, index=True, comment="关联任务ID")
parent_id = Column(UUID(as_uuid=True), nullable=True, comment="父级 todo_id(树状结构)")
title = Column(String(256), nullable=False, comment="子任务标题")
description = Column(Text, default="", comment="详细描述")
owner = Column(String(64), default="", comment="负责部门")
assignee_agent = Column(String(32), default="", comment="执行 Agent")
status = Column(String(32), nullable=False, default="open", index=True,
comment="状态: open|in_progress|done|cancelled")
priority = Column(String(16), default="normal", comment="优先级: low|normal|high|urgent")
estimated_cost = Column(Float, default=0.0, comment="预估 token 耗费")
created_by = Column(String(64), default="", comment="创建者")
checkpoints = Column(JSONB, default=list, comment="检查点 [{name, status}]")
metadata_ = Column("metadata", JSONB, default=dict, comment="扩展元数据")
created_at = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), nullable=False)
updated_at = Column(
DateTime(timezone=True),
default=lambda: datetime.now(timezone.utc),
onupdate=lambda: datetime.now(timezone.utc),
nullable=False,
)
__table_args__ = (
Index("ix_todos_trace_status", "trace_id", "status"),
)
def to_dict(self) -> dict:
return {
"todo_id": str(self.todo_id),
"trace_id": self.trace_id,
"parent_id": str(self.parent_id) if self.parent_id else None,
"title": self.title,
"description": self.description,
"owner": self.owner,
"assignee_agent": self.assignee_agent,
"status": self.status,
"priority": self.priority,
"estimated_cost": self.estimated_cost,
"created_by": self.created_by,
"checkpoints": self.checkpoints or [],
"metadata": self.metadata_ or {},
"created_at": self.created_at.isoformat() if self.created_at else "",
"updated_at": self.updated_at.isoformat() if self.updated_at else "",
}