""" Task model for hierarchical task tracking. Tasks represent work items that can be hierarchical, assigned to agents, and tracked across sessions with dependencies and complexity estimates. """ from datetime import datetime from typing import Optional from sqlalchemy import CHAR, CheckConstraint, ForeignKey, Index, Integer, String, Text from sqlalchemy.orm import Mapped, mapped_column, relationship from .base import Base, TimestampMixin, UUIDMixin class Task(Base, UUIDMixin, TimestampMixin): """ Task model representing hierarchical work items. Tasks support parent-child relationships for breaking down complex work, status tracking with blocking reasons, assignment to agents, and complexity estimation. Attributes: parent_task_id: Reference to parent task for hierarchical structure task_order: Order of this task relative to siblings title: Task title description: Detailed task description task_type: Type of task (implementation, research, review, etc.) status: Current status (pending, in_progress, blocked, completed, cancelled) blocking_reason: Reason why task is blocked session_id: Reference to the session this task belongs to client_id: Reference to the client project_id: Reference to the project assigned_agent: Which agent is handling this task estimated_complexity: Complexity estimate (trivial to very_complex) started_at: When the task was started completed_at: When the task was completed task_context: Detailed context for this task (JSON) dependencies: JSON array of dependency task IDs """ __tablename__ = "tasks" # Task hierarchy parent_task_id: Mapped[Optional[str]] = mapped_column( CHAR(36), ForeignKey("tasks.id", ondelete="CASCADE"), doc="Reference to parent task for hierarchical structure" ) task_order: Mapped[int] = mapped_column( Integer, nullable=False, doc="Order of this task relative to siblings" ) # Task details title: Mapped[str] = mapped_column( String(500), nullable=False, doc="Task title" ) description: Mapped[Optional[str]] = mapped_column( Text, doc="Detailed task description" ) task_type: Mapped[Optional[str]] = mapped_column( String(100), doc="Type: implementation, research, review, deployment, testing, documentation, bugfix, analysis" ) # Status tracking status: Mapped[str] = mapped_column( String(50), nullable=False, doc="Status: pending, in_progress, blocked, completed, cancelled" ) blocking_reason: Mapped[Optional[str]] = mapped_column( Text, doc="Reason why task is blocked (if status='blocked')" ) # Context references session_id: Mapped[Optional[str]] = mapped_column( CHAR(36), ForeignKey("sessions.id", ondelete="CASCADE"), doc="Reference to the session this task belongs to" ) client_id: Mapped[Optional[str]] = mapped_column( CHAR(36), ForeignKey("clients.id", ondelete="SET NULL"), doc="Reference to the client" ) project_id: Mapped[Optional[str]] = mapped_column( CHAR(36), ForeignKey("projects.id", ondelete="SET NULL"), doc="Reference to the project" ) assigned_agent: Mapped[Optional[str]] = mapped_column( String(100), doc="Which agent is handling this task" ) # Timing estimated_complexity: Mapped[Optional[str]] = mapped_column( String(20), doc="Complexity: trivial, simple, moderate, complex, very_complex" ) started_at: Mapped[Optional[datetime]] = mapped_column( doc="When the task was started" ) completed_at: Mapped[Optional[datetime]] = mapped_column( doc="When the task was completed" ) # Context data (stored as JSON text) task_context: Mapped[Optional[str]] = mapped_column( Text, doc="Detailed context for this task (JSON)" ) dependencies: Mapped[Optional[str]] = mapped_column( Text, doc="JSON array of dependency task IDs" ) # Constraints and indexes __table_args__ = ( CheckConstraint( "task_type IN ('implementation', 'research', 'review', 'deployment', 'testing', 'documentation', 'bugfix', 'analysis')", name="ck_tasks_type" ), CheckConstraint( "status IN ('pending', 'in_progress', 'blocked', 'completed', 'cancelled')", name="ck_tasks_status" ), CheckConstraint( "estimated_complexity IN ('trivial', 'simple', 'moderate', 'complex', 'very_complex')", name="ck_tasks_complexity" ), Index("idx_tasks_session", "session_id"), Index("idx_tasks_status", "status"), Index("idx_tasks_parent", "parent_task_id"), Index("idx_tasks_client", "client_id"), Index("idx_tasks_project", "project_id"), ) def __repr__(self) -> str: """String representation of the task.""" return f""