from sqlalchemy import Column, Integer, String, DateTime, Boolean, Text, Enum, ForeignKey, JSON from sqlalchemy.orm import relationship from datetime import datetime import enum from ..config.database import Base class WorkflowType(str, enum.Enum): pre_arrival = 'pre_arrival' room_preparation = 'room_preparation' maintenance = 'maintenance' guest_communication = 'guest_communication' follow_up = 'follow_up' custom = 'custom' class WorkflowStatus(str, enum.Enum): active = 'active' inactive = 'inactive' archived = 'archived' class WorkflowTrigger(str, enum.Enum): booking_created = 'booking_created' booking_confirmed = 'booking_confirmed' check_in = 'check_in' check_out = 'check_out' maintenance_request = 'maintenance_request' guest_message = 'guest_message' manual = 'manual' scheduled = 'scheduled' class Workflow(Base): __tablename__ = 'workflows' id = Column(Integer, primary_key=True, index=True, autoincrement=True) name = Column(String(255), nullable=False) description = Column(Text, nullable=True) workflow_type = Column(Enum(WorkflowType), nullable=False) status = Column(Enum(WorkflowStatus), nullable=False, default=WorkflowStatus.active) trigger = Column(Enum(WorkflowTrigger), nullable=False) trigger_config = Column(JSON, nullable=True) # Configuration for trigger (e.g., time before check-in) steps = Column(JSON, nullable=False) # Array of workflow steps sla_hours = Column(Integer, nullable=True) # SLA in hours for workflow completion is_active = Column(Boolean, nullable=False, default=True) created_by = Column(Integer, ForeignKey('users.id'), nullable=False) created_at = Column(DateTime, default=datetime.utcnow, nullable=False) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False) creator = relationship('User', foreign_keys=[created_by]) workflow_instances = relationship('WorkflowInstance', back_populates='workflow', cascade='all, delete-orphan') class WorkflowInstance(Base): __tablename__ = 'workflow_instances' id = Column(Integer, primary_key=True, index=True, autoincrement=True) workflow_id = Column(Integer, ForeignKey('workflows.id'), nullable=False) booking_id = Column(Integer, ForeignKey('bookings.id'), nullable=True) room_id = Column(Integer, ForeignKey('rooms.id'), nullable=True) user_id = Column(Integer, ForeignKey('users.id'), nullable=True) # Guest user status = Column(String(50), nullable=False, default='pending') # pending, in_progress, completed, cancelled started_at = Column(DateTime, default=datetime.utcnow, nullable=False) completed_at = Column(DateTime, nullable=True) due_date = Column(DateTime, nullable=True) meta_data = Column(JSON, nullable=True) # Additional context data created_at = Column(DateTime, default=datetime.utcnow, nullable=False) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False) workflow = relationship('Workflow', back_populates='workflow_instances') booking = relationship('Booking') room = relationship('Room') user = relationship('User', foreign_keys=[user_id]) tasks = relationship('Task', back_populates='workflow_instance', cascade='all, delete-orphan') class TaskStatus(str, enum.Enum): pending = 'pending' assigned = 'assigned' in_progress = 'in_progress' completed = 'completed' cancelled = 'cancelled' overdue = 'overdue' class TaskPriority(str, enum.Enum): low = 'low' medium = 'medium' high = 'high' urgent = 'urgent' class Task(Base): __tablename__ = 'tasks' id = Column(Integer, primary_key=True, index=True, autoincrement=True) title = Column(String(255), nullable=False) description = Column(Text, nullable=True) task_type = Column(String(100), nullable=False) # e.g., 'room_cleaning', 'maintenance', 'guest_communication' status = Column(Enum(TaskStatus), nullable=False, default=TaskStatus.pending) priority = Column(Enum(TaskPriority), nullable=False, default=TaskPriority.medium) workflow_instance_id = Column(Integer, ForeignKey('workflow_instances.id'), nullable=True) booking_id = Column(Integer, ForeignKey('bookings.id'), nullable=True) room_id = Column(Integer, ForeignKey('rooms.id'), nullable=True) assigned_to = Column(Integer, ForeignKey('users.id'), nullable=True) created_by = Column(Integer, ForeignKey('users.id'), nullable=False) due_date = Column(DateTime, nullable=True) completed_at = Column(DateTime, nullable=True) estimated_duration_minutes = Column(Integer, nullable=True) actual_duration_minutes = Column(Integer, nullable=True) notes = Column(Text, nullable=True) meta_data = Column(JSON, nullable=True) # Additional task-specific data created_at = Column(DateTime, default=datetime.utcnow, nullable=False) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False) workflow_instance = relationship('WorkflowInstance', back_populates='tasks') booking = relationship('Booking') room = relationship('Room') assignee = relationship('User', foreign_keys=[assigned_to]) creator_user = relationship('User', foreign_keys=[created_by]) task_comments = relationship('TaskComment', back_populates='task', cascade='all, delete-orphan') class TaskComment(Base): __tablename__ = 'task_comments' id = Column(Integer, primary_key=True, index=True, autoincrement=True) task_id = Column(Integer, ForeignKey('tasks.id'), nullable=False) user_id = Column(Integer, ForeignKey('users.id'), nullable=False) comment = Column(Text, nullable=False) created_at = Column(DateTime, default=datetime.utcnow, nullable=False) task = relationship('Task', back_populates='task_comments') user = relationship('User')