pdf-quiz-generator/backend/app/schemas/quiz.py
Daniel 2cbbfe00c3 Tag filtering, multi-category, bug fixes, image validation, docs
- Fix tag filtering (sa_text import shadowing caused UnboundLocalError)
- Add TagBrowser component with per-section search
- Multi-category selection (OR within categories, AND with tags)
- AI image validation: has_figure field in extraction prompt
- Skip known branding images by MD5 hash + dimension filters
- Fix quiz timer auto-submit (wrong useEffect dependency)
- Fix QuizResponse schema: section_id nullable
- Fix Question.quiz_id → source_quiz_id attribute name
- Fix SQL injection in quizzes.py vector search
- Add PDF processing progress steps via Redis
- Add delete user from admin panel
- Admin page: no spinner flash on data refresh
- Upload progress: axios 1.x e.progress, remove manual Content-Type
- Duplicate model error: 409 with clear message
- Backend startup: retry DDL migration on lock timeout
- Replace all silent except:pass with warning logs
- Comprehensive multi-page documentation (docs/)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 22:48:26 +02:00

70 lines
1.9 KiB
Python

from datetime import datetime
from pydantic import BaseModel
class QuizCreate(BaseModel):
section_id: int | None = None
title: str
mode: str = "timed" # timed, learning
time_limit_minutes: int | None = None
model_id: str | None = None # override extraction model
question_category_id: int | None = None # assign extracted questions to this bank category
extraction_mode: str = "standard"
# standard — current working mode (inline Correct Answer / Preferred Response)
# questions_only — extract Q+options only, no answers (admin fills later)
# two_step — separate answer key section (PREP 2013 style)
# regex — AI analyses format then extracts answer key with regex
# ai_decide — AI reads a sample and decides which approach to use
class QuizUpdate(BaseModel):
title: str
class QuestionResponse(BaseModel):
id: int
question_text: str
question_type: str
options: list[str] | None
image_path: str | None = None
class Config:
from_attributes = True
class QuestionWithAnswer(QuestionResponse):
correct_answer: str
explanation: str | None
page_reference: int | None
class QuizResponse(BaseModel):
id: int
section_id: int | None = None
user_id: int
title: str
questions_count: int
mode: str
time_limit_minutes: int | None
skipped_questions: str | None = None
category_id: int | None = None
created_at: datetime
deleted_at: datetime | None = None
is_published: int = 1
class Config:
from_attributes = True
class QuizDetail(QuizResponse):
questions: list[QuestionResponse] = []
class QuizLearningDetail(QuizResponse):
"""Learning mode — includes answers and explanations."""
questions: list[QuestionWithAnswer] = []
class QuizReview(QuizResponse):
questions: list[QuestionWithAnswer] = []