@studious-lms/server 1.2.44 → 1.2.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +45 -0
- package/.env.test.example +37 -0
- package/README.md +34 -7
- package/coverage/base.css +224 -0
- package/coverage/block-navigation.js +87 -0
- package/coverage/clover.xml +12110 -0
- package/coverage/coverage-final.json +44 -0
- package/coverage/favicon.png +0 -0
- package/coverage/index.html +221 -0
- package/coverage/prettify.css +1 -0
- package/coverage/prettify.js +2 -0
- package/coverage/server/index.html +116 -0
- package/coverage/server/src/exportType.ts.html +109 -0
- package/coverage/server/src/index.html +161 -0
- package/coverage/server/src/index.ts.html +1702 -0
- package/coverage/server/src/instrument.ts.html +130 -0
- package/coverage/server/src/lib/config/env.ts.html +448 -0
- package/coverage/server/src/lib/config/index.html +116 -0
- package/coverage/server/src/lib/fileUpload.ts.html +1138 -0
- package/coverage/server/src/lib/googleCloudStorage.ts.html +334 -0
- package/coverage/server/src/lib/index.html +206 -0
- package/coverage/server/src/lib/jsonConversion.ts.html +2323 -0
- package/coverage/server/src/lib/jsonStyles.ts.html +193 -0
- package/coverage/server/src/lib/notificationHandler.ts.html +193 -0
- package/coverage/server/src/lib/pusher.ts.html +121 -0
- package/coverage/server/src/lib/thumbnailGenerator.ts.html +592 -0
- package/coverage/server/src/middleware/auth.ts.html +646 -0
- package/coverage/server/src/middleware/index.html +146 -0
- package/coverage/server/src/middleware/logging.ts.html +244 -0
- package/coverage/server/src/middleware/security.ts.html +271 -0
- package/coverage/server/src/routers/_app.ts.html +232 -0
- package/coverage/server/src/routers/agenda.ts.html +319 -0
- package/coverage/server/src/routers/announcement.ts.html +3481 -0
- package/coverage/server/src/routers/assignment.ts.html +7633 -0
- package/coverage/server/src/routers/attendance.ts.html +1030 -0
- package/coverage/server/src/routers/auth.ts.html +1081 -0
- package/coverage/server/src/routers/class.ts.html +3535 -0
- package/coverage/server/src/routers/comment.ts.html +991 -0
- package/coverage/server/src/routers/conversation.ts.html +982 -0
- package/coverage/server/src/routers/event.ts.html +1609 -0
- package/coverage/server/src/routers/file.ts.html +1144 -0
- package/coverage/server/src/routers/folder.ts.html +2797 -0
- package/coverage/server/src/routers/index.html +386 -0
- package/coverage/server/src/routers/labChat.ts.html +3073 -0
- package/coverage/server/src/routers/marketing.ts.html +340 -0
- package/coverage/server/src/routers/message.ts.html +1912 -0
- package/coverage/server/src/routers/notifications.ts.html +364 -0
- package/coverage/server/src/routers/section.ts.html +1120 -0
- package/coverage/server/src/routers/user.ts.html +862 -0
- package/coverage/server/src/routers/worksheet.ts.html +1729 -0
- package/coverage/server/src/trpc.ts.html +397 -0
- package/coverage/server/src/types/index.html +116 -0
- package/coverage/server/src/types/trpc.ts.html +127 -0
- package/coverage/server/src/utils/aiUser.ts.html +280 -0
- package/coverage/server/src/utils/email.ts.html +121 -0
- package/coverage/server/src/utils/generateInviteCode.ts.html +106 -0
- package/coverage/server/src/utils/index.html +206 -0
- package/coverage/server/src/utils/inference.ts.html +709 -0
- package/coverage/server/src/utils/logger.ts.html +664 -0
- package/coverage/server/src/utils/prismaErrorHandler.ts.html +907 -0
- package/coverage/server/src/utils/prismaWrapper.ts.html +355 -0
- package/coverage/server/vitest.config.ts.html +196 -0
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +210 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +83 -52
- package/dist/index.js.map +1 -1
- package/dist/instrument.js +15 -8
- package/dist/instrument.js.map +1 -1
- package/dist/lib/config/env.d.ts +169 -0
- package/dist/lib/config/env.d.ts.map +1 -0
- package/dist/lib/config/env.js +115 -0
- package/dist/lib/config/env.js.map +1 -0
- package/dist/lib/fileUpload.d.ts.map +1 -1
- package/dist/lib/fileUpload.js +5 -4
- package/dist/lib/fileUpload.js.map +1 -1
- package/dist/lib/googleCloudStorage.d.ts.map +1 -1
- package/dist/lib/googleCloudStorage.js +7 -8
- package/dist/lib/googleCloudStorage.js.map +1 -1
- package/dist/lib/jsonConversion.d.ts.map +1 -1
- package/dist/lib/jsonConversion.js +14 -16
- package/dist/lib/jsonConversion.js.map +1 -1
- package/dist/lib/notificationHandler.d.ts +2 -2
- package/dist/lib/prisma.d.ts +2 -2
- package/dist/lib/prisma.d.ts.map +1 -1
- package/dist/lib/prisma.js +22 -3
- package/dist/lib/prisma.js.map +1 -1
- package/dist/lib/pusher.d.ts.map +1 -1
- package/dist/lib/pusher.js +8 -7
- package/dist/lib/pusher.js.map +1 -1
- package/dist/middleware/auth.d.ts.map +1 -1
- package/dist/middleware/auth.js +6 -5
- package/dist/middleware/auth.js.map +1 -1
- package/dist/middleware/security.d.ts +5 -0
- package/dist/middleware/security.d.ts.map +1 -0
- package/dist/middleware/security.js +77 -0
- package/dist/middleware/security.js.map +1 -0
- package/dist/routers/_app.d.ts +304 -98
- package/dist/routers/_app.d.ts.map +1 -1
- package/dist/routers/_app.js +4 -2
- package/dist/routers/_app.js.map +1 -1
- package/dist/routers/agenda.d.ts.map +1 -1
- package/dist/routers/agenda.js +12 -9
- package/dist/routers/agenda.js.map +1 -1
- package/dist/routers/announcement.d.ts +8 -0
- package/dist/routers/announcement.d.ts.map +1 -1
- package/dist/routers/announcement.js +6 -4
- package/dist/routers/announcement.js.map +1 -1
- package/dist/routers/assignment.d.ts +7 -4
- package/dist/routers/assignment.d.ts.map +1 -1
- package/dist/routers/assignment.js +35 -18
- package/dist/routers/assignment.js.map +1 -1
- package/dist/routers/attendance.d.ts +1 -0
- package/dist/routers/attendance.d.ts.map +1 -1
- package/dist/routers/attendance.js +4 -4
- package/dist/routers/attendance.js.map +1 -1
- package/dist/routers/auth.d.ts +20 -0
- package/dist/routers/auth.d.ts.map +1 -1
- package/dist/routers/auth.js +132 -15
- package/dist/routers/auth.js.map +1 -1
- package/dist/routers/class.d.ts +10 -0
- package/dist/routers/class.d.ts.map +1 -1
- package/dist/routers/class.js +49 -5
- package/dist/routers/class.js.map +1 -1
- package/dist/routers/comment.d.ts +7 -0
- package/dist/routers/comment.d.ts.map +1 -1
- package/dist/routers/comment.js +9 -2
- package/dist/routers/comment.js.map +1 -1
- package/dist/routers/conversation.d.ts +1 -0
- package/dist/routers/conversation.d.ts.map +1 -1
- package/dist/routers/conversation.js +46 -31
- package/dist/routers/conversation.js.map +1 -1
- package/dist/routers/file.d.ts.map +1 -1
- package/dist/routers/file.js +30 -7
- package/dist/routers/file.js.map +1 -1
- package/dist/routers/labChat.d.ts +1 -0
- package/dist/routers/labChat.d.ts.map +1 -1
- package/dist/routers/labChat.js +2 -3
- package/dist/routers/labChat.js.map +1 -1
- package/dist/routers/marketing.d.ts +1 -1
- package/dist/routers/newtonChat.d.ts +55 -0
- package/dist/routers/newtonChat.d.ts.map +1 -0
- package/dist/routers/newtonChat.js +438 -0
- package/dist/routers/newtonChat.js.map +1 -0
- package/dist/routers/notifications.d.ts +4 -4
- package/dist/routers/section.d.ts +9 -4
- package/dist/routers/section.d.ts.map +1 -1
- package/dist/routers/section.js +8 -8
- package/dist/routers/section.js.map +1 -1
- package/dist/routers/user.d.ts.map +1 -1
- package/dist/routers/user.js +5 -4
- package/dist/routers/user.js.map +1 -1
- package/dist/routers/worksheet.d.ts +30 -36
- package/dist/routers/worksheet.d.ts.map +1 -1
- package/dist/routers/worksheet.js +11 -33
- package/dist/routers/worksheet.js.map +1 -1
- package/dist/seedDatabase.d.ts +1 -1
- package/dist/seedDatabase.js +275 -284
- package/dist/seedDatabase.js.map +1 -1
- package/dist/server/pipelines/aiLabChat.d.ts +10 -0
- package/dist/server/pipelines/aiLabChat.d.ts.map +1 -0
- package/dist/server/pipelines/aiLabChat.js +83 -0
- package/dist/server/pipelines/aiLabChat.js.map +1 -0
- package/dist/server/pipelines/gradeWorksheet.d.ts +2 -0
- package/dist/server/pipelines/gradeWorksheet.d.ts.map +1 -0
- package/dist/server/pipelines/gradeWorksheet.js +138 -0
- package/dist/server/pipelines/gradeWorksheet.js.map +1 -0
- package/dist/trpc.d.ts.map +1 -1
- package/dist/trpc.js +2 -2
- package/dist/trpc.js.map +1 -1
- package/dist/utils/email.d.ts +9 -1
- package/dist/utils/email.d.ts.map +1 -1
- package/dist/utils/email.js +20 -5
- package/dist/utils/email.js.map +1 -1
- package/dist/utils/inference.d.ts +3 -0
- package/dist/utils/inference.d.ts.map +1 -1
- package/dist/utils/inference.js +41 -7
- package/dist/utils/inference.js.map +1 -1
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +3 -3
- package/dist/utils/logger.js.map +1 -1
- package/docker-compose.yml +14 -0
- package/package.json +13 -4
- package/prisma/schema.prisma +32 -5
- package/scripts/test-pre-push.ts +14 -0
- package/src/index.ts +98 -54
- package/src/instrument.ts +13 -6
- package/src/lib/config/env.ts +126 -0
- package/src/lib/fileUpload.ts +3 -2
- package/src/lib/googleCloudStorage.ts +6 -6
- package/src/lib/jsonConversion.ts +12 -14
- package/src/lib/prisma.ts +23 -2
- package/src/lib/pusher.ts +6 -5
- package/src/middleware/auth.ts +4 -3
- package/src/middleware/security.ts +80 -0
- package/src/routers/_app.ts +2 -0
- package/src/routers/agenda.ts +10 -7
- package/src/routers/announcement.ts +4 -2
- package/src/routers/assignment.ts +58 -40
- package/src/routers/attendance.ts +2 -2
- package/src/routers/auth.ts +143 -14
- package/src/routers/class.ts +52 -3
- package/src/routers/comment.ts +7 -0
- package/src/routers/conversation.ts +49 -29
- package/src/routers/file.ts +29 -5
- package/src/routers/labChat.ts +0 -1
- package/src/routers/newtonChat.ts +520 -0
- package/src/routers/section.ts +6 -6
- package/src/routers/user.ts +3 -2
- package/src/routers/worksheet.ts +9 -37
- package/src/seedDatabase.ts +290 -283
- package/src/server/pipelines/aiLabChat.ts +92 -0
- package/src/server/pipelines/gradeWorksheet.ts +152 -0
- package/src/trpc.ts +2 -0
- package/src/utils/email.ts +30 -3
- package/src/utils/inference.ts +50 -5
- package/src/utils/logger.ts +2 -1
- package/tests/announcement.test.ts +164 -0
- package/tests/assignment.test.ts +296 -0
- package/tests/attendance.test.ts +168 -0
- package/tests/auth.test.ts +33 -10
- package/tests/class.test.ts +34 -9
- package/tests/event.test.ts +228 -0
- package/tests/section.test.ts +216 -0
- package/tests/setup.ts +70 -16
- package/tests/user.test.ts +158 -0
- package/vitest.config.ts +26 -0
- package/API_SPECIFICATION.md +0 -1597
- package/BASE64_REMOVAL_SUMMARY.md +0 -164
- package/CHAT_API_SPEC.md +0 -579
- package/LAB_CHAT_API_SPEC.md +0 -518
- package/dist/routers/school.d.ts +0 -208
- package/dist/routers/school.d.ts.map +0 -1
- package/dist/routers/school.js +0 -483
package/LAB_CHAT_API_SPEC.md
DELETED
|
@@ -1,518 +0,0 @@
|
|
|
1
|
-
# AI Lab Chat API Specification - Studious LMS
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
|
|
5
|
-
AI Lab Chat system extends the regular chat functionality to provide class-bound AI-powered conversations with contextual learning environments. Teachers can create lab chats with specific AI contexts, and students can interact within these structured learning spaces.
|
|
6
|
-
|
|
7
|
-
### Key Features
|
|
8
|
-
- **Class Integration**: Lab chats are bound to specific classes
|
|
9
|
-
- **AI Context**: Each lab has a JSON context string for LLM integration
|
|
10
|
-
- **Isolated Conversations**: Lab chats don't appear in regular chat lists
|
|
11
|
-
- **Teacher Management**: Only teachers can create/delete lab chats
|
|
12
|
-
- **Real-time Updates**: Full Pusher integration for live collaboration
|
|
13
|
-
|
|
14
|
-
---
|
|
15
|
-
|
|
16
|
-
## 🔐 Authentication
|
|
17
|
-
|
|
18
|
-
All lab chat endpoints require authentication via Bearer token and appropriate class permissions.
|
|
19
|
-
|
|
20
|
-
---
|
|
21
|
-
|
|
22
|
-
## 📝 Data Models
|
|
23
|
-
|
|
24
|
-
### LabChat Object
|
|
25
|
-
```typescript
|
|
26
|
-
interface LabChat {
|
|
27
|
-
id: string;
|
|
28
|
-
title: string;
|
|
29
|
-
context: string; // JSON string for LLM context
|
|
30
|
-
classId: string;
|
|
31
|
-
conversationId: string;
|
|
32
|
-
createdById: string;
|
|
33
|
-
createdAt: Date;
|
|
34
|
-
updatedAt: Date;
|
|
35
|
-
|
|
36
|
-
// Relations
|
|
37
|
-
class: {
|
|
38
|
-
id: string;
|
|
39
|
-
name: string;
|
|
40
|
-
subject: string;
|
|
41
|
-
section: string;
|
|
42
|
-
};
|
|
43
|
-
createdBy: User;
|
|
44
|
-
conversation: Conversation;
|
|
45
|
-
}
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
### Lab Chat Message
|
|
49
|
-
```typescript
|
|
50
|
-
interface LabChatMessage {
|
|
51
|
-
id: string;
|
|
52
|
-
content: string;
|
|
53
|
-
senderId: string;
|
|
54
|
-
conversationId: string;
|
|
55
|
-
createdAt: Date;
|
|
56
|
-
sender: User;
|
|
57
|
-
mentionedUserIds: string[];
|
|
58
|
-
labChatId: string; // Additional context for lab chats
|
|
59
|
-
}
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
---
|
|
63
|
-
|
|
64
|
-
## 🧪 Lab Chat Endpoints
|
|
65
|
-
|
|
66
|
-
### `labChat.create`
|
|
67
|
-
**Type**: Mutation
|
|
68
|
-
**Access**: Teacher Only
|
|
69
|
-
**Description**: Create a new AI lab chat for a class
|
|
70
|
-
|
|
71
|
-
**Input**:
|
|
72
|
-
```typescript
|
|
73
|
-
{
|
|
74
|
-
classId: string;
|
|
75
|
-
title: string; // 1-200 characters
|
|
76
|
-
context: string; // Valid JSON string for LLM context
|
|
77
|
-
}
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
**Output**: `LabChat` (full object with relations)
|
|
81
|
-
|
|
82
|
-
**Example**:
|
|
83
|
-
```typescript
|
|
84
|
-
const labChat = await trpc.labChat.create.mutate({
|
|
85
|
-
classId: 'class-123',
|
|
86
|
-
title: 'Python Debugging Lab',
|
|
87
|
-
context: JSON.stringify({
|
|
88
|
-
subject: 'Computer Science',
|
|
89
|
-
topic: 'Python Debugging',
|
|
90
|
-
difficulty: 'intermediate',
|
|
91
|
-
objectives: [
|
|
92
|
-
'Identify common Python errors',
|
|
93
|
-
'Use debugging tools effectively',
|
|
94
|
-
'Apply systematic debugging approaches'
|
|
95
|
-
],
|
|
96
|
-
resources: [
|
|
97
|
-
'Python documentation',
|
|
98
|
-
'PDB debugger guide'
|
|
99
|
-
],
|
|
100
|
-
persona: 'helpful coding mentor',
|
|
101
|
-
constraints: [
|
|
102
|
-
'Provide hints rather than direct answers',
|
|
103
|
-
'Encourage best practices',
|
|
104
|
-
'Focus on learning process'
|
|
105
|
-
]
|
|
106
|
-
})
|
|
107
|
-
});
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
**Notes**:
|
|
111
|
-
- Creates a GROUP conversation with all class members
|
|
112
|
-
- Teachers become ADMINs, students become MEMBERs
|
|
113
|
-
- Lab chats have `displayInChat: false` (hidden from regular chat)
|
|
114
|
-
- Broadcasts `lab-chat-created` event to class channel
|
|
115
|
-
|
|
116
|
-
---
|
|
117
|
-
|
|
118
|
-
### `labChat.get`
|
|
119
|
-
**Type**: Query
|
|
120
|
-
**Access**: Class Member
|
|
121
|
-
**Description**: Get specific lab chat details
|
|
122
|
-
|
|
123
|
-
**Input**:
|
|
124
|
-
```typescript
|
|
125
|
-
{
|
|
126
|
-
labChatId: string;
|
|
127
|
-
}
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
**Output**: `LabChat` (full object with conversation and members)
|
|
131
|
-
|
|
132
|
-
**Example**:
|
|
133
|
-
```typescript
|
|
134
|
-
const labChat = await trpc.labChat.get.query({
|
|
135
|
-
labChatId: 'lab-456'
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
// Access the AI context
|
|
139
|
-
const aiContext = JSON.parse(labChat.context);
|
|
140
|
-
console.log('Lab objectives:', aiContext.objectives);
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
---
|
|
144
|
-
|
|
145
|
-
### `labChat.list`
|
|
146
|
-
**Type**: Query
|
|
147
|
-
**Access**: Class Member
|
|
148
|
-
**Description**: Get all lab chats for a class
|
|
149
|
-
|
|
150
|
-
**Input**:
|
|
151
|
-
```typescript
|
|
152
|
-
{
|
|
153
|
-
classId: string;
|
|
154
|
-
}
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
**Output**:
|
|
158
|
-
```typescript
|
|
159
|
-
Array<{
|
|
160
|
-
id: string;
|
|
161
|
-
title: string;
|
|
162
|
-
classId: string;
|
|
163
|
-
conversationId: string;
|
|
164
|
-
createdBy: User;
|
|
165
|
-
createdAt: Date;
|
|
166
|
-
updatedAt: Date;
|
|
167
|
-
lastMessage?: Message;
|
|
168
|
-
messageCount: number;
|
|
169
|
-
}>
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
**Example**:
|
|
173
|
-
```typescript
|
|
174
|
-
const labChats = await trpc.labChat.list.query({
|
|
175
|
-
classId: 'class-123'
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
// Display in UI
|
|
179
|
-
labChats.forEach(lab => {
|
|
180
|
-
console.log(`${lab.title} - ${lab.messageCount} messages`);
|
|
181
|
-
});
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
---
|
|
185
|
-
|
|
186
|
-
### `labChat.postToLabChat`
|
|
187
|
-
**Type**: Mutation
|
|
188
|
-
**Access**: Class Member
|
|
189
|
-
**Description**: Send a message to a lab chat
|
|
190
|
-
|
|
191
|
-
**Input**:
|
|
192
|
-
```typescript
|
|
193
|
-
{
|
|
194
|
-
labChatId: string;
|
|
195
|
-
content: string; // 1-4000 characters
|
|
196
|
-
mentionedUserIds?: string[]; // Optional mentions
|
|
197
|
-
}
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
**Output**: `LabChatMessage`
|
|
201
|
-
|
|
202
|
-
**Example**:
|
|
203
|
-
```typescript
|
|
204
|
-
// Student asks a question
|
|
205
|
-
const message = await trpc.labChat.postToLabChat.mutate({
|
|
206
|
-
labChatId: 'lab-456',
|
|
207
|
-
content: 'I\'m getting a KeyError in my Python code. Can someone help?'
|
|
208
|
-
});
|
|
209
|
-
|
|
210
|
-
// Teacher responds with mention
|
|
211
|
-
const response = await trpc.labChat.postToLabChat.mutate({
|
|
212
|
-
labChatId: 'lab-456',
|
|
213
|
-
content: '@john Can you share the specific error traceback?',
|
|
214
|
-
mentionedUserIds: ['student-john-id']
|
|
215
|
-
});
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
**Notes**:
|
|
219
|
-
- Works exactly like regular message.send but for lab contexts
|
|
220
|
-
- Updates lab chat `updatedAt` timestamp
|
|
221
|
-
- Broadcasts to conversation channel with `labChatId` context
|
|
222
|
-
- Perfect for AI integration on the frontend
|
|
223
|
-
|
|
224
|
-
---
|
|
225
|
-
|
|
226
|
-
### `labChat.delete`
|
|
227
|
-
**Type**: Mutation
|
|
228
|
-
**Access**: Creator Only
|
|
229
|
-
**Description**: Delete a lab chat and all associated data
|
|
230
|
-
|
|
231
|
-
**Input**:
|
|
232
|
-
```typescript
|
|
233
|
-
{
|
|
234
|
-
labChatId: string;
|
|
235
|
-
}
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
**Output**:
|
|
239
|
-
```typescript
|
|
240
|
-
{
|
|
241
|
-
success: boolean;
|
|
242
|
-
}
|
|
243
|
-
```
|
|
244
|
-
|
|
245
|
-
**Example**:
|
|
246
|
-
```typescript
|
|
247
|
-
await trpc.labChat.delete.mutate({
|
|
248
|
-
labChatId: 'lab-456'
|
|
249
|
-
});
|
|
250
|
-
```
|
|
251
|
-
|
|
252
|
-
**Notes**:
|
|
253
|
-
- Only the creator (teacher) can delete
|
|
254
|
-
- Cascades: deletes conversation, messages, mentions, members
|
|
255
|
-
- Broadcasts `lab-chat-deleted` event to class channel
|
|
256
|
-
|
|
257
|
-
---
|
|
258
|
-
|
|
259
|
-
## 🔴 Real-time Events (Pusher)
|
|
260
|
-
|
|
261
|
-
### Class-Level Events
|
|
262
|
-
**Channel**: `class-{classId}`
|
|
263
|
-
|
|
264
|
-
#### `lab-chat-created`
|
|
265
|
-
```typescript
|
|
266
|
-
{
|
|
267
|
-
id: string;
|
|
268
|
-
title: string;
|
|
269
|
-
classId: string;
|
|
270
|
-
conversationId: string;
|
|
271
|
-
createdBy: User;
|
|
272
|
-
createdAt: Date;
|
|
273
|
-
}
|
|
274
|
-
```
|
|
275
|
-
|
|
276
|
-
#### `lab-chat-deleted`
|
|
277
|
-
```typescript
|
|
278
|
-
{
|
|
279
|
-
labChatId: string;
|
|
280
|
-
classId: string;
|
|
281
|
-
}
|
|
282
|
-
```
|
|
283
|
-
|
|
284
|
-
### Lab Chat Messages
|
|
285
|
-
**Channel**: `conversation-{conversationId}`
|
|
286
|
-
|
|
287
|
-
#### `new-message` (Enhanced)
|
|
288
|
-
```typescript
|
|
289
|
-
{
|
|
290
|
-
id: string;
|
|
291
|
-
content: string;
|
|
292
|
-
senderId: string;
|
|
293
|
-
conversationId: string;
|
|
294
|
-
createdAt: Date;
|
|
295
|
-
sender: User;
|
|
296
|
-
mentionedUserIds: string[];
|
|
297
|
-
labChatId: string; // Additional context for lab chats
|
|
298
|
-
}
|
|
299
|
-
```
|
|
300
|
-
|
|
301
|
-
---
|
|
302
|
-
|
|
303
|
-
## 🤖 AI Integration Guide
|
|
304
|
-
|
|
305
|
-
### Context Structure
|
|
306
|
-
The `context` field should be a JSON string containing AI instructions:
|
|
307
|
-
|
|
308
|
-
```typescript
|
|
309
|
-
interface AIContext {
|
|
310
|
-
subject: string; // Course subject
|
|
311
|
-
topic: string; // Specific topic
|
|
312
|
-
difficulty: 'beginner' | 'intermediate' | 'advanced';
|
|
313
|
-
objectives: string[]; // Learning objectives
|
|
314
|
-
resources?: string[]; // Available resources
|
|
315
|
-
persona: string; // AI personality/role
|
|
316
|
-
constraints: string[]; // Behavioral constraints
|
|
317
|
-
examples?: any[]; // Example problems/solutions
|
|
318
|
-
metadata?: Record<string, any>; // Additional context
|
|
319
|
-
}
|
|
320
|
-
```
|
|
321
|
-
|
|
322
|
-
### Frontend AI Integration Example
|
|
323
|
-
```typescript
|
|
324
|
-
// Get lab chat context
|
|
325
|
-
const labChat = await trpc.labChat.get.query({ labChatId });
|
|
326
|
-
const aiContext = JSON.parse(labChat.context);
|
|
327
|
-
|
|
328
|
-
// Send to AI service with context
|
|
329
|
-
const aiResponse = await fetch('/api/ai/chat', {
|
|
330
|
-
method: 'POST',
|
|
331
|
-
body: JSON.stringify({
|
|
332
|
-
message: userMessage,
|
|
333
|
-
context: aiContext,
|
|
334
|
-
conversationHistory: messages.slice(-10) // Last 10 messages
|
|
335
|
-
})
|
|
336
|
-
});
|
|
337
|
-
|
|
338
|
-
// Post AI response to lab chat
|
|
339
|
-
await trpc.labChat.postToLabChat.mutate({
|
|
340
|
-
labChatId,
|
|
341
|
-
content: aiResponse.content
|
|
342
|
-
});
|
|
343
|
-
```
|
|
344
|
-
|
|
345
|
-
---
|
|
346
|
-
|
|
347
|
-
## 🎨 UI/UX Patterns
|
|
348
|
-
|
|
349
|
-
### Lab Chat List
|
|
350
|
-
```typescript
|
|
351
|
-
function LabChatList({ classId }: { classId: string }) {
|
|
352
|
-
const { data: labChats } = trpc.labChat.list.useQuery({ classId });
|
|
353
|
-
|
|
354
|
-
return (
|
|
355
|
-
<div className="lab-chat-list">
|
|
356
|
-
{labChats?.map(lab => (
|
|
357
|
-
<div key={lab.id} className="lab-chat-item">
|
|
358
|
-
<div className="lab-header">
|
|
359
|
-
<h3>{lab.title}</h3>
|
|
360
|
-
<span className="message-count">{lab.messageCount} messages</span>
|
|
361
|
-
</div>
|
|
362
|
-
<div className="lab-meta">
|
|
363
|
-
<span>Created by {lab.createdBy.profile?.displayName || lab.createdBy.username}</span>
|
|
364
|
-
<span>{formatDate(lab.createdAt)}</span>
|
|
365
|
-
</div>
|
|
366
|
-
{lab.lastMessage && (
|
|
367
|
-
<div className="last-message">
|
|
368
|
-
<strong>{lab.lastMessage.sender.username}:</strong>
|
|
369
|
-
<span>{lab.lastMessage.content.substring(0, 100)}...</span>
|
|
370
|
-
</div>
|
|
371
|
-
)}
|
|
372
|
-
</div>
|
|
373
|
-
))}
|
|
374
|
-
</div>
|
|
375
|
-
);
|
|
376
|
-
}
|
|
377
|
-
```
|
|
378
|
-
|
|
379
|
-
### Lab Chat Interface
|
|
380
|
-
```typescript
|
|
381
|
-
function LabChatInterface({ labChatId }: { labChatId: string }) {
|
|
382
|
-
const { data: labChat } = trpc.labChat.get.useQuery({ labChatId });
|
|
383
|
-
const { data: messages } = trpc.message.list.useQuery({
|
|
384
|
-
conversationId: labChat?.conversationId
|
|
385
|
-
});
|
|
386
|
-
|
|
387
|
-
const aiContext = labChat ? JSON.parse(labChat.context) : null;
|
|
388
|
-
|
|
389
|
-
return (
|
|
390
|
-
<div className="lab-chat-interface">
|
|
391
|
-
<div className="lab-header">
|
|
392
|
-
<h2>{labChat?.title}</h2>
|
|
393
|
-
<div className="lab-context-preview">
|
|
394
|
-
<strong>Topic:</strong> {aiContext?.topic}
|
|
395
|
-
<strong>Difficulty:</strong> {aiContext?.difficulty}
|
|
396
|
-
</div>
|
|
397
|
-
</div>
|
|
398
|
-
|
|
399
|
-
<div className="messages-area">
|
|
400
|
-
{messages?.messages.map(message => (
|
|
401
|
-
<MessageComponent
|
|
402
|
-
key={message.id}
|
|
403
|
-
message={message}
|
|
404
|
-
isLabChat={true}
|
|
405
|
-
/>
|
|
406
|
-
))}
|
|
407
|
-
</div>
|
|
408
|
-
|
|
409
|
-
<MessageInput
|
|
410
|
-
onSend={(content, mentions) =>
|
|
411
|
-
trpc.labChat.postToLabChat.mutate({
|
|
412
|
-
labChatId,
|
|
413
|
-
content,
|
|
414
|
-
mentionedUserIds: mentions
|
|
415
|
-
})
|
|
416
|
-
}
|
|
417
|
-
placeholder="Ask a question or share your progress..."
|
|
418
|
-
/>
|
|
419
|
-
</div>
|
|
420
|
-
);
|
|
421
|
-
}
|
|
422
|
-
```
|
|
423
|
-
|
|
424
|
-
---
|
|
425
|
-
|
|
426
|
-
## 🚀 Implementation Workflow
|
|
427
|
-
|
|
428
|
-
### For Teachers:
|
|
429
|
-
1. **Create Lab**: Set up lab with title and AI context
|
|
430
|
-
2. **Monitor Progress**: View student questions and interactions
|
|
431
|
-
3. **Provide Guidance**: Answer questions and guide discussions
|
|
432
|
-
4. **Manage Labs**: Delete completed or outdated labs
|
|
433
|
-
|
|
434
|
-
### For Students:
|
|
435
|
-
1. **Join Lab**: Access lab chats from class dashboard
|
|
436
|
-
2. **Ask Questions**: Post questions and get AI/peer help
|
|
437
|
-
3. **Collaborate**: Work together on problems
|
|
438
|
-
4. **Learn**: Benefit from AI-guided learning experience
|
|
439
|
-
|
|
440
|
-
### For AI Integration:
|
|
441
|
-
1. **Context Awareness**: Use lab context for relevant responses
|
|
442
|
-
2. **Educational Focus**: Maintain learning-oriented conversations
|
|
443
|
-
3. **Progress Tracking**: Monitor student understanding
|
|
444
|
-
4. **Adaptive Responses**: Adjust difficulty based on context
|
|
445
|
-
|
|
446
|
-
---
|
|
447
|
-
|
|
448
|
-
## 📊 Use Cases
|
|
449
|
-
|
|
450
|
-
### Programming Labs
|
|
451
|
-
```json
|
|
452
|
-
{
|
|
453
|
-
"subject": "Computer Science",
|
|
454
|
-
"topic": "Data Structures - Binary Trees",
|
|
455
|
-
"difficulty": "intermediate",
|
|
456
|
-
"objectives": [
|
|
457
|
-
"Implement binary tree operations",
|
|
458
|
-
"Understand tree traversal algorithms",
|
|
459
|
-
"Analyze time complexity"
|
|
460
|
-
],
|
|
461
|
-
"persona": "patient coding mentor",
|
|
462
|
-
"constraints": [
|
|
463
|
-
"Provide pseudocode hints before full solutions",
|
|
464
|
-
"Encourage testing and debugging",
|
|
465
|
-
"Focus on algorithmic thinking"
|
|
466
|
-
]
|
|
467
|
-
}
|
|
468
|
-
```
|
|
469
|
-
|
|
470
|
-
### Science Labs
|
|
471
|
-
```json
|
|
472
|
-
{
|
|
473
|
-
"subject": "Chemistry",
|
|
474
|
-
"topic": "Acid-Base Reactions",
|
|
475
|
-
"difficulty": "beginner",
|
|
476
|
-
"objectives": [
|
|
477
|
-
"Identify acids and bases",
|
|
478
|
-
"Predict reaction products",
|
|
479
|
-
"Balance chemical equations"
|
|
480
|
-
],
|
|
481
|
-
"persona": "encouraging science teacher",
|
|
482
|
-
"resources": [
|
|
483
|
-
"Periodic table",
|
|
484
|
-
"pH scale reference"
|
|
485
|
-
],
|
|
486
|
-
"constraints": [
|
|
487
|
-
"Use simple language",
|
|
488
|
-
"Provide step-by-step guidance",
|
|
489
|
-
"Relate to real-world examples"
|
|
490
|
-
]
|
|
491
|
-
}
|
|
492
|
-
```
|
|
493
|
-
|
|
494
|
-
### Math Labs
|
|
495
|
-
```json
|
|
496
|
-
{
|
|
497
|
-
"subject": "Mathematics",
|
|
498
|
-
"topic": "Calculus - Derivatives",
|
|
499
|
-
"difficulty": "advanced",
|
|
500
|
-
"objectives": [
|
|
501
|
-
"Apply derivative rules",
|
|
502
|
-
"Solve optimization problems",
|
|
503
|
-
"Interpret graphical meaning"
|
|
504
|
-
],
|
|
505
|
-
"persona": "rigorous math tutor",
|
|
506
|
-
"constraints": [
|
|
507
|
-
"Show work step-by-step",
|
|
508
|
-
"Explain reasoning behind each step",
|
|
509
|
-
"Connect to geometric interpretation"
|
|
510
|
-
]
|
|
511
|
-
}
|
|
512
|
-
```
|
|
513
|
-
|
|
514
|
-
---
|
|
515
|
-
|
|
516
|
-
**Generated**: September 25, 2025
|
|
517
|
-
**Version**: 1.0
|
|
518
|
-
**Backend Version**: Compatible with Studious LMS Server v1.1.8+
|
package/dist/routers/school.d.ts
DELETED
|
@@ -1,208 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
export declare const schoolRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
3
|
-
ctx: import("../trpc").Context;
|
|
4
|
-
meta: object;
|
|
5
|
-
errorShape: {
|
|
6
|
-
data: {
|
|
7
|
-
zodError: z.typeToFlattenedError<any, string> | null;
|
|
8
|
-
prismaError: null;
|
|
9
|
-
code: import("@trpc/server").TRPC_ERROR_CODE_KEY;
|
|
10
|
-
httpStatus: number;
|
|
11
|
-
path?: string;
|
|
12
|
-
stack?: string;
|
|
13
|
-
};
|
|
14
|
-
message: string;
|
|
15
|
-
code: import("@trpc/server").TRPC_ERROR_CODE_NUMBER;
|
|
16
|
-
};
|
|
17
|
-
transformer: false;
|
|
18
|
-
}, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
|
|
19
|
-
createSchool: import("@trpc/server").TRPCMutationProcedure<{
|
|
20
|
-
input: {
|
|
21
|
-
name: string;
|
|
22
|
-
subdomain: string;
|
|
23
|
-
};
|
|
24
|
-
output: {
|
|
25
|
-
id: string;
|
|
26
|
-
name: string;
|
|
27
|
-
logoId: string;
|
|
28
|
-
subdomain: string | null;
|
|
29
|
-
};
|
|
30
|
-
meta: object;
|
|
31
|
-
}>;
|
|
32
|
-
checkAdmin: import("@trpc/server").TRPCQueryProcedure<{
|
|
33
|
-
input: {
|
|
34
|
-
schoolId: string;
|
|
35
|
-
};
|
|
36
|
-
output: boolean;
|
|
37
|
-
meta: object;
|
|
38
|
-
}>;
|
|
39
|
-
getUsers: import("@trpc/server").TRPCQueryProcedure<{
|
|
40
|
-
input: {
|
|
41
|
-
schoolId: string;
|
|
42
|
-
role?: "STUDENT" | "TEACHER" | "ADMIN" | "NONE" | undefined;
|
|
43
|
-
};
|
|
44
|
-
output: {
|
|
45
|
-
id: string;
|
|
46
|
-
username: string;
|
|
47
|
-
email: string;
|
|
48
|
-
verified: boolean;
|
|
49
|
-
role: import(".prisma/client").$Enums.UserRole;
|
|
50
|
-
profile: {
|
|
51
|
-
id: string;
|
|
52
|
-
userId: string;
|
|
53
|
-
} | null;
|
|
54
|
-
}[];
|
|
55
|
-
meta: object;
|
|
56
|
-
}>;
|
|
57
|
-
createUser: import("@trpc/server").TRPCMutationProcedure<{
|
|
58
|
-
input: {
|
|
59
|
-
username: string;
|
|
60
|
-
email: string;
|
|
61
|
-
role: "STUDENT" | "TEACHER" | "ADMIN" | "NONE";
|
|
62
|
-
schoolId: string;
|
|
63
|
-
sendInvite?: boolean | undefined;
|
|
64
|
-
};
|
|
65
|
-
output: {
|
|
66
|
-
id: string;
|
|
67
|
-
username: string;
|
|
68
|
-
email: string;
|
|
69
|
-
password: string;
|
|
70
|
-
verified: boolean;
|
|
71
|
-
role: import(".prisma/client").$Enums.UserRole;
|
|
72
|
-
profileId: string | null;
|
|
73
|
-
schoolId: string | null;
|
|
74
|
-
};
|
|
75
|
-
meta: object;
|
|
76
|
-
}>;
|
|
77
|
-
bulkCreateUsers: import("@trpc/server").TRPCMutationProcedure<{
|
|
78
|
-
input: {
|
|
79
|
-
schoolId: string;
|
|
80
|
-
users: {
|
|
81
|
-
username: string;
|
|
82
|
-
email: string;
|
|
83
|
-
role: "STUDENT" | "TEACHER" | "ADMIN" | "NONE";
|
|
84
|
-
}[];
|
|
85
|
-
};
|
|
86
|
-
output: {
|
|
87
|
-
results: never[];
|
|
88
|
-
errors: never[];
|
|
89
|
-
};
|
|
90
|
-
meta: object;
|
|
91
|
-
}>;
|
|
92
|
-
updateUser: import("@trpc/server").TRPCMutationProcedure<{
|
|
93
|
-
input: {
|
|
94
|
-
schoolId: string;
|
|
95
|
-
userId: string;
|
|
96
|
-
verified?: boolean | undefined;
|
|
97
|
-
role?: "STUDENT" | "TEACHER" | "ADMIN" | "NONE" | undefined;
|
|
98
|
-
};
|
|
99
|
-
output: {
|
|
100
|
-
id: string;
|
|
101
|
-
username: string;
|
|
102
|
-
email: string;
|
|
103
|
-
password: string;
|
|
104
|
-
verified: boolean;
|
|
105
|
-
role: import(".prisma/client").$Enums.UserRole;
|
|
106
|
-
profileId: string | null;
|
|
107
|
-
schoolId: string | null;
|
|
108
|
-
};
|
|
109
|
-
meta: object;
|
|
110
|
-
}>;
|
|
111
|
-
deleteUser: import("@trpc/server").TRPCMutationProcedure<{
|
|
112
|
-
input: {
|
|
113
|
-
schoolId: string;
|
|
114
|
-
userId: string;
|
|
115
|
-
};
|
|
116
|
-
output: {
|
|
117
|
-
id: string;
|
|
118
|
-
username: string;
|
|
119
|
-
email: string;
|
|
120
|
-
password: string;
|
|
121
|
-
verified: boolean;
|
|
122
|
-
role: import(".prisma/client").$Enums.UserRole;
|
|
123
|
-
profileId: string | null;
|
|
124
|
-
schoolId: string | null;
|
|
125
|
-
};
|
|
126
|
-
meta: object;
|
|
127
|
-
}>;
|
|
128
|
-
getSchool: import("@trpc/server").TRPCQueryProcedure<{
|
|
129
|
-
input: {
|
|
130
|
-
schoolId: string;
|
|
131
|
-
};
|
|
132
|
-
output: ({
|
|
133
|
-
_count: {
|
|
134
|
-
users: number;
|
|
135
|
-
classes: number;
|
|
136
|
-
};
|
|
137
|
-
logo: {
|
|
138
|
-
path: string;
|
|
139
|
-
type: string;
|
|
140
|
-
id: string;
|
|
141
|
-
name: string;
|
|
142
|
-
size: number | null;
|
|
143
|
-
uploadedAt: Date | null;
|
|
144
|
-
assignmentId: string | null;
|
|
145
|
-
submissionId: string | null;
|
|
146
|
-
userId: string | null;
|
|
147
|
-
thumbnailId: string | null;
|
|
148
|
-
annotationId: string | null;
|
|
149
|
-
classDraftId: string | null;
|
|
150
|
-
folderId: string | null;
|
|
151
|
-
};
|
|
152
|
-
} & {
|
|
153
|
-
id: string;
|
|
154
|
-
name: string;
|
|
155
|
-
logoId: string;
|
|
156
|
-
subdomain: string | null;
|
|
157
|
-
}) | null;
|
|
158
|
-
meta: object;
|
|
159
|
-
}>;
|
|
160
|
-
updateSchool: import("@trpc/server").TRPCMutationProcedure<{
|
|
161
|
-
input: {
|
|
162
|
-
schoolId: string;
|
|
163
|
-
name?: string | undefined;
|
|
164
|
-
logoId?: string | undefined;
|
|
165
|
-
subdomain?: string | undefined;
|
|
166
|
-
};
|
|
167
|
-
output: {
|
|
168
|
-
id: string;
|
|
169
|
-
name: string;
|
|
170
|
-
logoId: string;
|
|
171
|
-
subdomain: string | null;
|
|
172
|
-
};
|
|
173
|
-
meta: object;
|
|
174
|
-
}>;
|
|
175
|
-
getClasses: import("@trpc/server").TRPCQueryProcedure<{
|
|
176
|
-
input: {
|
|
177
|
-
schoolId: string;
|
|
178
|
-
};
|
|
179
|
-
output: ({
|
|
180
|
-
_count: {
|
|
181
|
-
assignments: number;
|
|
182
|
-
students: number;
|
|
183
|
-
teachers: number;
|
|
184
|
-
};
|
|
185
|
-
} & {
|
|
186
|
-
id: string;
|
|
187
|
-
schoolId: string | null;
|
|
188
|
-
name: string;
|
|
189
|
-
subject: string;
|
|
190
|
-
color: string | null;
|
|
191
|
-
section: string;
|
|
192
|
-
syllabus: string | null;
|
|
193
|
-
})[];
|
|
194
|
-
meta: object;
|
|
195
|
-
}>;
|
|
196
|
-
sendBulkEmail: import("@trpc/server").TRPCMutationProcedure<{
|
|
197
|
-
input: {
|
|
198
|
-
schoolId: string;
|
|
199
|
-
subject: string;
|
|
200
|
-
content: string;
|
|
201
|
-
recipientRole?: "STUDENT" | "TEACHER" | "ADMIN" | "ALL" | undefined;
|
|
202
|
-
recipientIds?: string[] | undefined;
|
|
203
|
-
};
|
|
204
|
-
output: never[];
|
|
205
|
-
meta: object;
|
|
206
|
-
}>;
|
|
207
|
-
}>>;
|
|
208
|
-
//# sourceMappingURL=school.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"school.d.ts","sourceRoot":"","sources":["../../src/routers/school.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AASxB,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4gBvB,CAAC"}
|