""" Practice session and analysis models """ from sqlalchemy import Column, Integer, String, ForeignKey, DateTime, Float, JSON, Text, Boolean from sqlalchemy.orm import relationship from sqlalchemy.sql import func from config.database import Base class PracticeSession(Base): __tablename__ = "practice_sessions" id = Column(Integer, primary_key=True) student_id = Column(Integer, ForeignKey("students.id"), nullable=False) assignment_id = Column(Integer, ForeignKey("assignments.id"), nullable=True) # Session info practice_type = Column(String, nullable=False) # conversation, reading, articulation technique = Column(String, nullable=False) # normal, prolonged_speech, easy_onset duration_seconds = Column(Float) # Content prompt_text = Column(Text) # What they were supposed to say/read transcribed_text = Column(Text) # What they actually said audio_file_path = Column(JSON) # Array of audio file paths (for multi-turn sessions) or single path # Format: ["sessionID_date_studentID_therapistID_turn1.wav", "sessionID_date_studentID_therapistID_turn2.wav", ...] # For reading practice: single string or array with one element # Quick metrics total_words = Column(Integer) words_per_minute = Column(Float) # Status is_completed = Column(Boolean, default=False) completed_at = Column(DateTime(timezone=True)) created_at = Column(DateTime(timezone=True), server_default=func.now()) # Relationships student = relationship("Student", back_populates="sessions") assignment = relationship("Assignment", back_populates="sessions") analysis = relationship("SessionAnalysis", back_populates="session", uselist=False) def __repr__(self): return f"" class SessionAnalysis(Base): __tablename__ = "session_analyses" id = Column(Integer, primary_key=True) session_id = Column(Integer, ForeignKey("practice_sessions.id"), unique=True, nullable=False) # Analysis results (stored as JSON for flexibility) stutter_analysis = Column(JSON) # Detailed stutter types, counts, locations fluency_analysis = Column(JSON) # Prolongation %, consistency scores rushed_speech_analysis = Column(JSON) # Burst patterns, pause analysis articulation_analysis = Column(JSON) # Accuracy scores per sound # Summary metrics total_stutters = Column(Integer, default=0) stutter_frequency_percent = Column(Float, default=0.0) fluency_score = Column(Float) # 0-100 rushed_speech_severity = Column(String) # minimal, mild, moderate, severe articulation_accuracy = Column(Float) # 0-100 # Affected phonemes/patterns struggled_phonemes = Column(JSON) # List of problem sounds stutter_patterns = Column(JSON) # Common patterns identified # Feedback patient_feedback = Column(Text) # Generated patient-friendly feedback therapist_notes = Column(Text) # Detailed clinical notes # Timestamps analyzed_at = Column(DateTime(timezone=True), server_default=func.now()) # Relationships session = relationship("PracticeSession", back_populates="analysis") def __repr__(self): return f""