""" Work item model for tracking session work activities. Work items represent individual tasks and activities completed during work sessions, with categorization, timing, and billing tracking. """ from datetime import datetime from typing import TYPE_CHECKING, Optional from sqlalchemy import Boolean, CHAR, CheckConstraint, ForeignKey, Index, Integer, String, Text from sqlalchemy.orm import Mapped, mapped_column, relationship from sqlalchemy.sql import func from .base import Base, UUIDMixin if TYPE_CHECKING: from .database_change import DatabaseChange from .deployment import Deployment from .infrastructure_change import InfrastructureChange from .session import Session class WorkItem(Base, UUIDMixin): """ Work item model representing individual work activities during sessions. Tracks detailed work activities completed during a session including categorization, status, timing estimates and actuals, affected systems, and technologies used. Attributes: session_id: Reference to the session this work item belongs to category: Work category (infrastructure, troubleshooting, etc.) title: Brief title of the work item description: Detailed description of the work performed status: Current status of the work item priority: Priority level (critical, high, medium, low) is_billable: Whether this work item is billable estimated_minutes: Estimated time to complete in minutes actual_minutes: Actual time spent in minutes affected_systems: JSON array of affected systems technologies_used: JSON array of technologies used item_order: Sequence order within the session created_at: When the work item was created completed_at: When the work item was completed """ __tablename__ = "work_items" # Foreign keys session_id: Mapped[str] = mapped_column( CHAR(36), ForeignKey("sessions.id", ondelete="CASCADE"), nullable=False, doc="Reference to the session this work item belongs to" ) # Relationships session: Mapped["Session"] = relationship( "Session", back_populates="work_items", doc="Relationship to Session model" ) deployments: Mapped[list["Deployment"]] = relationship( "Deployment", back_populates="work_item", cascade="all, delete-orphan", doc="Relationship to Deployment model" ) database_changes: Mapped[list["DatabaseChange"]] = relationship( "DatabaseChange", back_populates="work_item", cascade="all, delete-orphan", doc="Relationship to DatabaseChange model" ) infrastructure_changes: Mapped[list["InfrastructureChange"]] = relationship( "InfrastructureChange", back_populates="work_item", cascade="all, delete-orphan", doc="Relationship to InfrastructureChange model" ) # Work categorization category: Mapped[str] = mapped_column( String(50), nullable=False, doc="Work category: infrastructure, troubleshooting, configuration, development, maintenance, security, documentation" ) title: Mapped[str] = mapped_column( String(500), nullable=False, doc="Brief title of the work item" ) description: Mapped[str] = mapped_column( Text, nullable=False, doc="Detailed description of the work performed" ) # Status tracking status: Mapped[str] = mapped_column( String(50), default="completed", server_default="completed", nullable=False, doc="Status: completed, in_progress, blocked, pending, deferred" ) priority: Mapped[Optional[str]] = mapped_column( String(20), doc="Priority level: critical, high, medium, low" ) # Billing is_billable: Mapped[bool] = mapped_column( Boolean, default=False, server_default="0", nullable=False, doc="Whether this work item is billable" ) # Time tracking estimated_minutes: Mapped[Optional[int]] = mapped_column( Integer, doc="Estimated time to complete in minutes" ) actual_minutes: Mapped[Optional[int]] = mapped_column( Integer, doc="Actual time spent in minutes" ) # Context data (stored as JSON text) affected_systems: Mapped[Optional[str]] = mapped_column( Text, doc='JSON array of affected systems (e.g., ["jupiter", "172.16.3.20"])' ) technologies_used: Mapped[Optional[str]] = mapped_column( Text, doc='JSON array of technologies used (e.g., ["docker", "mariadb"])' ) # Ordering item_order: Mapped[Optional[int]] = mapped_column( Integer, doc="Sequence order within the session" ) # Timestamps created_at: Mapped[datetime] = mapped_column( nullable=False, server_default=func.now(), doc="When the work item was created" ) completed_at: Mapped[Optional[datetime]] = mapped_column( doc="When the work item was completed" ) # Constraints and indexes __table_args__ = ( CheckConstraint( "category IN ('infrastructure', 'troubleshooting', 'configuration', 'development', 'maintenance', 'security', 'documentation')", name="ck_work_items_category" ), CheckConstraint( "status IN ('completed', 'in_progress', 'blocked', 'pending', 'deferred')", name="ck_work_items_status" ), CheckConstraint( "priority IN ('critical', 'high', 'medium', 'low')", name="ck_work_items_priority" ), Index("idx_work_items_session", "session_id"), Index("idx_work_items_category", "category"), Index("idx_work_items_status", "status"), ) def __repr__(self) -> str: """String representation of the work item.""" return f""