Files
virtual_board_member/app/models/commitment.py
2025-08-07 16:11:14 -04:00

102 lines
3.6 KiB
Python

"""
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"<Commitment(id={self.id}, title='{self.title}', status='{self.status}')>"
@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