Automated Action 4f7baf8e68 Implement comprehensive Projects system for todo management
- Add Project model with status management (active/archived)
- Create ProjectCreate, ProjectUpdate, ProjectWithTodos schemas
- Implement full CRUD operations for projects with pagination
- Add project filtering by status and search functionality
- Add project_id foreign key to Todo model with relationship
- Update Todo API to support project filtering
- Create archive project endpoint
- Add comprehensive project endpoints:
  - GET /projects - list with filtering
  - POST /projects - create new project
  - GET /projects/{id} - get project with todos
  - PUT /projects/{id} - update project
  - DELETE /projects/{id} - delete project
  - GET /projects/{id}/todos - get project todos
  - PUT /projects/{id}/archive - archive project
- Update README with Projects system documentation
- Add migration for projects table and project_id field
- Clean up imports and remove obsolete tag references

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-06-19 00:11:25 +00:00

45 lines
1.5 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")
# 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