from sqlalchemy import Column, Integer, String, ForeignKey, Table, DateTime, Enum from sqlalchemy.orm import relationship from sqlalchemy.sql import func from .database import Base task_tags = Table( "task_tags", Base.metadata, Column("task_id", String, ForeignKey("tasks.id", ondelete="CASCADE"), primary_key=True), Column("tag", String, ForeignKey("tags.tag", ondelete="CASCADE"), primary_key=True), ) class User(Base): __tablename__ = "users" id = Column(String, primary_key=True) name = Column(String, nullable=False) role = Column(String, nullable=False) hue = Column(Integer, nullable=False) initials = Column(String, nullable=False) email = Column(String) phone = Column(String) photo = Column(String) password_hash = Column(String) account_type = Column(String, nullable=False, default="standard") created_at = Column(DateTime(timezone=True), server_default=func.now()) tasks = relationship("Task", back_populates="assignee", foreign_keys="Task.assignee_id") notes = relationship("TaskNote", back_populates="author") class Task(Base): __tablename__ = "tasks" id = Column(String, primary_key=True) title = Column(String, nullable=False) description = Column(String) assignee_id = Column(String, ForeignKey("users.id"), nullable=False) added_by = Column(String, nullable=False) priority = Column(String, nullable=False) # low, med, high source = Column(String, nullable=False) # manual, imessage, email, automation status = Column(String, nullable=False, default="open") added_at = Column(DateTime(timezone=True), server_default=func.now()) due_at = Column(DateTime(timezone=True)) reminder_at = Column(DateTime(timezone=True)) deleted_at = Column(DateTime(timezone=True)) assignee = relationship("User", back_populates="tasks", foreign_keys=[assignee_id]) tags = relationship("Tag", secondary=task_tags, back_populates="tasks") notes = relationship("TaskNote", back_populates="task", cascade="all, delete") class Tag(Base): __tablename__ = "tags" tag = Column(String, primary_key=True) tasks = relationship("Task", secondary=task_tags, back_populates="tags") class TaskNote(Base): __tablename__ = "task_notes" id = Column(Integer, primary_key=True, index=True) task_id = Column(String, ForeignKey("tasks.id", ondelete="CASCADE"), nullable=False) author_id = Column(String, ForeignKey("users.id"), nullable=False) body = Column(String, nullable=False) created_at = Column(DateTime(timezone=True), server_default=func.now()) task = relationship("Task", back_populates="notes") author = relationship("User", back_populates="notes") class AuditLog(Base): __tablename__ = "audit_log" id = Column(String, primary_key=True) at = Column(DateTime(timezone=True), server_default=func.now()) actor = Column(String, nullable=False) action = Column(String, nullable=False) summary = Column(String, nullable=False) target = Column(String) class Session(Base): __tablename__ = "sessions" id = Column(Integer, primary_key=True, index=True) user_id = Column(String, ForeignKey("users.id"), nullable=False) device = Column(String, nullable=False) location = Column(String) last_active = Column(DateTime(timezone=True), server_default=func.now()) class Workspace(Base): __tablename__ = "workspace" id = Column(String, primary_key=True) name = Column(String, nullable=False) timezone = Column(String, nullable=False, default="Pacific/Auckland")