from datetime import date, datetime from sqlalchemy import Date, DateTime, String, Text from sqlalchemy.orm import Mapped, mapped_column from app.db.base import Base class ProjectCourse(Base): __tablename__ = "project_courses" id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True) code: Mapped[str] = mapped_column(String(16), unique=True, index=True) name: Mapped[str] = mapped_column(String(128)) default_certificate_name: Mapped[str] = mapped_column(String(128), default="培训结业证书") default_course_name: Mapped[str | None] = mapped_column(String(128), nullable=True) default_stage_name: Mapped[str | None] = mapped_column(String(128), nullable=True) default_issuer_name: Mapped[str] = mapped_column(String(128), default="本公司") status: Mapped[str] = mapped_column(String(32), default="active") created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow) updated_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) class Certificate(Base): __tablename__ = "certificates" id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True) learner_id: Mapped[int] = mapped_column(index=True) project_code: Mapped[str] = mapped_column(String(16), index=True) certificate_no: Mapped[str] = mapped_column(String(64), unique=True, index=True) certificate_name: Mapped[str] = mapped_column(String(128)) class_name: Mapped[str | None] = mapped_column(String(128), nullable=True) course_name: Mapped[str | None] = mapped_column(String(128), nullable=True) stage_name: Mapped[str | None] = mapped_column(String(128), nullable=True) issue_date: Mapped[date] = mapped_column(Date) issuer_name: Mapped[str] = mapped_column(String(128)) status: Mapped[str] = mapped_column(String(32), default="valid") pdf_status: Mapped[str] = mapped_column(String(32), default="not_generated") pdf_file_path: Mapped[str | None] = mapped_column(String(512), nullable=True) pdf_last_accessed_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True) public_token_id: Mapped[int | None] = mapped_column(nullable=True) qr_token_id: Mapped[int | None] = mapped_column(nullable=True) remark: Mapped[str | None] = mapped_column(Text, nullable=True) created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow) updated_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) class CertificateAccessToken(Base): __tablename__ = "certificate_access_tokens" id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True) certificate_id: Mapped[int] = mapped_column(index=True) token_hash: Mapped[str] = mapped_column(String(128), unique=True, index=True) token_value: Mapped[str] = mapped_column(String(128), unique=True, index=True) token_type: Mapped[str] = mapped_column(String(32)) status: Mapped[str] = mapped_column(String(32), default="active") created_reason: Mapped[str] = mapped_column(String(128), default="initial") revoked_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True) last_access_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True) created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)