"""ORM model for the 知识题库 (arcade trivia bank) — the question pool for 知识竞速 (Knowledge Rush). Deliberately SEPARATE from `secquiz_questions` (security awareness): the daily security quiz PRODUCES points; the arcade game SPENDS them on general-knowledge trivia, so mixing the two banks would collapse the earn/spend loop the user asked to keep distinct. Table created by migration 412. No FK columns beyond created_by → identity_persons (charset-matched, TiDB-safe). """ from __future__ import annotations import uuid from datetime import datetime from sqlalchemy import ( JSON, DateTime, ForeignKey, Index, String, Text, func, ) from sqlalchemy.orm import Mapped, mapped_column from app.core.database import Base from app.core.sql_types import GUID as Uuid QUESTION_ACTIVE = "active" QUESTION_ARCHIVED = "archived" SOURCE_SEED = "seed" SOURCE_AI = "ai" SOURCE_MANUAL = "manual" # Trivia categories — the competitive dimensions ("who knows history best?"). # Slugs are language-neutral; the frontend maps to localized labels. CAT_COMMON_SENSE = "common_sense" # 常识 CAT_HISTORY = "history" # 历史 CAT_SCIENCE = "science" # 科学 CAT_GEOGRAPHY = "geography" # 地理 CAT_CHINESE_CULTURE = "chinese_culture" # 中华文化 CAT_LIFE = "life" # 生活百科 TRIVIA_CATEGORIES = ( CAT_COMMON_SENSE, CAT_HISTORY, CAT_SCIENCE, CAT_GEOGRAPHY, CAT_CHINESE_CULTURE, CAT_LIFE, ) class ArcadeTriviaQuestion(Base): __tablename__ = "arcade_trivia_questions" __table_args__ = ( Index("ix_arcade_trivia_status_cat", "status", "category"), ) id: Mapped[uuid.UUID] = mapped_column(Uuid, primary_key=True, default=uuid.uuid4) prompt: Mapped[str] = mapped_column(Text, nullable=False) # JSON list of {"key": "A", "text": "..."} — always single-answer here # (the rush UI is one tap per question). options: Mapped[list] = mapped_column(JSON, nullable=False) correct_key: Mapped[str] = mapped_column(String(8), nullable=False) explanation: Mapped[str | None] = mapped_column(Text) category: Mapped[str] = mapped_column(String(32), nullable=False, default=CAT_COMMON_SENSE) difficulty: Mapped[str] = mapped_column(String(16), nullable=False, default="normal") status: Mapped[str] = mapped_column(String(16), nullable=False, default=QUESTION_ACTIVE) source: Mapped[str] = mapped_column(String(16), nullable=False, default=SOURCE_SEED) created_by: Mapped[uuid.UUID | None] = mapped_column(Uuid, ForeignKey("identity_persons.id")) created_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), nullable=False, server_default=func.now() ) updated_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), nullable=False, server_default=func.now(), onupdate=func.now() ) __all__ = [ "ArcadeTriviaQuestion", "QUESTION_ACTIVE", "QUESTION_ARCHIVED", "SOURCE_SEED", "SOURCE_AI", "SOURCE_MANUAL", "CAT_COMMON_SENSE", "CAT_HISTORY", "CAT_SCIENCE", "CAT_GEOGRAPHY", "CAT_CHINESE_CULTURE", "CAT_LIFE", "TRIVIA_CATEGORIES", ]