Automated Action d993db2f17 Implement subtasks functionality for todo system
- Add parent_id field to Todo model with self-referential foreign key
- Add parent/children relationships and is_subtask property
- Update TodoCreate/TodoUpdate schemas to include parent_id
- Add subtasks list to Todo schema and create SubtaskCreate schema
- Enhance get_todos CRUD function with parent_id filtering
- Add subtask-specific CRUD functions: get_subtasks, create_subtask, move_subtask
- Add API endpoints for subtask management
- Create migration for adding parent_id column
- Update imports and fix circular dependencies
- Ensure proper cycle prevention and validation

Features added:
- GET /todos/{todo_id}/subtasks - Get all subtasks for a todo
- POST /todos/{todo_id}/subtasks - Create a new subtask
- PUT /subtasks/{subtask_id}/move - Move subtask or convert to main todo
- Query parameter parent_id for filtering by parent
- Query parameter include_subtasks for excluding subtasks from main list
2025-06-19 00:04:18 +00:00

48 lines
1.6 KiB
Python

from sqlalchemy import Column, Integer, String, Boolean, DateTime, Enum, ForeignKey
from sqlalchemy.orm import relationship
from sqlalchemy.sql import func
import enum
from app.db.base import Base
class Priority(str, enum.Enum):
LOW = "low"
MEDIUM = "medium"
HIGH = "high"
class Todo(Base):
__tablename__ = "todos"
id = Column(Integer, primary_key=True, index=True)
title = Column(String(200), nullable=False)
description = Column(String(500), nullable=True)
completed = Column(Boolean, default=False)
priority = Column(Enum(Priority), default=Priority.MEDIUM)
project_id = Column(Integer, ForeignKey("projects.id"), nullable=True)
category_id = Column(Integer, ForeignKey("categories.id"), nullable=True)
parent_id = Column(Integer, ForeignKey("todos.id"), nullable=True)
created_at = Column(DateTime(timezone=True), server_default=func.now())
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
# Relationship to project
project = relationship("Project", back_populates="todos")
# Relationship to category
category = relationship("Category", back_populates="todos")
# Many-to-many relationship with tags
tags = relationship("Tag", secondary="todo_tags", back_populates="todos")
# Self-referential relationship for subtasks
parent = relationship("Todo", remote_side=[id], back_populates="children")
children = relationship(
"Todo", back_populates="parent", cascade="all, delete-orphan"
)
@property
def is_subtask(self) -> bool:
"""Check if this todo is a subtask of another todo."""
return self.parent_id is not None