할일관리 시스템 구현 완료
주요 기능: - memos/트위터 스타일 할일 입력 - 5단계 워크플로우: draft → scheduled → active → completed/delayed - 2시간 이상 작업 자동 분할 제안 (1분/30분/1시간 선택) - 시작날짜 기반 자동 활성화 - 할일별 댓글/메모 기능 - 개인별 할일 관리 백엔드: - TodoItem, TodoComment 모델 추가 - 완전한 REST API 구현 - 자동 상태 전환 로직 - 분할 기능 지원 프론트엔드: - 직관적인 탭 기반 UI - 실시간 상태 업데이트 - 모달 기반 상세 관리 - 반응형 디자인 데이터베이스: - PostgreSQL 테이블 및 인덱스 생성 - 트리거 기반 자동 업데이트
This commit is contained in:
63
backend/src/models/todo.py
Normal file
63
backend/src/models/todo.py
Normal file
@@ -0,0 +1,63 @@
|
||||
"""
|
||||
할일관리 시스템 모델
|
||||
"""
|
||||
from sqlalchemy import Column, String, DateTime, Text, Boolean, Integer, ForeignKey
|
||||
from sqlalchemy.dialects.postgresql import UUID
|
||||
from sqlalchemy.orm import relationship
|
||||
from datetime import datetime
|
||||
import uuid
|
||||
|
||||
from ..core.database import Base
|
||||
|
||||
|
||||
class TodoItem(Base):
|
||||
"""할일 아이템"""
|
||||
__tablename__ = "todo_items"
|
||||
|
||||
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||
user_id = Column(UUID(as_uuid=True), ForeignKey("users.id"), nullable=False)
|
||||
|
||||
# 기본 정보
|
||||
content = Column(Text, nullable=False) # 할일 내용
|
||||
status = Column(String(20), nullable=False, default="draft") # draft, scheduled, active, completed, delayed
|
||||
|
||||
# 시간 관리
|
||||
created_at = Column(DateTime, nullable=False, default=datetime.utcnow)
|
||||
start_date = Column(DateTime, nullable=True) # 시작 예정일
|
||||
estimated_minutes = Column(Integer, nullable=True) # 예상 소요시간 (분)
|
||||
completed_at = Column(DateTime, nullable=True)
|
||||
delayed_until = Column(DateTime, nullable=True) # 지연된 경우 새로운 시작일
|
||||
|
||||
# 분할 관리
|
||||
parent_id = Column(UUID(as_uuid=True), ForeignKey("todo_items.id"), nullable=True) # 분할된 할일의 부모
|
||||
split_order = Column(Integer, nullable=True) # 분할 순서
|
||||
|
||||
# 관계
|
||||
user = relationship("User", back_populates="todo_items")
|
||||
comments = relationship("TodoComment", back_populates="todo_item", cascade="all, delete-orphan")
|
||||
|
||||
# 자기 참조 관계 (분할된 할일들)
|
||||
subtasks = relationship("TodoItem", backref="parent_task", remote_side=[id])
|
||||
|
||||
def __repr__(self):
|
||||
return f"<TodoItem(id={self.id}, content='{self.content[:50]}...', status='{self.status}')>"
|
||||
|
||||
|
||||
class TodoComment(Base):
|
||||
"""할일 댓글/메모"""
|
||||
__tablename__ = "todo_comments"
|
||||
|
||||
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||
todo_item_id = Column(UUID(as_uuid=True), ForeignKey("todo_items.id"), nullable=False)
|
||||
user_id = Column(UUID(as_uuid=True), ForeignKey("users.id"), nullable=False)
|
||||
|
||||
content = Column(Text, nullable=False)
|
||||
created_at = Column(DateTime, nullable=False, default=datetime.utcnow)
|
||||
updated_at = Column(DateTime, nullable=False, default=datetime.utcnow, onupdate=datetime.utcnow)
|
||||
|
||||
# 관계
|
||||
todo_item = relationship("TodoItem", back_populates="comments")
|
||||
user = relationship("User")
|
||||
|
||||
def __repr__(self):
|
||||
return f"<TodoComment(id={self.id}, content='{self.content[:30]}...')>"
|
||||
@@ -45,6 +45,7 @@ class User(Base):
|
||||
# 관계 (lazy loading을 위해 문자열로 참조)
|
||||
memo_trees = relationship("MemoTree", back_populates="user", lazy="dynamic")
|
||||
memo_nodes = relationship("MemoNode", back_populates="user", lazy="dynamic")
|
||||
todo_items = relationship("TodoItem", back_populates="user", lazy="dynamic")
|
||||
|
||||
def __repr__(self):
|
||||
return f"<User(email='{self.email}', full_name='{self.full_name}')>"
|
||||
|
||||
Reference in New Issue
Block a user