@studious-lms/server 1.5.0 → 1.6.0
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/dist/index.js +15 -3
- package/dist/index.js.map +1 -1
- package/dist/lib/config/cors.d.ts.map +1 -1
- package/dist/lib/config/cors.js +3 -2
- package/dist/lib/config/cors.js.map +1 -1
- package/dist/lib/pusher.d.ts +7 -1
- package/dist/lib/pusher.d.ts.map +1 -1
- package/dist/lib/pusher.js +9 -3
- package/dist/lib/pusher.js.map +1 -1
- package/dist/models/attendance.d.ts +16 -7
- package/dist/models/attendance.d.ts.map +1 -1
- package/dist/models/attendance.js +17 -2
- package/dist/models/attendance.js.map +1 -1
- package/dist/models/conversation.d.ts +17 -17
- package/dist/pipelines/aiLabChat.d.ts +20 -9
- package/dist/pipelines/aiLabChat.d.ts.map +1 -1
- package/dist/pipelines/aiLabChat.js +62 -74
- package/dist/pipelines/aiLabChat.js.map +1 -1
- package/dist/pipelines/aiNewtonChat.d.ts +13 -4
- package/dist/pipelines/aiNewtonChat.d.ts.map +1 -1
- package/dist/pipelines/aiNewtonChat.js +39 -27
- package/dist/pipelines/aiNewtonChat.js.map +1 -1
- package/dist/pipelines/pdfToWorksheet.d.ts +31 -2
- package/dist/pipelines/pdfToWorksheet.d.ts.map +1 -1
- package/dist/pipelines/pdfToWorksheet.js +160 -28
- package/dist/pipelines/pdfToWorksheet.js.map +1 -1
- package/dist/routers/_app.d.ts +18 -4
- package/dist/routers/_app.d.ts.map +1 -1
- package/dist/routers/assignment.d.ts.map +1 -1
- package/dist/routers/assignment.js +64 -4
- package/dist/routers/assignment.js.map +1 -1
- package/dist/routers/labChat.d.ts +1 -0
- package/dist/routers/labChat.d.ts.map +1 -1
- package/dist/routers/message.d.ts +3 -0
- package/dist/routers/message.d.ts.map +1 -1
- package/dist/routers/newtonChat.d.ts +1 -0
- package/dist/routers/newtonChat.d.ts.map +1 -1
- package/dist/routers/worksheet.d.ts +4 -2
- package/dist/routers/worksheet.d.ts.map +1 -1
- package/dist/routers/worksheet.js +16 -6
- package/dist/routers/worksheet.js.map +1 -1
- package/dist/services/announcement.js +4 -4
- package/dist/services/announcement.js.map +1 -1
- package/dist/services/assignment.d.ts.map +1 -1
- package/dist/services/assignment.js +16 -6
- package/dist/services/assignment.js.map +1 -1
- package/dist/services/attendance.d.ts.map +1 -1
- package/dist/services/attendance.js +68 -4
- package/dist/services/attendance.js.map +1 -1
- package/dist/services/labChat.d.ts +8 -1
- package/dist/services/labChat.d.ts.map +1 -1
- package/dist/services/labChat.js +101 -42
- package/dist/services/labChat.js.map +1 -1
- package/dist/services/message.d.ts +3 -0
- package/dist/services/message.d.ts.map +1 -1
- package/dist/services/message.js +8 -2
- package/dist/services/message.js.map +1 -1
- package/dist/services/newtonChat.d.ts +1 -0
- package/dist/services/newtonChat.d.ts.map +1 -1
- package/dist/services/newtonChat.js +40 -17
- package/dist/services/newtonChat.js.map +1 -1
- package/dist/services/worksheet.d.ts +15 -6
- package/dist/services/worksheet.d.ts.map +1 -1
- package/dist/services/worksheet.js +58 -12
- package/dist/services/worksheet.js.map +1 -1
- package/dist/utils/inference.d.ts +50 -1
- package/dist/utils/inference.d.ts.map +1 -1
- package/dist/utils/inference.js +167 -2
- package/dist/utils/inference.js.map +1 -1
- package/dist/workers/index.js +13 -3
- package/dist/workers/index.js.map +1 -1
- package/dist/workers/processors/aiLabChat.d.ts +7 -0
- package/dist/workers/processors/aiLabChat.d.ts.map +1 -0
- package/dist/workers/processors/aiLabChat.js +52 -0
- package/dist/workers/processors/aiLabChat.js.map +1 -0
- package/dist/workers/processors/aiNewtonChat.d.ts +7 -0
- package/dist/workers/processors/aiNewtonChat.d.ts.map +1 -0
- package/dist/workers/processors/aiNewtonChat.js +57 -0
- package/dist/workers/processors/aiNewtonChat.js.map +1 -0
- package/dist/workers/processors/createRunJobWorker.d.ts +46 -0
- package/dist/workers/processors/createRunJobWorker.d.ts.map +1 -0
- package/dist/workers/processors/createRunJobWorker.js +118 -0
- package/dist/workers/processors/createRunJobWorker.js.map +1 -0
- package/dist/workers/processors/gradeWorksheet.d.ts +6 -0
- package/dist/workers/processors/gradeWorksheet.d.ts.map +1 -0
- package/dist/workers/processors/gradeWorksheet.js +19 -0
- package/dist/workers/processors/gradeWorksheet.js.map +1 -0
- package/dist/workers/processors/pdfToWorksheet.d.ts +5 -6
- package/dist/workers/processors/pdfToWorksheet.d.ts.map +1 -1
- package/dist/workers/processors/pdfToWorksheet.js +15 -95
- package/dist/workers/processors/pdfToWorksheet.js.map +1 -1
- package/dist/workers/processors/studentProgressChat.d.ts +8 -0
- package/dist/workers/processors/studentProgressChat.d.ts.map +1 -0
- package/dist/workers/processors/studentProgressChat.js +27 -0
- package/dist/workers/processors/studentProgressChat.js.map +1 -0
- package/dist/workers/queues.d.ts +20 -4
- package/dist/workers/queues.d.ts.map +1 -1
- package/dist/workers/queues.js +3 -3
- package/dist/workers/queues.js.map +1 -1
- package/package.json +3 -3
- package/src/index.ts +12 -1
- package/src/lib/config/cors.ts +1 -0
- package/src/lib/pusher.ts +7 -1
- package/src/models/attendance.ts +15 -0
- package/src/pipelines/aiLabChat.ts +70 -78
- package/src/pipelines/aiNewtonChat.ts +47 -31
- package/src/pipelines/pdfToWorksheet.ts +224 -32
- package/src/routers/assignment.ts +74 -3
- package/src/routers/worksheet.ts +25 -4
- package/src/services/announcement.ts +2 -2
- package/src/services/assignment.ts +18 -4
- package/src/services/attendance.ts +87 -2
- package/src/services/labChat.ts +107 -47
- package/src/services/message.ts +6 -0
- package/src/services/newtonChat.ts +46 -25
- package/src/services/worksheet.ts +71 -10
- package/src/utils/inference.ts +209 -1
- package/src/workers/index.ts +11 -1
- package/src/workers/processors/aiLabChat.ts +65 -0
- package/src/workers/processors/aiNewtonChat.ts +75 -0
- package/src/workers/processors/createRunJobWorker.ts +164 -0
- package/src/workers/processors/gradeWorksheet.ts +16 -0
- package/src/workers/processors/pdfToWorksheet.ts +12 -114
- package/src/workers/processors/studentProgressChat.ts +28 -0
- package/src/workers/queues.ts +20 -5
- package/tests/integration/routers/attendance.test.ts +60 -1
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { chatAboutStudentProgress } from '../../services/studentProgress.js';
|
|
2
|
+
import { createRunJobWorker } from './createRunJobWorker.js';
|
|
3
|
+
|
|
4
|
+
export const studentProgressChatWorker = createRunJobWorker({
|
|
5
|
+
type: 'STUDENT_PROGRESS_CHAT',
|
|
6
|
+
workerOptions: {
|
|
7
|
+
concurrency: 4,
|
|
8
|
+
limiter: { max: 20, duration: 60_000 },
|
|
9
|
+
},
|
|
10
|
+
run: async ({ classId, studentId, message }, ctx) => {
|
|
11
|
+
// `chatAboutStudentProgress` runs an authorization check using the viewer
|
|
12
|
+
// id, so callers MUST pass `userId` via `enqueueRunJob` options for the
|
|
13
|
+
// service to receive it here.
|
|
14
|
+
if (!ctx.userId) {
|
|
15
|
+
throw new Error(
|
|
16
|
+
'STUDENT_PROGRESS_CHAT requires `userId` on the RunJob (set via enqueueRunJob options)',
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const response = await chatAboutStudentProgress(ctx.userId, {
|
|
21
|
+
classId,
|
|
22
|
+
studentId,
|
|
23
|
+
message,
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
return response;
|
|
27
|
+
},
|
|
28
|
+
});
|
package/src/workers/queues.ts
CHANGED
|
@@ -26,15 +26,30 @@ const DEFAULT_JOB_OPTIONS: JobsOptions = {
|
|
|
26
26
|
* The queue name string must match what the corresponding processor passes
|
|
27
27
|
* to `new Worker(<name>, ...)`.
|
|
28
28
|
*/
|
|
29
|
-
type JobInputs = {
|
|
30
|
-
|
|
29
|
+
export type JobInputs = {
|
|
30
|
+
/**
|
|
31
|
+
* `worksheetId` is the placeholder Worksheet row created synchronously by
|
|
32
|
+
* the producer (so the client has an id to navigate to). The pipeline fills
|
|
33
|
+
* that row in asynchronously and broadcasts progress on the per-worksheet
|
|
34
|
+
* job channel.
|
|
35
|
+
*/
|
|
36
|
+
PDF_TO_WORKSHEET: { gcsUrl: string; classId: string; worksheetId: string };
|
|
31
37
|
GRADE_WORKSHEET: { worksheetResponseId: string };
|
|
32
|
-
|
|
33
|
-
|
|
38
|
+
/**
|
|
39
|
+
* `aiMessageId` is the placeholder AI Message row created synchronously by
|
|
40
|
+
* the producer before enqueue (so the client renders a PENDING bubble in
|
|
41
|
+
* the timeline). The pipeline fills in the content and flips the row to
|
|
42
|
+
* COMPLETED / FAILED. Used for both intros and replies — single shape.
|
|
43
|
+
*/
|
|
44
|
+
AI_LAB_CHAT: { conversationId: string; aiMessageId: string };
|
|
45
|
+
/**
|
|
46
|
+
* `aiMessageId` placeholder pattern, same as AI_LAB_CHAT — see above.
|
|
47
|
+
*/
|
|
48
|
+
AI_NEWTON_CHAT: { conversationId: string; aiMessageId: string };
|
|
34
49
|
STUDENT_PROGRESS_CHAT: { classId: string; studentId: string; message: string };
|
|
35
50
|
};
|
|
36
51
|
|
|
37
|
-
const QUEUE_NAMES: Record<RunJobType, string> = {
|
|
52
|
+
export const QUEUE_NAMES: Record<RunJobType, string> = {
|
|
38
53
|
PDF_TO_WORKSHEET: 'pdfToWorksheet',
|
|
39
54
|
GRADE_WORKSHEET: 'gradeWorksheet',
|
|
40
55
|
AI_LAB_CHAT: 'aiLabChat',
|
|
@@ -117,6 +117,66 @@ describe('Attendance Router', () => {
|
|
|
117
117
|
expect(updatedRecord?.late.some((l: any) => l.id === student2.id)).toBe(true);
|
|
118
118
|
});
|
|
119
119
|
|
|
120
|
+
test('should notify students newly marked late or absent', async () => {
|
|
121
|
+
await prisma.notification.deleteMany({
|
|
122
|
+
where: { receiverId: student2.id },
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
await user1Caller.attendance.update({
|
|
126
|
+
classId: testClass.id,
|
|
127
|
+
eventId: testEvent.event.id,
|
|
128
|
+
attendance: {
|
|
129
|
+
present: [{ id: student1.id, username: student1.username }],
|
|
130
|
+
late: [{ id: student2.id, username: student2.username }],
|
|
131
|
+
absent: [],
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
let notifications = await user2Caller.notification.list();
|
|
136
|
+
expect(
|
|
137
|
+
notifications.some(
|
|
138
|
+
(notification: any) =>
|
|
139
|
+
notification.title === `Marked late in ${testClass.name}` &&
|
|
140
|
+
notification.content.includes(testEvent.event.name) &&
|
|
141
|
+
notification.content.includes(`/class/${testClass.id}/attendance/${testEvent.event.id}`)
|
|
142
|
+
)
|
|
143
|
+
).toBe(true);
|
|
144
|
+
|
|
145
|
+
await user1Caller.attendance.update({
|
|
146
|
+
classId: testClass.id,
|
|
147
|
+
eventId: testEvent.event.id,
|
|
148
|
+
attendance: {
|
|
149
|
+
present: [{ id: student1.id, username: student1.username }],
|
|
150
|
+
late: [{ id: student2.id, username: student2.username }],
|
|
151
|
+
absent: [],
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
notifications = await user2Caller.notification.list();
|
|
156
|
+
expect(
|
|
157
|
+
notifications.filter(
|
|
158
|
+
(notification: any) => notification.title === `Marked late in ${testClass.name}`
|
|
159
|
+
)
|
|
160
|
+
).toHaveLength(1);
|
|
161
|
+
|
|
162
|
+
await user1Caller.attendance.update({
|
|
163
|
+
classId: testClass.id,
|
|
164
|
+
eventId: testEvent.event.id,
|
|
165
|
+
attendance: {
|
|
166
|
+
present: [{ id: student1.id, username: student1.username }],
|
|
167
|
+
late: [],
|
|
168
|
+
absent: [{ id: student2.id, username: student2.username }],
|
|
169
|
+
},
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
notifications = await user2Caller.notification.list();
|
|
173
|
+
expect(
|
|
174
|
+
notifications.some(
|
|
175
|
+
(notification: any) => notification.title === `Marked absent in ${testClass.name}`
|
|
176
|
+
)
|
|
177
|
+
).toBe(true);
|
|
178
|
+
});
|
|
179
|
+
|
|
120
180
|
test('should update attendance without event', async () => {
|
|
121
181
|
const result = await user1Caller.attendance.update({
|
|
122
182
|
classId: testClass.id,
|
|
@@ -157,4 +217,3 @@ describe('Attendance Router', () => {
|
|
|
157
217
|
})));
|
|
158
218
|
});
|
|
159
219
|
});
|
|
160
|
-
|