from dataclasses import dataclass, field from datetime import date, datetime from typing import Literal, Optional AssignmentStatus = Literal["assigned", "in_progress", "submitted", "graded", "late", "missing"] UploadStatus = Literal["draft", "uploaded", "confirmed", "failed"] ProcessingStatus = Literal["queued", "processing", "ready", "failed"] @dataclass class Course: d2l_course_id: str name: str id: Optional[int] = None code: Optional[str] = None semester: Optional[str] = None active: bool = True @dataclass class Assignment: course_id: int title: str id: Optional[int] = None d2l_assignment_key: Optional[str] = None category: Optional[str] = None due_at: Optional[datetime] = None status: AssignmentStatus = "assigned" grade_text: Optional[str] = None grade_numeric: Optional[float] = None professor_comments: Optional[str] = None source: Literal["d2l", "manual", "template"] = "d2l" @dataclass class Submission: assignment_id: int original_filename: str mime_type: str id: Optional[int] = None version_label: str = "v1" submitted_at: datetime = field(default_factory=datetime.utcnow) paperless_document_id: Optional[int] = None paperless_title: Optional[str] = None status: UploadStatus = "draft" @dataclass class Recording: course_id: int session_date: date original_filename: str id: Optional[int] = None assignment_id: Optional[int] = None mp3_filename: Optional[str] = None duration_seconds: Optional[int] = None transcription_status: ProcessingStatus = "queued" summary_status: ProcessingStatus = "queued" transcript_paperless_document_id: Optional[int] = None summary_paperless_document_id: Optional[int] = None