"""구글 계정으로 로그인한 사람 id가 곧 구글 sub다. 이메일이 바뀌어도 유지되는 값이라 따로 발급하지 않는다. 잡 생성 횟수는 행을 세지 않고 누적값을 올린다 — 잡을 지워도 회복되지 않는다. """ from datetime import datetime from sqlalchemy import DateTime, Integer, String, func from sqlalchemy.orm import Mapped, mapped_column from utils.database import Base USER_ID_LENGTH = 64 EMAIL_LENGTH = 320 PICTURE_URL_LENGTH = 512 DEFAULT_JOB_LIMIT = 3 # 소유자를 모르는 잡의 자리. 나중에 admin의 sub로 덮어쓴다 UNASSIGNED_USER_ID = "0" class User(Base): __tablename__ = "user" id: Mapped[str] = mapped_column(String(USER_ID_LENGTH), primary_key=True) email: Mapped[str] = mapped_column(String(EMAIL_LENGTH), index=True) name: Mapped[str] = mapped_column(String(255), default="") # 구글 프로필 사진. 토큰에만 들어오는 값이라 로그인할 때 받아 둔다 picture_url: Mapped[str] = mapped_column(String(PICTURE_URL_LENGTH), default="") # 만들 수 있는 총 잡 수. 무제한으로 둘 계정은 이 값을 크게 올린다 job_limit: Mapped[int] = mapped_column(Integer, default=DEFAULT_JOB_LIMIT) jobs_created: Mapped[int] = mapped_column(Integer, default=0) created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now()) last_login_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now(), onupdate=func.now()) @property def can_create_job(self) -> bool: return self.jobs_created < self.job_limit @property def jobs_left(self) -> int: return max(0, self.job_limit - self.jobs_created)