Files
john 05e173b293 Ship native iOS app, Wiki/TTS backend, and skeleton loading UX.
Replace the WebView shell with SwiftUI screens, add account-scoped Wiki and TTS APIs with adaptive review and photo scan support, and keep web/iOS pages usable while data loads asynchronously.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-08 15:13:59 +08:00

89 lines
2.7 KiB
Python

from typing import Literal, Optional
from fastapi import APIRouter, Depends, Query
from sqlalchemy.orm import Session
from auth import get_current_user
from database import get_db
from models import User
from schemas import (
DailyQuizResponse,
ErrorBankListResponse,
PracticePlanResetResponse,
QuizAnswerRequest,
QuizAnswerResponse,
QuizStatsResponse,
)
from services.quiz_service import quiz_service
router = APIRouter(prefix="/api/quiz", tags=["quiz"])
@router.get("/daily", response_model=DailyQuizResponse)
def daily_quiz(
track: Literal["accumulation", "book"] = Query("accumulation"),
pool: Literal["untrained", "errors", "error_bank"] = Query("untrained"),
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
):
result = quiz_service.get_daily_quiz(db, current_user, track=track, pool=pool)
return DailyQuizResponse(**result)
@router.get("/spell", response_model=DailyQuizResponse)
def spell_quiz(
track: Literal["accumulation", "book"] = Query("accumulation"),
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
):
result = quiz_service.get_spell_quiz(db, current_user, track=track)
return DailyQuizResponse(**result)
@router.post("/answer", response_model=QuizAnswerResponse)
def submit_answer(
data: QuizAnswerRequest,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
):
result = quiz_service.submit_answer(
db,
current_user,
data.word_id,
data.question_type,
data.user_answer,
data.correct_answer,
data.duration_seconds or 0,
pool=data.pool,
)
return QuizAnswerResponse(**result)
@router.get("/error-bank", response_model=ErrorBankListResponse)
def error_bank_list(
track: Literal["accumulation", "book"] = Query("accumulation"),
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
):
return ErrorBankListResponse(**quiz_service.list_error_bank(db, current_user, track=track))
@router.get("/stats", response_model=QuizStatsResponse)
def quiz_stats(
track: Literal["accumulation", "book"] = Query("accumulation"),
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
):
return quiz_service.get_stats(db, current_user, track=track)
@router.post("/reset-plan", response_model=PracticePlanResetResponse)
def reset_practice_plan(
track: Literal["accumulation", "book"] = Query("accumulation"),
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
):
return PracticePlanResetResponse(
**quiz_service.reset_practice_plan_for_track(db, current_user, track=track)
)