Files
JARVIS/backend/app/models/task.py

165 lines
5.3 KiB
Python

from enum import Enum as PyEnum
from sqlalchemy import Column, DateTime, Enum, ForeignKey, Integer, String, Text
from sqlalchemy.orm import relationship
from app.models.base import BaseModel
class TaskStatus(str, PyEnum):
TODO = "todo"
IN_PROGRESS = "in_progress"
DONE = "done"
CANCELLED = "cancelled"
class TaskPriority(str, PyEnum):
LOW = "low"
MEDIUM = "medium"
HIGH = "high"
URGENT = "urgent"
class TaskSource(str, PyEnum):
MANUAL = "manual"
CHAT = "chat"
SCHEDULE_CENTER = "schedule_center"
TODAY_STATUS = "today_status"
COMMANDER = "commander"
class TaskQuadrant(str, PyEnum):
URGENT_IMPORTANT = "urgent-important"
NOT_URGENT_IMPORTANT = "not-urgent-important"
URGENT_NOT_IMPORTANT = "urgent-not-important"
NOT_URGENT_NOT_IMPORTANT = "not-urgent-not-important"
class TaskAssigneeType(str, PyEnum):
USER = "user"
COMMANDER = "commander"
AGENT = "agent"
PLANNER = "planner"
EXECUTOR = "executor"
KNOWLEDGE = "knowledge"
ANALYST = "analyst"
CODER = "coder"
RESEARCHER = "researcher"
class TaskDispatchStatus(str, PyEnum):
IDLE = "idle"
QUEUED = "queued"
RUNNING = "running"
COMPLETED = "completed"
FAILED = "failed"
DispatchStatus = TaskDispatchStatus
DispatchStatus = TaskDispatchStatus
class TaskHistoryAction(str, PyEnum):
CREATED = "created"
CREATED_FROM_CHAT = "created_from_chat"
UPDATED = "updated"
STATUS_CHANGED = "status_changed"
ASSIGNED = "assigned"
DELETED = "deleted"
SUBTASK_CREATED = "subtask_created"
SUBTASK_UPDATED = "subtask_updated"
SUBTASK_DELETED = "subtask_deleted"
SUBTASK_REORDERED = "subtask_reordered"
DISPATCHED_TO_COMMANDER = "dispatched_to_commander"
DISPATCH_STATUS_CHANGED = "dispatch_status_changed"
def enum_values(enum_cls: type[PyEnum]) -> list[str]:
return [item.value for item in enum_cls]
TASK_STATUS_ENUM = Enum(TaskStatus, values_callable=enum_values)
TASK_PRIORITY_ENUM = Enum(TaskPriority, values_callable=enum_values)
TASK_SOURCE_ENUM = Enum(TaskSource, values_callable=enum_values)
TASK_QUADRANT_ENUM = Enum(TaskQuadrant, values_callable=enum_values)
TASK_ASSIGNEE_TYPE_ENUM = Enum(TaskAssigneeType, values_callable=enum_values)
TASK_DISPATCH_STATUS_ENUM = Enum(TaskDispatchStatus, values_callable=enum_values)
class Task(BaseModel):
__tablename__ = "tasks"
user_id = Column(String(36), ForeignKey("users.id"), nullable=False, index=True)
title = Column(String(500), nullable=False)
description = Column(Text, nullable=True)
status = Column(TASK_STATUS_ENUM, default=TaskStatus.TODO, nullable=False, index=True)
priority = Column(TASK_PRIORITY_ENUM, default=TaskPriority.MEDIUM, nullable=False)
due_date = Column(DateTime, nullable=True, index=True)
completed_at = Column(DateTime, nullable=True)
tags = Column(String(1000), nullable=True) # JSON array
source = Column(TASK_SOURCE_ENUM, default=TaskSource.MANUAL, nullable=False, index=True)
conversation_id = Column(String(36), nullable=True, index=True)
quadrant = Column(TASK_QUADRANT_ENUM, nullable=True, index=True)
assignee_type = Column(TASK_ASSIGNEE_TYPE_ENUM, nullable=True, index=True)
assignee_id = Column(String(255), nullable=True, index=True)
dispatch_status = Column(
TASK_DISPATCH_STATUS_ENUM,
default=TaskDispatchStatus.IDLE,
nullable=False,
index=True,
)
dispatch_run_id = Column(String(64), nullable=True, index=True)
result_summary = Column(Text, nullable=True)
started_at = Column(DateTime, nullable=True)
last_synced_at = Column(DateTime, nullable=True)
subtasks = relationship(
"TaskSubTask",
back_populates="task",
cascade="all, delete-orphan",
order_by="TaskSubTask.order_index.asc()",
)
history = relationship(
"TaskHistory",
back_populates="task",
cascade="all, delete-orphan",
order_by="TaskHistory.created_at.desc()",
)
class TaskSubTask(BaseModel):
__tablename__ = "task_subtasks"
task_id = Column(String(36), ForeignKey("tasks.id"), nullable=False, index=True)
title = Column(String(500), nullable=False)
description = Column(Text, nullable=True)
status = Column(TASK_STATUS_ENUM, default=TaskStatus.TODO, nullable=False, index=True)
order_index = Column(Integer, default=0, nullable=False, index=True)
assignee_type = Column(TASK_ASSIGNEE_TYPE_ENUM, nullable=True, index=True)
assignee_id = Column(String(255), nullable=True, index=True)
dispatch_status = Column(
TASK_DISPATCH_STATUS_ENUM,
default=TaskDispatchStatus.IDLE,
nullable=False,
index=True,
)
dispatch_run_id = Column(String(64), nullable=True, index=True)
result_summary = Column(Text, nullable=True)
completed_at = Column(DateTime, nullable=True)
task = relationship("Task", back_populates="subtasks")
class TaskHistory(BaseModel):
__tablename__ = "task_histories"
task_id = Column(String(36), ForeignKey("tasks.id"), nullable=False, index=True)
subtask_id = Column(String(36), ForeignKey("task_subtasks.id"), nullable=True, index=True)
action = Column(String(100), nullable=False)
old_value = Column(Text, nullable=True)
new_value = Column(Text, nullable=True)
task = relationship("Task", back_populates="history")