""" 員工基本資料 Model """ from datetime import datetime, date from sqlalchemy import Column, Integer, String, Boolean, Date, DateTime, Enum, ForeignKey, UniqueConstraint from sqlalchemy.orm import relationship import enum from app.db.base import Base class EmployeeStatus(str, enum.Enum): """員工狀態""" ACTIVE = "active" INACTIVE = "inactive" TERMINATED = "terminated" class Employee(Base): """員工基本資料表""" __tablename__ = "tenant_employees" __table_args__ = ( UniqueConstraint("tenant_id", "employee_id", name="uq_tenant_employee_id"), UniqueConstraint("tenant_id", "seq_no", name="uq_tenant_seq_no"), ) id = Column(Integer, primary_key=True, index=True) tenant_id = Column(Integer, ForeignKey("tenants.id", ondelete="CASCADE"), nullable=False, index=True, comment="租戶 ID") seq_no = Column(Integer, nullable=False, comment="租戶內序號 (自動從1開始)") employee_id = Column(String(20), nullable=False, index=True, comment="員工編號 (EMP001, 租戶內唯一,永久不變)") keycloak_user_id = Column(String(36), unique=True, nullable=True, index=True, comment="Keycloak User UUID (唯一 SSO 識別碼,永久不變,一個員工只有一個)") username_base = Column(String(50), unique=True, nullable=False, index=True, comment="基礎帳號名稱 (全系統唯一)") legal_name = Column(String(100), nullable=False, comment="法定姓名") english_name = Column(String(100), comment="英文名稱") phone = Column(String(20), comment="電話") mobile = Column(String(20), comment="手機") hire_date = Column(Date, nullable=False, comment="到職日期") status = Column( String(20), default=EmployeeStatus.ACTIVE, nullable=False, comment="狀態 (active/inactive/terminated)" ) # 通用欄位 is_active = Column(Boolean, default=True, nullable=False, comment="是否啟用") edit_by = Column(String(100), nullable=True, comment="最後編輯者") created_at = Column(DateTime, default=datetime.utcnow, nullable=False, comment="建立時間") updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False, comment="更新時間") # 關聯 tenant = relationship("Tenant", back_populates="employees") department_memberships = relationship( "DepartmentMember", back_populates="employee", cascade="all, delete-orphan", lazy="selectin" ) email_accounts = relationship( "EmailAccount", back_populates="employee", cascade="all, delete-orphan", lazy="selectin" ) permissions = relationship( "Permission", foreign_keys="Permission.employee_id", back_populates="employee", cascade="all, delete-orphan", lazy="selectin" ) network_drive = relationship( "NetworkDrive", back_populates="employee", uselist=False, cascade="all, delete-orphan", lazy="selectin" ) def __repr__(self): return f"" # is_active 已改為資料庫欄位,移除 @property