from __future__ import annotations from datetime import datetime, timezone from enum import Enum from sqlalchemy import DateTime, Float, ForeignKey, String from sqlalchemy.orm import Mapped, mapped_column, relationship from app.extensions import db def utcnow() -> datetime: return datetime.now(timezone.utc) class AttendanceType(str, Enum): CHECK_IN = "check_in" CHECK_OUT = "check_out" @property def label(self) -> str: return "Check in" if self is AttendanceType.CHECK_IN else "Check out" class AttendanceEvent(db.Model): __tablename__ = "attendance_events" id: Mapped[int] = mapped_column(primary_key=True) person_id: Mapped[int] = mapped_column(ForeignKey("people.id"), nullable=False, index=True) event_type: Mapped[str] = mapped_column(String(20), nullable=False) occurred_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utcnow, nullable=False, index=True) source: Mapped[str] = mapped_column(String(80), default="web", nullable=False) confidence: Mapped[float | None] = mapped_column(Float) created_by_id: Mapped[int | None] = mapped_column(ForeignKey("accounts.id"), index=True) person = relationship("Person", back_populates="attendance_events") created_by = relationship("Account", back_populates="attendance_events") @property def type_label(self) -> str: try: return AttendanceType(self.event_type).label except ValueError: return self.event_type