Add due date functionality to Todo model
- Add due_date field as nullable DateTime with timezone support - Add is_overdue property to check if task is overdue - Add days_until_due property for time calculations - Create migration 007 to add due_date column with index - Maintain backward compatibility with nullable due_date
This commit is contained in:
parent
ab8e9a826d
commit
7251fea2ba
32
alembic/versions/007_add_due_date.py
Normal file
32
alembic/versions/007_add_due_date.py
Normal file
@ -0,0 +1,32 @@
|
||||
"""Add due_date field to todos table
|
||||
|
||||
Revision ID: 007
|
||||
Revises: 006
|
||||
Create Date: 2025-06-19 12:00:00.000000
|
||||
|
||||
"""
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = "007"
|
||||
down_revision = "006"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# Add due_date column to todos table
|
||||
op.add_column(
|
||||
"todos",
|
||||
sa.Column("due_date", sa.DateTime(timezone=True), nullable=True),
|
||||
)
|
||||
|
||||
# Add index for better performance on due date queries
|
||||
op.create_index(op.f("ix_todos_due_date"), "todos", ["due_date"], unique=False)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.drop_index(op.f("ix_todos_due_date"), table_name="todos")
|
||||
op.drop_column("todos", "due_date")
|
@ -2,6 +2,8 @@ from sqlalchemy import Column, Integer, String, Boolean, DateTime, Enum, Foreign
|
||||
from sqlalchemy.orm import relationship
|
||||
from sqlalchemy.sql import func
|
||||
import enum
|
||||
from datetime import datetime, timezone
|
||||
from typing import Optional
|
||||
|
||||
from app.db.base import Base
|
||||
|
||||
@ -23,6 +25,7 @@ class Todo(Base):
|
||||
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)
|
||||
due_date = Column(DateTime(timezone=True), nullable=True)
|
||||
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
||||
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
|
||||
|
||||
@ -42,3 +45,25 @@ class Todo(Base):
|
||||
def is_subtask(self) -> bool:
|
||||
"""Check if this todo is a subtask of another todo."""
|
||||
return self.parent_id is not None
|
||||
|
||||
@property
|
||||
def is_overdue(self) -> bool:
|
||||
"""Check if this todo is overdue."""
|
||||
if self.due_date is None or self.completed:
|
||||
return False
|
||||
return datetime.now(timezone.utc) > self.due_date
|
||||
|
||||
@property
|
||||
def days_until_due(self) -> Optional[int]:
|
||||
"""Calculate the number of days until the due date.
|
||||
|
||||
Returns:
|
||||
int: Number of days until due (negative if overdue)
|
||||
None: If no due date is set
|
||||
"""
|
||||
if self.due_date is None:
|
||||
return None
|
||||
|
||||
now = datetime.now(timezone.utc)
|
||||
delta = (self.due_date - now).days
|
||||
return delta
|
Loading…
x
Reference in New Issue
Block a user