""" Commitment models for the Virtual Board Member AI System. """ from datetime import datetime from typing import Optional from sqlalchemy import Column, String, DateTime, Boolean, Text, Integer, ForeignKey, Date from sqlalchemy.dialects.postgresql import UUID, JSONB from sqlalchemy.orm import relationship import uuid import enum from app.core.database import Base class CommitmentStatus(str, enum.Enum): """Commitment status enumeration.""" PENDING = "pending" IN_PROGRESS = "in_progress" COMPLETED = "completed" OVERDUE = "overdue" CANCELLED = "cancelled" DEFERRED = "deferred" class CommitmentPriority(str, enum.Enum): """Commitment priority levels.""" LOW = "low" MEDIUM = "medium" HIGH = "high" CRITICAL = "critical" class Commitment(Base): """Commitment model for tracking board and executive commitments.""" __tablename__ = "commitments" id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) # Commitment details title = Column(String(500), nullable=False, index=True) description = Column(Text, nullable=True) commitment_text = Column(Text, nullable=False) # Original text from document # Status and priority status = Column(String(50), default=CommitmentStatus.PENDING, nullable=False) priority = Column(String(20), default=CommitmentPriority.MEDIUM, nullable=False) # Dates due_date = Column(Date, nullable=True) completion_date = Column(Date, nullable=True) # Assignment assigned_to = Column(UUID(as_uuid=True), ForeignKey("users.id"), nullable=True) assigned_by = Column(UUID(as_uuid=True), ForeignKey("users.id"), nullable=True) # Source information document_id = Column(UUID(as_uuid=True), ForeignKey("documents.id"), nullable=False) document_page = Column(Integer, nullable=True) # Page number in document document_section = Column(String(200), nullable=True) # Section/context # AI extraction metadata confidence_score = Column(Integer, nullable=True) # 0-100 confidence in extraction extraction_method = Column(String(50), nullable=True) # LLM, rule-based, etc. extraction_metadata = Column(JSONB, nullable=True) # Additional extraction info # Progress tracking progress_notes = Column(Text, nullable=True) progress_percentage = Column(Integer, default=0) # 0-100 # Notifications reminder_enabled = Column(Boolean, default=True) reminder_frequency = Column(String(50), default="weekly") # daily, weekly, monthly # Timestamps created_at = Column(DateTime, default=datetime.utcnow, nullable=False) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False) # Relationships document = relationship("Document", back_populates="commitments") assigned_user = relationship("User", foreign_keys=[assigned_to]) assigned_by_user = relationship("User", foreign_keys=[assigned_by]) def __repr__(self): return f"" @property def is_overdue(self) -> bool: """Check if commitment is overdue.""" if self.due_date and self.status not in [CommitmentStatus.COMPLETED, CommitmentStatus.CANCELLED]: return datetime.now().date() > self.due_date return False @property def days_until_due(self) -> Optional[int]: """Get days until due date.""" if self.due_date: delta = self.due_date - datetime.now().date() return delta.days return None