247 lines
4.9 KiB
Python
247 lines
4.9 KiB
Python
from pydantic import BaseModel, Field
|
|
from datetime import datetime
|
|
from typing import Any, List
|
|
|
|
|
|
class StudentCreate(BaseModel):
|
|
first_name: str = Field(..., min_length=1)
|
|
age: int = Field(..., ge=8, le=12)
|
|
grade: str
|
|
|
|
|
|
class StudentRead(BaseModel):
|
|
id: int
|
|
first_name: str
|
|
age: int
|
|
grade: str
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
class UserRead(BaseModel):
|
|
id: int
|
|
username: str
|
|
role: str
|
|
student_id: int | None = None
|
|
student: StudentRead | None = None
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
class LoginRequest(BaseModel):
|
|
username: str = Field(..., min_length=1)
|
|
password: str = Field(..., min_length=1)
|
|
|
|
|
|
class LoginResponse(BaseModel):
|
|
access_token: str
|
|
token_type: str = "bearer"
|
|
user: UserRead
|
|
|
|
|
|
class StudentAccountCreate(StudentCreate):
|
|
username: str = Field(..., min_length=1)
|
|
password: str = Field(..., min_length=1)
|
|
|
|
|
|
class StudentAccountResponse(BaseModel):
|
|
student: StudentRead
|
|
user: UserRead
|
|
|
|
|
|
class ChatRequest(BaseModel):
|
|
student_id: int
|
|
message: str
|
|
lesson_id: str | None = None
|
|
lesson_title: str | None = None
|
|
asset_title: str | None = None
|
|
section_title: str | None = None
|
|
section_context_key: str | None = None
|
|
section_context: str | None = None
|
|
step_percent: int | None = None
|
|
|
|
|
|
class ChatResponse(BaseModel):
|
|
reply: str
|
|
should_speak: bool = True
|
|
advance_lesson_step: bool = False
|
|
|
|
|
|
class MessageRead(BaseModel):
|
|
id: int
|
|
student_id: int
|
|
role: str
|
|
content: str
|
|
created_at: datetime
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
class TTSProfile(BaseModel):
|
|
id: str
|
|
label: str
|
|
description: str
|
|
|
|
|
|
class TTSProfilesResponse(BaseModel):
|
|
profiles: List[TTSProfile]
|
|
|
|
|
|
class TTSRequest(BaseModel):
|
|
text: str = Field(..., min_length=1, max_length=4096)
|
|
profile_id: str = Field(..., min_length=1)
|
|
|
|
|
|
class SkillProgress(BaseModel):
|
|
code: str
|
|
subject: str
|
|
label: str
|
|
mastery_score: float
|
|
confidence: float
|
|
evidence_count: int
|
|
|
|
|
|
class ProgressResponse(BaseModel):
|
|
student: StudentRead
|
|
progress: List[SkillProgress]
|
|
|
|
|
|
class ProgramAsset(BaseModel):
|
|
name: str
|
|
title: str
|
|
path: str
|
|
url: str
|
|
sections: List[dict] = []
|
|
|
|
|
|
class ProgramLesson(BaseModel):
|
|
id: str
|
|
title: str
|
|
subject: str
|
|
grade: str
|
|
cycle: str
|
|
asset_count: int
|
|
assets: List[ProgramAsset] = []
|
|
adaptive_kit: dict[str, Any] | None = None
|
|
|
|
|
|
class ProgramLessonListResponse(BaseModel):
|
|
lessons: List[ProgramLesson]
|
|
|
|
|
|
class ProgramReviewRequest(BaseModel):
|
|
node_key: str = Field(..., min_length=1)
|
|
status: str = "needs_changes"
|
|
comment: str = ""
|
|
|
|
|
|
class StudentProgramAssignRequest(BaseModel):
|
|
lesson_id: str = Field(..., min_length=1)
|
|
|
|
|
|
class StudentProgramResponse(BaseModel):
|
|
student: StudentRead
|
|
lesson: ProgramLesson | None = None
|
|
start_asset_index: int = 0
|
|
start_section_index: int = 0
|
|
|
|
|
|
class StudentProgramStartRequest(BaseModel):
|
|
asset_index: int = Field(..., ge=0)
|
|
section_index: int = Field(..., ge=0)
|
|
|
|
|
|
class StudentAdaptiveProfileRequest(BaseModel):
|
|
lesson_id: str = Field(..., min_length=1)
|
|
diagnostic_id: str | None = None
|
|
profile_id: str = Field(..., min_length=1)
|
|
profile_title: str = Field(..., min_length=1)
|
|
notes: str = ""
|
|
source: str = "teacher"
|
|
|
|
|
|
class StudentAdaptiveProfileRead(BaseModel):
|
|
id: int
|
|
student_id: int
|
|
lesson_id: str
|
|
diagnostic_id: str | None = None
|
|
profile_id: str
|
|
profile_title: str
|
|
notes: str
|
|
source: str
|
|
updated_at: datetime
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
class LessonCardState(BaseModel):
|
|
lesson_id: str
|
|
asset_path: str
|
|
asset_title: str
|
|
section_key: str
|
|
section_title: str
|
|
comprehension_score: float = Field(..., ge=0, le=100)
|
|
attempts: int = Field(0, ge=0)
|
|
validated: bool = False
|
|
|
|
|
|
class LessonSessionEndRequest(BaseModel):
|
|
student_id: int
|
|
lesson_id: str
|
|
lesson_title: str
|
|
conversation: List[dict[str, Any]]
|
|
card_states: List[LessonCardState] = []
|
|
|
|
|
|
class LessonSessionLogRead(BaseModel):
|
|
id: int
|
|
student_id: int
|
|
lesson_id: str
|
|
lesson_title: str
|
|
started_at: datetime
|
|
ended_at: datetime
|
|
conversation: str
|
|
card_results: str
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
class LessonCardProgressRead(BaseModel):
|
|
id: int
|
|
student_id: int
|
|
lesson_id: str
|
|
asset_path: str
|
|
asset_title: str
|
|
section_key: str
|
|
section_title: str
|
|
comprehension_score: float
|
|
attempts: int
|
|
validated_at: datetime | None = None
|
|
updated_at: datetime
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
class AssessmentQuestionResponse(BaseModel):
|
|
skill_code: str
|
|
skill_label: str
|
|
question: str
|
|
|
|
|
|
class AssessmentAnswerRequest(BaseModel):
|
|
student_id: int
|
|
skill_code: str
|
|
answer: str
|
|
|
|
|
|
class AssessmentAnswerResponse(BaseModel):
|
|
correct: bool
|
|
feedback: str
|
|
mastery_score: float
|