feat(coord): add todos system with per-user/machine/project scoping
New coord_todos table and API endpoints (GET/POST/PUT/DELETE /api/coord/todos) supporting manual and auto-created items, sub-tasks via parent_id, and inclusive for_user/for_machine filters (OR-null) for sync/save display. sync.sh Phase 7 now shows pending todos grouped by project after every sync. CLAUDE.md documents auto-creation behavior for unresolved follow-up. Web/email pricing doc updated: block time rate clarified, INKY reference removed, dates updated. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,7 @@ from api.models.coord_work_item import CoordWorkItem
|
||||
from api.models.coord_session_lock import CoordSessionLock
|
||||
from api.models.coord_component_state import CoordComponentState
|
||||
from api.models.coord_message import CoordMessage
|
||||
from api.models.coord_todo import CoordTodo
|
||||
from api.models.backup_log import BackupLog
|
||||
from api.models.base import Base, TimestampMixin, UUIDMixin
|
||||
from api.models.billable_time import BillableTime
|
||||
@@ -57,6 +58,7 @@ __all__ = [
|
||||
"CoordSessionLock",
|
||||
"CoordComponentState",
|
||||
"CoordMessage",
|
||||
"CoordTodo",
|
||||
"BackupLog",
|
||||
"Base",
|
||||
"BillableTime",
|
||||
|
||||
96
api/models/coord_todo.py
Normal file
96
api/models/coord_todo.py
Normal file
@@ -0,0 +1,96 @@
|
||||
"""Coordination personal/project to-do item model."""
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
|
||||
from sqlalchemy import CHAR, Boolean, CheckConstraint, DateTime, ForeignKey, Index, String, Text
|
||||
from sqlalchemy.orm import Mapped, mapped_column
|
||||
|
||||
from .base import Base, TimestampMixin, UUIDMixin
|
||||
|
||||
|
||||
class CoordTodo(Base, UUIDMixin, TimestampMixin):
|
||||
"""A personal or project-scoped to-do item, optionally nested under a parent."""
|
||||
|
||||
__tablename__ = "coord_todos"
|
||||
|
||||
text: Mapped[str] = mapped_column(
|
||||
Text,
|
||||
nullable=False,
|
||||
doc="The to-do item text"
|
||||
)
|
||||
|
||||
project_key: Mapped[Optional[str]] = mapped_column(
|
||||
String(100),
|
||||
doc="Project scope; NULL means personal"
|
||||
)
|
||||
|
||||
parent_id: Mapped[Optional[str]] = mapped_column(
|
||||
CHAR(36),
|
||||
ForeignKey("coord_todos.id", ondelete="CASCADE"),
|
||||
doc="Parent to-do ID for sub-tasks; NULL means top-level"
|
||||
)
|
||||
|
||||
assigned_to_user: Mapped[Optional[str]] = mapped_column(
|
||||
String(50),
|
||||
doc="Target user, e.g. 'mike' or 'howard'; NULL = any user"
|
||||
)
|
||||
|
||||
assigned_to_machine: Mapped[Optional[str]] = mapped_column(
|
||||
String(100),
|
||||
doc="Target hostname; NULL = any machine"
|
||||
)
|
||||
|
||||
auto_created: Mapped[bool] = mapped_column(
|
||||
Boolean,
|
||||
nullable=False,
|
||||
default=False,
|
||||
doc="True when Claude auto-generated this item"
|
||||
)
|
||||
|
||||
source_context: Mapped[Optional[str]] = mapped_column(
|
||||
Text,
|
||||
doc="Why Claude auto-created this item"
|
||||
)
|
||||
|
||||
status: Mapped[str] = mapped_column(
|
||||
String(20),
|
||||
nullable=False,
|
||||
default="pending",
|
||||
doc="Status: pending / done / cancelled"
|
||||
)
|
||||
|
||||
completed_at: Mapped[Optional[datetime]] = mapped_column(
|
||||
DateTime,
|
||||
doc="When the item was marked done"
|
||||
)
|
||||
|
||||
completed_by: Mapped[Optional[str]] = mapped_column(
|
||||
String(100),
|
||||
doc="Session or user that completed the item"
|
||||
)
|
||||
|
||||
created_by_user: Mapped[str] = mapped_column(
|
||||
String(50),
|
||||
nullable=False,
|
||||
doc="User who created the item"
|
||||
)
|
||||
|
||||
created_by_machine: Mapped[str] = mapped_column(
|
||||
String(100),
|
||||
nullable=False,
|
||||
doc="Hostname where the item was created"
|
||||
)
|
||||
|
||||
__table_args__ = (
|
||||
CheckConstraint(
|
||||
"status IN ('pending', 'done', 'cancelled')",
|
||||
name="ck_coord_todos_status",
|
||||
),
|
||||
Index("idx_coord_todos_project_status", "project_key", "status"),
|
||||
Index("idx_coord_todos_assigned", "assigned_to_user", "assigned_to_machine", "status"),
|
||||
Index("idx_coord_todos_parent", "parent_id"),
|
||||
)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"<CoordTodo(status='{self.status}', text='{self.text[:40]}')>"
|
||||
Reference in New Issue
Block a user