- New dedicated meetings.py router with full CRUD (list/get/create/update/delete)
- All endpoints accept meeting_code or numeric id
- MeetingParticipant model for tracking meeting attendance
- POST /meetings/{id}/attend adds current user to participant list
- Serialization includes participants list, project_code, milestone_code
- Creator auto-added as participant on meeting creation
- Registered in main.py alongside existing routers
54 lines
2.1 KiB
Python
54 lines
2.1 KiB
Python
from sqlalchemy import Column, Integer, String, Text, DateTime, ForeignKey, Enum, UniqueConstraint
|
|
from sqlalchemy.orm import relationship
|
|
from sqlalchemy.sql import func
|
|
from app.core.config import Base
|
|
import enum
|
|
|
|
class MeetingStatus(str, enum.Enum):
|
|
SCHEDULED = "scheduled"
|
|
IN_PROGRESS = "in_progress"
|
|
COMPLETED = "completed"
|
|
CANCELLED = "cancelled"
|
|
|
|
class MeetingPriority(str, enum.Enum):
|
|
LOW = "low"
|
|
MEDIUM = "medium"
|
|
HIGH = "high"
|
|
CRITICAL = "critical"
|
|
|
|
class Meeting(Base):
|
|
__tablename__ = "meetings"
|
|
|
|
id = Column(Integer, primary_key=True, index=True)
|
|
title = Column(String(255), nullable=False)
|
|
description = Column(Text, nullable=True)
|
|
status = Column(Enum(MeetingStatus, values_callable=lambda x: [e.value for e in x]), default=MeetingStatus.SCHEDULED)
|
|
priority = Column(Enum(MeetingPriority, values_callable=lambda x: [e.value for e in x]), default=MeetingPriority.MEDIUM)
|
|
meeting_code = Column(String(64), nullable=True, unique=True, index=True)
|
|
|
|
project_id = Column(Integer, ForeignKey("projects.id"), nullable=False)
|
|
milestone_id = Column(Integer, ForeignKey("milestones.id"), nullable=False)
|
|
reporter_id = Column(Integer, ForeignKey("users.id"), nullable=False)
|
|
|
|
scheduled_at = Column(DateTime(timezone=True), nullable=True)
|
|
duration_minutes = Column(Integer, nullable=True)
|
|
|
|
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
|
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
|
|
|
|
participants = relationship("MeetingParticipant", back_populates="meeting", cascade="all, delete-orphan")
|
|
|
|
|
|
class MeetingParticipant(Base):
|
|
__tablename__ = "meeting_participants"
|
|
__table_args__ = (
|
|
UniqueConstraint("meeting_id", "user_id", name="uq_meeting_participant"),
|
|
)
|
|
|
|
id = Column(Integer, primary_key=True, index=True)
|
|
meeting_id = Column(Integer, ForeignKey("meetings.id", ondelete="CASCADE"), nullable=False)
|
|
user_id = Column(Integer, ForeignKey("users.id"), nullable=False)
|
|
joined_at = Column(DateTime(timezone=True), server_default=func.now())
|
|
|
|
meeting = relationship("Meeting", back_populates="participants")
|