File size: 8,609 Bytes
3736c33
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
"""

Studio Models - Notebook, Flashcards, Quiz

These models represent the core Studio features for NotebookPRO

"""
from pydantic import BaseModel, Field
from typing import List, Optional, Dict, Any
from datetime import datetime
from enum import Enum


# ============================================================================
# NOTEBOOK MODELS
# ============================================================================

class NotebookEntry(BaseModel):
    """A single note entry in the notebook"""
    id: str = Field(..., description="Unique identifier for the note")
    space_id: str = Field(..., description="Space this note belongs to")
    title: str = Field(..., description="Title of the note")
    content: str = Field(..., description="Main content/body of the note")
    source_type: str = Field(default="manual", description="Source: manual, chat, generated")
    source_id: Optional[str] = Field(None, description="ID of source (e.g., chat message ID)")
    tags: List[str] = Field(default_factory=list, description="Tags for categorization")
    created_at: datetime = Field(default_factory=datetime.now)
    updated_at: datetime = Field(default_factory=datetime.now)
    metadata: Dict[str, Any] = Field(default_factory=dict)


class NotebookEntryCreate(BaseModel):
    """Request model for creating a notebook entry"""
    space_id: str
    title: str
    content: str
    source_type: str = "manual"
    source_id: Optional[str] = None
    tags: List[str] = []
    metadata: Dict[str, Any] = {}


class NotebookEntryUpdate(BaseModel):
    """Request model for updating a notebook entry"""
    title: Optional[str] = None
    content: Optional[str] = None
    tags: Optional[List[str]] = None
    metadata: Optional[Dict[str, Any]] = None


# ============================================================================
# FLASHCARD MODELS
# ============================================================================

class DifficultyLevel(str, Enum):
    """Difficulty level for flashcards"""
    EASY = "easy"
    MEDIUM = "medium"
    HARD = "hard"


class MasteryLevel(str, Enum):
    """User's mastery level for a flashcard"""
    NEW = "new"
    LEARNING = "learning"
    REVIEWING = "reviewing"
    MASTERED = "mastered"


class Flashcard(BaseModel):
    """A single flashcard for memorization"""
    id: str = Field(..., description="Unique identifier")
    space_id: str = Field(..., description="Space this flashcard belongs to")
    question: str = Field(..., description="Front of the card (question/prompt)")
    answer: str = Field(..., description="Back of the card (answer/explanation)")
    difficulty: DifficultyLevel = Field(default=DifficultyLevel.MEDIUM)
    mastery: MasteryLevel = Field(default=MasteryLevel.NEW)
    source_type: str = Field(default="manual", description="Source: manual, generated, notebook")
    source_id: Optional[str] = Field(None, description="Source ID (e.g., notebook entry ID)")
    tags: List[str] = Field(default_factory=list)
    review_count: int = Field(default=0, description="Number of times reviewed")
    correct_count: int = Field(default=0, description="Number of times answered correctly")
    last_reviewed: Optional[datetime] = None
    next_review: Optional[datetime] = None
    created_at: datetime = Field(default_factory=datetime.now)
    metadata: Dict[str, Any] = Field(default_factory=dict)


class FlashcardCreate(BaseModel):
    """Request model for creating a flashcard"""
    space_id: str
    question: str
    answer: str
    difficulty: DifficultyLevel = DifficultyLevel.MEDIUM
    source_type: str = "manual"
    source_id: Optional[str] = None
    tags: List[str] = []
    metadata: Dict[str, Any] = {}


class FlashcardUpdate(BaseModel):
    """Request model for updating a flashcard"""
    question: Optional[str] = None
    answer: Optional[str] = None
    difficulty: Optional[DifficultyLevel] = None
    mastery: Optional[MasteryLevel] = None
    tags: Optional[List[str]] = None


class FlashcardReview(BaseModel):
    """Request model for reviewing a flashcard"""
    correct: bool = Field(..., description="Whether the user answered correctly")


class FlashcardGenerateRequest(BaseModel):
    """Request to generate flashcards from content"""
    space_id: str
    source_type: str = Field(..., description="Source type: notebook, file, text")
    source_ids: Optional[List[str]] = Field(None, description="IDs of notebook entries or files")
    text_content: Optional[str] = Field(None, description="Direct text content to generate from")
    num_cards: int = Field(default=5, description="Number of flashcards to generate")
    difficulty: DifficultyLevel = DifficultyLevel.MEDIUM


# ============================================================================
# QUIZ MODELS
# ============================================================================

class QuestionType(str, Enum):
    """Type of quiz question"""
    MULTIPLE_CHOICE = "multiple_choice"
    TRUE_FALSE = "true_false"
    SHORT_ANSWER = "short_answer"


class QuizQuestion(BaseModel):
    """A single quiz question"""
    id: str = Field(..., description="Unique identifier")
    question: str = Field(..., description="Question text")
    type: QuestionType = Field(..., description="Question type")
    options: Optional[List[str]] = Field(None, description="Options for multiple choice")
    correct_answer: str = Field(..., description="Correct answer")
    explanation: Optional[str] = Field(None, description="Explanation of the answer")
    points: int = Field(default=1, description="Points for this question")
    difficulty: DifficultyLevel = Field(default=DifficultyLevel.MEDIUM)


class Quiz(BaseModel):
    """A quiz session"""
    id: str = Field(..., description="Unique identifier")
    space_id: str = Field(..., description="Space this quiz belongs to")
    title: str = Field(..., description="Quiz title")
    description: Optional[str] = None
    questions: List[QuizQuestion] = Field(..., description="List of questions")
    source_type: str = Field(default="manual", description="Source: manual, generated, notebook, file")
    source_ids: Optional[List[str]] = None
    created_at: datetime = Field(default_factory=datetime.now)
    metadata: Dict[str, Any] = Field(default_factory=dict)


class QuizCreate(BaseModel):
    """Request model for creating a quiz"""
    space_id: str
    title: str
    description: Optional[str] = None
    questions: List[QuizQuestion] = []
    source_type: str = "manual"
    source_ids: Optional[List[str]] = None


class QuizGenerateRequest(BaseModel):
    """Request to generate a quiz from content"""
    space_id: str
    title: str
    source_type: str = Field(..., description="Source type: notebook, file, text")
    source_ids: Optional[List[str]] = Field(None, description="IDs of notebook entries or files")
    text_content: Optional[str] = Field(None, description="Direct text content")
    num_questions: int = Field(default=5, description="Number of questions")
    question_types: List[QuestionType] = Field(
        default=[QuestionType.MULTIPLE_CHOICE],
        description="Types of questions to include"
    )
    difficulty: DifficultyLevel = DifficultyLevel.MEDIUM


class QuizAnswer(BaseModel):
    """User's answer to a quiz question"""
    question_id: str
    answer: str
    time_spent: Optional[int] = Field(None, description="Time spent in seconds")


class QuizSubmission(BaseModel):
    """User's quiz submission"""
    quiz_id: str
    answers: List[QuizAnswer]


class QuizResult(BaseModel):
    """Result of a quiz submission"""
    quiz_id: str
    submission_id: str = Field(..., description="Unique submission ID")
    total_questions: int
    correct_answers: int
    incorrect_answers: int
    score_percentage: float
    total_points: int
    earned_points: int
    answers: List[Dict[str, Any]] = Field(..., description="Detailed answer results")
    completed_at: datetime = Field(default_factory=datetime.now)
    time_taken: Optional[int] = Field(None, description="Total time in seconds")


class QuizHistory(BaseModel):
    """Quiz attempt history"""
    quiz_id: str
    space_id: str
    quiz_title: str
    results: List[QuizResult] = Field(default_factory=list)
    best_score: float = Field(default=0.0)
    average_score: float = Field(default=0.0)
    attempts_count: int = Field(default=0)