@goscribe/server 1.1.2 → 1.1.4
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/lib/ai-session.d.ts +13 -3
- package/dist/lib/ai-session.js +66 -146
- package/dist/lib/pusher.js +1 -1
- package/dist/routers/_app.d.ts +114 -7
- package/dist/routers/chat.js +2 -23
- package/dist/routers/flashcards.d.ts +25 -1
- package/dist/routers/flashcards.js +0 -14
- package/dist/routers/members.d.ts +18 -0
- package/dist/routers/members.js +14 -1
- package/dist/routers/worksheets.js +5 -4
- package/dist/routers/workspace.d.ts +89 -6
- package/dist/routers/workspace.js +389 -259
- package/dist/services/flashcard-progress.service.d.ts +25 -1
- package/dist/services/flashcard-progress.service.js +70 -31
- package/package.json +3 -2
- package/prisma/schema.prisma +196 -184
- package/src/lib/ai-session.ts +3 -21
- package/src/routers/auth.ts +50 -2
- package/src/routers/flashcards.ts +0 -16
- package/src/routers/members.ts +27 -6
- package/src/routers/workspace.ts +468 -439
- package/src/server.ts +13 -0
- package/ANALYSIS_PROGRESS_SPEC.md +0 -463
- package/PROGRESS_QUICK_REFERENCE.md +0 -239
- package/dist/lib/podcast-prompts.d.ts +0 -43
- package/dist/lib/podcast-prompts.js +0 -135
- package/dist/routers/ai-session.d.ts +0 -0
- package/dist/routers/ai-session.js +0 -1
- package/dist/services/flashcard.service.d.ts +0 -183
- package/dist/services/flashcard.service.js +0 -224
- package/dist/services/podcast-segment-reorder.d.ts +0 -0
- package/dist/services/podcast-segment-reorder.js +0 -107
- package/dist/services/podcast.service.d.ts +0 -0
- package/dist/services/podcast.service.js +0 -326
- package/dist/services/worksheet.service.d.ts +0 -0
- package/dist/services/worksheet.service.js +0 -295
|
@@ -94,7 +94,7 @@ export declare class FlashcardProgressService {
|
|
|
94
94
|
/**
|
|
95
95
|
* Get flashcards due for review, non-studied flashcards, and flashcards with low mastery
|
|
96
96
|
*/
|
|
97
|
-
getDueFlashcards(userId: string, workspaceId: string): Promise<({
|
|
97
|
+
getDueFlashcards(userId: string, workspaceId: string): Promise<(({
|
|
98
98
|
artifact: {
|
|
99
99
|
id: string;
|
|
100
100
|
createdAt: Date;
|
|
@@ -119,6 +119,30 @@ export declare class FlashcardProgressService {
|
|
|
119
119
|
front: string;
|
|
120
120
|
back: string;
|
|
121
121
|
tags: string[];
|
|
122
|
+
}) | {
|
|
123
|
+
artifact: {
|
|
124
|
+
id: string;
|
|
125
|
+
createdAt: Date;
|
|
126
|
+
updatedAt: Date;
|
|
127
|
+
title: string;
|
|
128
|
+
description: string | null;
|
|
129
|
+
workspaceId: string;
|
|
130
|
+
type: import("@prisma/client").$Enums.ArtifactType;
|
|
131
|
+
isArchived: boolean;
|
|
132
|
+
generating: boolean;
|
|
133
|
+
generatingMetadata: import("@prisma/client/runtime/library").JsonValue | null;
|
|
134
|
+
difficulty: import("@prisma/client").$Enums.Difficulty | null;
|
|
135
|
+
estimatedTime: string | null;
|
|
136
|
+
imageObjectKey: string | null;
|
|
137
|
+
createdById: string | null;
|
|
138
|
+
};
|
|
139
|
+
id: string;
|
|
140
|
+
createdAt: Date;
|
|
141
|
+
artifactId: string;
|
|
142
|
+
order: number;
|
|
143
|
+
front: string;
|
|
144
|
+
back: string;
|
|
145
|
+
tags: string[];
|
|
122
146
|
})[]>;
|
|
123
147
|
/**
|
|
124
148
|
* Get user statistics for a flashcard set
|
|
@@ -226,12 +226,23 @@ export class FlashcardProgressService {
|
|
|
226
226
|
async getDueFlashcards(userId, workspaceId) {
|
|
227
227
|
const now = new Date();
|
|
228
228
|
const LOW_MASTERY_THRESHOLD = 50; // Consider mastery < 50 as low
|
|
229
|
-
// Get
|
|
229
|
+
// Get the latest artifact in the workspace
|
|
230
|
+
const latestArtifact = await this.db.artifact.findFirst({
|
|
231
|
+
where: {
|
|
232
|
+
workspaceId,
|
|
233
|
+
type: 'FLASHCARD_SET',
|
|
234
|
+
},
|
|
235
|
+
orderBy: {
|
|
236
|
+
updatedAt: 'desc',
|
|
237
|
+
},
|
|
238
|
+
});
|
|
239
|
+
if (!latestArtifact) {
|
|
240
|
+
return [];
|
|
241
|
+
}
|
|
242
|
+
// Get all flashcards from the latest artifact
|
|
230
243
|
const allFlashcards = await this.db.flashcard.findMany({
|
|
231
244
|
where: {
|
|
232
|
-
|
|
233
|
-
workspaceId,
|
|
234
|
-
},
|
|
245
|
+
artifactId: latestArtifact.id,
|
|
235
246
|
},
|
|
236
247
|
include: {
|
|
237
248
|
artifact: true,
|
|
@@ -242,6 +253,7 @@ export class FlashcardProgressService {
|
|
|
242
253
|
},
|
|
243
254
|
},
|
|
244
255
|
});
|
|
256
|
+
console.log('allFlashcards', allFlashcards.length);
|
|
245
257
|
const TAKE_NUMBER = (allFlashcards.length > 10) ? 10 : allFlashcards.length;
|
|
246
258
|
// Get progress records for flashcards that are due or have low mastery
|
|
247
259
|
const progressRecords = await this.db.flashcardProgress.findMany({
|
|
@@ -265,9 +277,7 @@ export class FlashcardProgressService {
|
|
|
265
277
|
}
|
|
266
278
|
],
|
|
267
279
|
flashcard: {
|
|
268
|
-
|
|
269
|
-
workspaceId,
|
|
270
|
-
},
|
|
280
|
+
artifactId: latestArtifact.id,
|
|
271
281
|
},
|
|
272
282
|
},
|
|
273
283
|
include: {
|
|
@@ -279,6 +289,38 @@ export class FlashcardProgressService {
|
|
|
279
289
|
},
|
|
280
290
|
take: TAKE_NUMBER,
|
|
281
291
|
});
|
|
292
|
+
console.log('TAKE_NUMBER', TAKE_NUMBER);
|
|
293
|
+
console.log('TAKE_NUMBER - progressRecords.length', TAKE_NUMBER - progressRecords.length);
|
|
294
|
+
console.log('progressRecords', progressRecords.map((progress) => progress.flashcard.id));
|
|
295
|
+
// Get flashcard IDs that already have progress records
|
|
296
|
+
const flashcardIdsWithProgress = new Set(progressRecords.map((progress) => progress.flashcard.id));
|
|
297
|
+
// Find flashcards without progress records (non-studied) to pad the results
|
|
298
|
+
const nonStudiedFlashcards = allFlashcards
|
|
299
|
+
.filter((flashcard) => !flashcardIdsWithProgress.has(flashcard.id))
|
|
300
|
+
.slice(0, TAKE_NUMBER - progressRecords.length);
|
|
301
|
+
// Create progress-like structures for non-studied flashcards
|
|
302
|
+
const progressRecordsPadding = nonStudiedFlashcards.map((flashcard) => {
|
|
303
|
+
const { progress, ...flashcardWithoutProgress } = flashcard;
|
|
304
|
+
return {
|
|
305
|
+
id: `temp-${flashcard.id}`,
|
|
306
|
+
userId,
|
|
307
|
+
flashcardId: flashcard.id,
|
|
308
|
+
timesStudied: 0,
|
|
309
|
+
timesCorrect: 0,
|
|
310
|
+
timesIncorrect: 0,
|
|
311
|
+
timesIncorrectConsecutive: 0,
|
|
312
|
+
easeFactor: 2.5,
|
|
313
|
+
interval: 0,
|
|
314
|
+
repetitions: 0,
|
|
315
|
+
masteryLevel: 0,
|
|
316
|
+
lastStudiedAt: null,
|
|
317
|
+
nextReviewAt: null,
|
|
318
|
+
flashcard: flashcardWithoutProgress,
|
|
319
|
+
};
|
|
320
|
+
});
|
|
321
|
+
console.log('progressRecordsPadding', progressRecordsPadding.length);
|
|
322
|
+
console.log('progressRecords', progressRecords.length);
|
|
323
|
+
const selectedCards = [...progressRecords, ...progressRecordsPadding];
|
|
282
324
|
// Build result array: include progress records and non-studied flashcards
|
|
283
325
|
const results = [];
|
|
284
326
|
// Add flashcards with progress (due or low mastery)
|
|
@@ -286,30 +328,27 @@ export class FlashcardProgressService {
|
|
|
286
328
|
results.push(progress);
|
|
287
329
|
}
|
|
288
330
|
// Sort by priority: due first (by nextReviewAt), then low mastery, then non-studied
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
return 0;
|
|
311
|
-
});
|
|
312
|
-
return results.map((progress) => progress.flashcard);
|
|
331
|
+
// @todo: make an actual algorithm. research
|
|
332
|
+
// results.sort((a, b) => {
|
|
333
|
+
// // Due flashcards first (nextReviewAt <= now)
|
|
334
|
+
// const aIsDue = a.nextReviewAt && a.nextReviewAt <= now;
|
|
335
|
+
// const bIsDue = b.nextReviewAt && b.nextReviewAt <= now;
|
|
336
|
+
// // if (aIsDue && !bIsDue) return -1;
|
|
337
|
+
// // if (!aIsDue && bIsDue) return 1;
|
|
338
|
+
// // Among due flashcards, sort by nextReviewAt
|
|
339
|
+
// if (aIsDue && bIsDue && a.nextReviewAt && b.nextReviewAt) {
|
|
340
|
+
// return a.nextReviewAt.getTime() - b.nextReviewAt.getTime();
|
|
341
|
+
// }
|
|
342
|
+
// // Then low mastery (lower mastery first)
|
|
343
|
+
// if (a.masteryLevel !== b.masteryLevel) {
|
|
344
|
+
// return a.masteryLevel - b.masteryLevel;
|
|
345
|
+
// }
|
|
346
|
+
// // Finally, non-studied (timesStudied === 0)
|
|
347
|
+
// if (a.timesStudied === 0 && b.timesStudied !== 0) return -1;
|
|
348
|
+
// if (a.timesStudied !== 0 && b.timesStudied === 0) return 1;
|
|
349
|
+
// return 0;
|
|
350
|
+
// });
|
|
351
|
+
return selectedCards.map((progress) => progress.flashcard);
|
|
313
352
|
}
|
|
314
353
|
/**
|
|
315
354
|
* Get user statistics for a flashcard set
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@goscribe/server",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.4",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"@auth/express": "^0.11.0",
|
|
24
24
|
"@auth/prisma-adapter": "^2.10.0",
|
|
25
|
-
"@goscribe/server": "^1.
|
|
25
|
+
"@goscribe/server": "^1.1.2",
|
|
26
26
|
"@prisma/client": "^6.14.0",
|
|
27
27
|
"@supabase/supabase-js": "^2.76.1",
|
|
28
28
|
"@trpc/server": "^11.5.0",
|
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
"pusher-js": "^8.4.0",
|
|
43
43
|
"socket.io": "^4.8.1",
|
|
44
44
|
"superjson": "^2.2.2",
|
|
45
|
+
"uuid": "^13.0.0",
|
|
45
46
|
"zod": "^4.1.1"
|
|
46
47
|
},
|
|
47
48
|
"devDependencies": {
|