d968b2d901
- 라벨 "복습 시작" → "문제풀이" - attempts.outcome 컬럼 + selected_choice nullable (correct/wrong/unsure) - 풀이 중 정답·해설·AI·비슷한 문제 모두 비노출, 답 클릭 시 자동 진행 - "모르겠음" 5번째 옵션 추가 - 결과 화면 = 정답/틀린/모르겠음 3 카테고리 탭, 카드 클릭 expand - 틀린 → PR-3 AI 해설 (RAG) - 모르겠음 → 분야(subject+scope) 설명 AI 즉석 생성 + 캐시 (PR-9 신규) - 분야 설명 RAG: 매핑 documents 청크 + 같은 분야 다른 문제·해설 → bge-reranker - 마이그레이션 200~205 (single-statement, asyncpg 호환) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
39 lines
1.6 KiB
Python
39 lines
1.6 KiB
Python
"""study_topic_subject_notes ORM (PR-9) — 분야 설명 캐시.
|
|
|
|
(user, study_topic, subject, scope) 단위 unique. AI 즉석 생성 + 캐시.
|
|
사용자가 풀이 결과 화면에서 "모르겠음" 카드 클릭 시 호출.
|
|
|
|
status: none/pending/ready/failed/stale (PR-3 패턴 동일).
|
|
"""
|
|
|
|
from datetime import datetime
|
|
|
|
from sqlalchemy import BigInteger, DateTime, ForeignKey, String, Text
|
|
from sqlalchemy.orm import Mapped, mapped_column
|
|
|
|
from core.database import Base
|
|
|
|
|
|
class StudyTopicSubjectNote(Base):
|
|
__tablename__ = "study_topic_subject_notes"
|
|
|
|
id: Mapped[int] = mapped_column(BigInteger, primary_key=True)
|
|
user_id: Mapped[int] = mapped_column(
|
|
BigInteger, ForeignKey("users.id", ondelete="CASCADE"), nullable=False
|
|
)
|
|
study_topic_id: Mapped[int] = mapped_column(
|
|
BigInteger, ForeignKey("study_topics.id", ondelete="CASCADE"), nullable=False
|
|
)
|
|
subject: Mapped[str] = mapped_column(String(120), nullable=False)
|
|
scope: Mapped[str] = mapped_column(String(200), nullable=False, default="")
|
|
content: Mapped[str | None] = mapped_column(Text)
|
|
status: Mapped[str] = mapped_column(String(20), default="none", nullable=False)
|
|
generated_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
|
|
model: Mapped[str | None] = mapped_column(String(120))
|
|
created_at: Mapped[datetime] = mapped_column(
|
|
DateTime(timezone=True), default=datetime.now, nullable=False
|
|
)
|
|
updated_at: Mapped[datetime] = mapped_column(
|
|
DateTime(timezone=True), default=datetime.now, onupdate=datetime.now, nullable=False
|
|
)
|