@goscribe/server 1.0.8 → 1.0.10

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.
Files changed (58) hide show
  1. package/AUTH_FRONTEND_SPEC.md +21 -0
  2. package/CHAT_FRONTEND_SPEC.md +474 -0
  3. package/DATABASE_SETUP.md +165 -0
  4. package/MEETINGSUMMARY_FRONTEND_SPEC.md +28 -0
  5. package/PODCAST_FRONTEND_SPEC.md +595 -0
  6. package/STUDYGUIDE_FRONTEND_SPEC.md +18 -0
  7. package/WORKSHEETS_FRONTEND_SPEC.md +26 -0
  8. package/WORKSPACE_FRONTEND_SPEC.md +47 -0
  9. package/dist/lib/ai-session.d.ts +26 -0
  10. package/dist/lib/ai-session.js +343 -0
  11. package/dist/lib/inference.d.ts +2 -0
  12. package/dist/lib/inference.js +21 -0
  13. package/dist/lib/pusher.d.ts +14 -0
  14. package/dist/lib/pusher.js +94 -0
  15. package/dist/lib/storage.d.ts +10 -2
  16. package/dist/lib/storage.js +63 -6
  17. package/dist/routers/_app.d.ts +840 -58
  18. package/dist/routers/_app.js +6 -0
  19. package/dist/routers/ai-session.d.ts +0 -0
  20. package/dist/routers/ai-session.js +1 -0
  21. package/dist/routers/auth.d.ts +1 -0
  22. package/dist/routers/auth.js +6 -4
  23. package/dist/routers/chat.d.ts +171 -0
  24. package/dist/routers/chat.js +270 -0
  25. package/dist/routers/flashcards.d.ts +37 -0
  26. package/dist/routers/flashcards.js +128 -0
  27. package/dist/routers/meetingsummary.d.ts +0 -0
  28. package/dist/routers/meetingsummary.js +377 -0
  29. package/dist/routers/podcast.d.ts +277 -0
  30. package/dist/routers/podcast.js +847 -0
  31. package/dist/routers/studyguide.d.ts +54 -0
  32. package/dist/routers/studyguide.js +125 -0
  33. package/dist/routers/worksheets.d.ts +138 -51
  34. package/dist/routers/worksheets.js +317 -7
  35. package/dist/routers/workspace.d.ts +162 -7
  36. package/dist/routers/workspace.js +440 -8
  37. package/dist/server.js +6 -2
  38. package/package.json +11 -4
  39. package/prisma/migrations/20250826124819_add_worksheet_difficulty_and_estimated_time/migration.sql +213 -0
  40. package/prisma/migrations/20250826133236_add_worksheet_question_progress/migration.sql +31 -0
  41. package/prisma/migrations/migration_lock.toml +3 -0
  42. package/prisma/schema.prisma +87 -6
  43. package/prisma/seed.mjs +135 -0
  44. package/src/lib/ai-session.ts +412 -0
  45. package/src/lib/inference.ts +21 -0
  46. package/src/lib/pusher.ts +104 -0
  47. package/src/lib/storage.ts +89 -6
  48. package/src/routers/_app.ts +6 -0
  49. package/src/routers/auth.ts +8 -4
  50. package/src/routers/chat.ts +275 -0
  51. package/src/routers/flashcards.ts +142 -0
  52. package/src/routers/meetingsummary.ts +416 -0
  53. package/src/routers/podcast.ts +934 -0
  54. package/src/routers/studyguide.ts +144 -0
  55. package/src/routers/worksheets.ts +336 -7
  56. package/src/routers/workspace.ts +487 -8
  57. package/src/server.ts +7 -2
  58. package/test-ai-integration.js +134 -0
@@ -1,6 +1,8 @@
1
1
  import { z } from 'zod';
2
2
  import { TRPCError } from '@trpc/server';
3
3
  import { router, authedProcedure } from '../trpc.js';
4
+ import { aiSessionService } from '../lib/ai-session.js';
5
+ import PusherService from '../lib/pusher.js';
4
6
  // Avoid importing Prisma enums directly; mirror values as string literals
5
7
  const ArtifactType = {
6
8
  WORKSHEET: 'WORKSHEET',
@@ -10,6 +12,14 @@ const Difficulty = {
10
12
  MEDIUM: 'MEDIUM',
11
13
  HARD: 'HARD',
12
14
  };
15
+ const QuestionType = {
16
+ MULTIPLE_CHOICE: 'MULTIPLE_CHOICE',
17
+ TEXT: 'TEXT',
18
+ NUMERIC: 'NUMERIC',
19
+ TRUE_FALSE: 'TRUE_FALSE',
20
+ MATCHING: 'MATCHING',
21
+ FILL_IN_THE_BLANK: 'FILL_IN_THE_BLANK',
22
+ };
13
23
  export const worksheets = router({
14
24
  // List all worksheet artifacts for a workspace
15
25
  list: authedProcedure
@@ -28,23 +38,76 @@ export const worksheets = router({
28
38
  });
29
39
  if (!worksheets)
30
40
  throw new TRPCError({ code: 'NOT_FOUND' });
31
- return worksheets;
41
+ // Merge per-user progress into question.meta for compatibility with UI
42
+ const allQuestionIds = worksheets.flatMap(w => w.questions.map(q => q.id));
43
+ if (allQuestionIds.length === 0)
44
+ return worksheets;
45
+ const progress = await ctx.db.worksheetQuestionProgress.findMany({
46
+ where: { userId: ctx.session.user.id, worksheetQuestionId: { in: allQuestionIds } },
47
+ });
48
+ const progressByQuestionId = new Map(progress.map(p => [p.worksheetQuestionId, p]));
49
+ const merged = worksheets.map(w => ({
50
+ ...w,
51
+ questions: w.questions.map(q => {
52
+ const p = progressByQuestionId.get(q.id);
53
+ if (!p)
54
+ return q;
55
+ const existingMeta = q.meta ? (typeof q.meta === 'object' ? q.meta : JSON.parse(q.meta)) : {};
56
+ return {
57
+ ...q,
58
+ meta: {
59
+ ...existingMeta,
60
+ completed: p.completed,
61
+ userAnswer: p.userAnswer,
62
+ completedAt: p.completedAt,
63
+ },
64
+ };
65
+ }),
66
+ }));
67
+ return merged;
32
68
  }),
33
69
  // Create a worksheet set
34
- createWorksheet: authedProcedure
35
- .input(z.object({ workspaceId: z.string(), title: z.string().min(1).max(120) }))
70
+ create: authedProcedure
71
+ .input(z.object({
72
+ workspaceId: z.string(),
73
+ title: z.string().min(1).max(120),
74
+ description: z.string().optional(),
75
+ difficulty: z.enum(['EASY', 'MEDIUM', 'HARD']).optional(),
76
+ estimatedTime: z.string().optional(),
77
+ problems: z.array(z.object({
78
+ question: z.string().min(1),
79
+ answer: z.string().min(1),
80
+ type: z.enum(['MULTIPLE_CHOICE', 'TEXT', 'NUMERIC', 'TRUE_FALSE', 'MATCHING', 'FILL_IN_THE_BLANK']).default('TEXT'),
81
+ options: z.array(z.string()).optional(),
82
+ })).optional(),
83
+ }))
36
84
  .mutation(async ({ ctx, input }) => {
37
85
  const workspace = await ctx.db.workspace.findFirst({
38
86
  where: { id: input.workspaceId, ownerId: ctx.session.user.id },
39
87
  });
40
88
  if (!workspace)
41
89
  throw new TRPCError({ code: 'NOT_FOUND' });
90
+ const { problems, ...worksheetData } = input;
42
91
  return ctx.db.artifact.create({
43
92
  data: {
44
93
  workspaceId: input.workspaceId,
45
94
  type: ArtifactType.WORKSHEET,
46
95
  title: input.title,
96
+ difficulty: input.difficulty,
97
+ estimatedTime: input.estimatedTime,
47
98
  createdById: ctx.session.user.id,
99
+ questions: problems ? {
100
+ create: problems.map((problem, index) => ({
101
+ prompt: problem.question,
102
+ answer: problem.answer,
103
+ type: problem.type,
104
+ order: index,
105
+ meta: problem.options ? { options: problem.options } : undefined,
106
+ })),
107
+ } : undefined,
108
+ },
109
+ include: {
110
+ questions: true,
48
111
  },
49
112
  });
50
113
  }),
@@ -59,10 +122,37 @@ export const worksheets = router({
59
122
  workspace: { ownerId: ctx.session.user.id },
60
123
  },
61
124
  include: { questions: true },
125
+ orderBy: { updatedAt: 'desc' },
62
126
  });
63
127
  if (!worksheet)
64
128
  throw new TRPCError({ code: 'NOT_FOUND' });
65
- return worksheet;
129
+ // Merge per-user progress into question.meta for compatibility with UI
130
+ const questionIds = worksheet.questions.map(q => q.id);
131
+ if (questionIds.length === 0)
132
+ return worksheet;
133
+ const progress = await ctx.db.worksheetQuestionProgress.findMany({
134
+ where: { userId: ctx.session.user.id, worksheetQuestionId: { in: questionIds } },
135
+ });
136
+ const progressByQuestionId = new Map(progress.map(p => [p.worksheetQuestionId, p]));
137
+ const merged = {
138
+ ...worksheet,
139
+ questions: worksheet.questions.map(q => {
140
+ const p = progressByQuestionId.get(q.id);
141
+ if (!p)
142
+ return q;
143
+ const existingMeta = q.meta ? (typeof q.meta === 'object' ? q.meta : JSON.parse(q.meta)) : {};
144
+ return {
145
+ ...q,
146
+ meta: {
147
+ ...existingMeta,
148
+ completed: p.completed,
149
+ userAnswer: p.userAnswer,
150
+ completedAt: p.completedAt,
151
+ },
152
+ };
153
+ }),
154
+ };
155
+ return merged;
66
156
  }),
67
157
  // Add a question to a worksheet
68
158
  createWorksheetQuestion: authedProcedure
@@ -70,6 +160,7 @@ export const worksheets = router({
70
160
  worksheetId: z.string(),
71
161
  prompt: z.string().min(1),
72
162
  answer: z.string().optional(),
163
+ type: z.enum(['MULTIPLE_CHOICE', 'TEXT', 'NUMERIC', 'TRUE_FALSE', 'MATCHING', 'FILL_IN_THE_BLANK']).optional(),
73
164
  difficulty: z.enum(['EASY', 'MEDIUM', 'HARD']).optional(),
74
165
  order: z.number().int().optional(),
75
166
  meta: z.record(z.string(), z.unknown()).optional(),
@@ -85,6 +176,7 @@ export const worksheets = router({
85
176
  artifactId: input.worksheetId,
86
177
  prompt: input.prompt,
87
178
  answer: input.answer,
179
+ type: (input.type ?? QuestionType.TEXT),
88
180
  difficulty: (input.difficulty ?? Difficulty.MEDIUM),
89
181
  order: input.order ?? 0,
90
182
  meta: input.meta,
@@ -97,6 +189,7 @@ export const worksheets = router({
97
189
  worksheetQuestionId: z.string(),
98
190
  prompt: z.string().optional(),
99
191
  answer: z.string().optional(),
192
+ type: z.enum(['MULTIPLE_CHOICE', 'TEXT', 'NUMERIC', 'TRUE_FALSE', 'MATCHING', 'FILL_IN_THE_BLANK']).optional(),
100
193
  difficulty: z.enum(['EASY', 'MEDIUM', 'HARD']).optional(),
101
194
  order: z.number().int().optional(),
102
195
  meta: z.record(z.string(), z.unknown()).optional(),
@@ -112,6 +205,7 @@ export const worksheets = router({
112
205
  data: {
113
206
  prompt: input.prompt ?? q.prompt,
114
207
  answer: input.answer ?? q.answer,
208
+ type: (input.type ?? q.type),
115
209
  difficulty: (input.difficulty ?? q.difficulty),
116
210
  order: input.order ?? q.order,
117
211
  meta: (input.meta ?? q.meta),
@@ -130,15 +224,231 @@ export const worksheets = router({
130
224
  await ctx.db.worksheetQuestion.delete({ where: { id: input.worksheetQuestionId } });
131
225
  return true;
132
226
  }),
133
- // Delete a worksheet set and its questions
134
- deleteWorksheet: authedProcedure
227
+ // Update problem completion status
228
+ updateProblemStatus: authedProcedure
229
+ .input(z.object({
230
+ problemId: z.string(),
231
+ completed: z.boolean(),
232
+ answer: z.string().optional(),
233
+ }))
234
+ .mutation(async ({ ctx, input }) => {
235
+ // Verify question ownership through worksheet
236
+ const question = await ctx.db.worksheetQuestion.findFirst({
237
+ where: {
238
+ id: input.problemId,
239
+ artifact: {
240
+ type: ArtifactType.WORKSHEET,
241
+ workspace: { ownerId: ctx.session.user.id },
242
+ },
243
+ },
244
+ });
245
+ if (!question)
246
+ throw new TRPCError({ code: 'NOT_FOUND' });
247
+ // Upsert per-user progress row
248
+ const progress = await ctx.db.worksheetQuestionProgress.upsert({
249
+ where: {
250
+ worksheetQuestionId_userId: {
251
+ worksheetQuestionId: input.problemId,
252
+ userId: ctx.session.user.id,
253
+ },
254
+ },
255
+ create: {
256
+ worksheetQuestionId: input.problemId,
257
+ userId: ctx.session.user.id,
258
+ completed: input.completed,
259
+ userAnswer: input.answer,
260
+ completedAt: input.completed ? new Date() : null,
261
+ attempts: 1,
262
+ },
263
+ update: {
264
+ completed: input.completed,
265
+ userAnswer: input.answer,
266
+ completedAt: input.completed ? new Date() : null,
267
+ attempts: { increment: 1 },
268
+ },
269
+ });
270
+ return progress;
271
+ }),
272
+ // Get current user's progress for all questions in a worksheet
273
+ getProgress: authedProcedure
135
274
  .input(z.object({ worksheetId: z.string() }))
275
+ .query(async ({ ctx, input }) => {
276
+ // Verify worksheet ownership
277
+ const worksheet = await ctx.db.artifact.findFirst({
278
+ where: {
279
+ id: input.worksheetId,
280
+ type: ArtifactType.WORKSHEET,
281
+ workspace: { ownerId: ctx.session.user.id },
282
+ },
283
+ });
284
+ if (!worksheet)
285
+ throw new TRPCError({ code: 'NOT_FOUND' });
286
+ const questions = await ctx.db.worksheetQuestion.findMany({
287
+ where: { artifactId: input.worksheetId },
288
+ select: { id: true },
289
+ });
290
+ const questionIds = questions.map(q => q.id);
291
+ const progress = await ctx.db.worksheetQuestionProgress.findMany({
292
+ where: {
293
+ userId: ctx.session.user.id,
294
+ worksheetQuestionId: { in: questionIds },
295
+ },
296
+ });
297
+ return progress;
298
+ }),
299
+ // Update a worksheet
300
+ update: authedProcedure
301
+ .input(z.object({
302
+ id: z.string(),
303
+ title: z.string().min(1).max(120).optional(),
304
+ description: z.string().optional(),
305
+ difficulty: z.enum(['EASY', 'MEDIUM', 'HARD']).optional(),
306
+ estimatedTime: z.string().optional(),
307
+ problems: z.array(z.object({
308
+ id: z.string().optional(),
309
+ question: z.string().min(1),
310
+ answer: z.string().min(1),
311
+ type: z.enum(['MULTIPLE_CHOICE', 'TEXT', 'NUMERIC', 'TRUE_FALSE', 'MATCHING', 'FILL_IN_THE_BLANK']).default('TEXT'),
312
+ options: z.array(z.string()).optional(),
313
+ })).optional(),
314
+ }))
315
+ .mutation(async ({ ctx, input }) => {
316
+ const { id, problems, ...updateData } = input;
317
+ // Verify worksheet ownership
318
+ const existingWorksheet = await ctx.db.artifact.findFirst({
319
+ where: {
320
+ id,
321
+ type: ArtifactType.WORKSHEET,
322
+ workspace: { ownerId: ctx.session.user.id },
323
+ },
324
+ });
325
+ if (!existingWorksheet)
326
+ throw new TRPCError({ code: 'NOT_FOUND' });
327
+ // Handle questions update if provided
328
+ if (problems) {
329
+ // Delete existing questions and create new ones
330
+ await ctx.db.worksheetQuestion.deleteMany({
331
+ where: { artifactId: id },
332
+ });
333
+ await ctx.db.worksheetQuestion.createMany({
334
+ data: problems.map((problem, index) => ({
335
+ artifactId: id,
336
+ prompt: problem.question,
337
+ answer: problem.answer,
338
+ type: problem.type,
339
+ order: index,
340
+ meta: problem.options ? { options: problem.options } : undefined,
341
+ })),
342
+ });
343
+ }
344
+ // Process update data
345
+ const processedUpdateData = {
346
+ ...updateData,
347
+ difficulty: updateData.difficulty,
348
+ };
349
+ return ctx.db.artifact.update({
350
+ where: { id },
351
+ data: processedUpdateData,
352
+ include: {
353
+ questions: {
354
+ orderBy: { order: 'asc' },
355
+ },
356
+ },
357
+ });
358
+ }),
359
+ // Delete a worksheet set and its questions
360
+ delete: authedProcedure
361
+ .input(z.object({ id: z.string() }))
136
362
  .mutation(async ({ ctx, input }) => {
137
363
  const deleted = await ctx.db.artifact.deleteMany({
138
- where: { id: input.worksheetId, type: ArtifactType.WORKSHEET, workspace: { ownerId: ctx.session.user.id } },
364
+ where: { id: input.id, type: ArtifactType.WORKSHEET, workspace: { ownerId: ctx.session.user.id } },
139
365
  });
140
366
  if (deleted.count === 0)
141
367
  throw new TRPCError({ code: 'NOT_FOUND' });
142
368
  return true;
143
369
  }),
370
+ // Generate a worksheet from a user prompt
371
+ generateFromPrompt: authedProcedure
372
+ .input(z.object({
373
+ workspaceId: z.string(),
374
+ prompt: z.string().min(1),
375
+ numQuestions: z.number().int().min(1).max(20).default(8),
376
+ difficulty: z.enum(['easy', 'medium', 'hard']).default('medium'),
377
+ title: z.string().optional(),
378
+ estimatedTime: z.string().optional(),
379
+ }))
380
+ .mutation(async ({ ctx, input }) => {
381
+ const workspace = await ctx.db.workspace.findFirst({ where: { id: input.workspaceId, ownerId: ctx.session.user.id } });
382
+ if (!workspace)
383
+ throw new TRPCError({ code: 'NOT_FOUND' });
384
+ await PusherService.emitTaskComplete(input.workspaceId, 'worksheet_load_start', { source: 'prompt' });
385
+ const session = await aiSessionService.initSession(input.workspaceId);
386
+ await aiSessionService.setInstruction(session.id, `Create a worksheet with ${input.numQuestions} questions at ${input.difficulty} difficulty from this prompt. Return JSON.\n\nPrompt:\n${input.prompt}`);
387
+ await aiSessionService.startLLMSession(session.id);
388
+ const content = await aiSessionService.generateWorksheetQuestions(session.id, input.numQuestions, input.difficulty);
389
+ await PusherService.emitTaskComplete(input.workspaceId, 'worksheet_info', { contentLength: content.length });
390
+ const artifact = await ctx.db.artifact.create({
391
+ data: {
392
+ workspaceId: input.workspaceId,
393
+ type: ArtifactType.WORKSHEET,
394
+ title: input.title || `Worksheet - ${new Date().toLocaleString()}`,
395
+ createdById: ctx.session.user.id,
396
+ difficulty: (input.difficulty.toUpperCase()),
397
+ estimatedTime: input.estimatedTime,
398
+ },
399
+ });
400
+ try {
401
+ const worksheetData = JSON.parse(content);
402
+ let actualWorksheetData = worksheetData;
403
+ if (worksheetData.last_response) {
404
+ try {
405
+ actualWorksheetData = JSON.parse(worksheetData.last_response);
406
+ }
407
+ catch { }
408
+ }
409
+ const problems = actualWorksheetData.problems || actualWorksheetData.questions || actualWorksheetData || [];
410
+ for (let i = 0; i < Math.min(problems.length, input.numQuestions); i++) {
411
+ const problem = problems[i];
412
+ const prompt = problem.question || problem.prompt || `Question ${i + 1}`;
413
+ const answer = problem.answer || problem.solution || `Answer ${i + 1}`;
414
+ const type = problem.type || 'TEXT';
415
+ const options = problem.options || [];
416
+ await ctx.db.worksheetQuestion.create({
417
+ data: {
418
+ artifactId: artifact.id,
419
+ prompt,
420
+ answer,
421
+ difficulty: (input.difficulty.toUpperCase()),
422
+ order: i,
423
+ meta: {
424
+ type,
425
+ options: options.length > 0 ? options : undefined,
426
+ },
427
+ },
428
+ });
429
+ }
430
+ }
431
+ catch {
432
+ const lines = content.split('\n').filter(line => line.trim());
433
+ for (let i = 0; i < Math.min(lines.length, input.numQuestions); i++) {
434
+ const line = lines[i];
435
+ if (line.includes(' - ')) {
436
+ const [q, a] = line.split(' - ');
437
+ await ctx.db.worksheetQuestion.create({
438
+ data: {
439
+ artifactId: artifact.id,
440
+ prompt: q.trim(),
441
+ answer: a.trim(),
442
+ difficulty: (input.difficulty.toUpperCase()),
443
+ order: i,
444
+ meta: { type: 'TEXT' },
445
+ },
446
+ });
447
+ }
448
+ }
449
+ }
450
+ await PusherService.emitWorksheetComplete(input.workspaceId, artifact);
451
+ aiSessionService.deleteSession(session.id);
452
+ return { artifact };
453
+ }),
144
454
  });
@@ -11,7 +11,37 @@ export declare const workspace: import("@trpc/server").TRPCBuiltRouter<{
11
11
  transformer: true;
12
12
  }, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
13
13
  list: import("@trpc/server").TRPCQueryProcedure<{
14
- input: void;
14
+ input: {
15
+ parentId?: string | undefined;
16
+ };
17
+ output: {
18
+ workspaces: {
19
+ id: string;
20
+ createdAt: Date;
21
+ updatedAt: Date;
22
+ ownerId: string;
23
+ title: string;
24
+ description: string | null;
25
+ folderId: string | null;
26
+ shareLink: string | null;
27
+ }[];
28
+ folders: {
29
+ name: string;
30
+ id: string;
31
+ createdAt: Date;
32
+ updatedAt: Date;
33
+ ownerId: string;
34
+ parentId: string | null;
35
+ }[];
36
+ };
37
+ meta: object;
38
+ }>;
39
+ create: import("@trpc/server").TRPCMutationProcedure<{
40
+ input: {
41
+ name: string;
42
+ description?: string | undefined;
43
+ parentId?: string | undefined;
44
+ };
15
45
  output: {
16
46
  id: string;
17
47
  createdAt: Date;
@@ -20,22 +50,22 @@ export declare const workspace: import("@trpc/server").TRPCBuiltRouter<{
20
50
  title: string;
21
51
  description: string | null;
22
52
  folderId: string | null;
23
- }[];
53
+ shareLink: string | null;
54
+ };
24
55
  meta: object;
25
56
  }>;
26
- create: import("@trpc/server").TRPCMutationProcedure<{
57
+ createFolder: import("@trpc/server").TRPCMutationProcedure<{
27
58
  input: {
28
59
  name: string;
29
- description?: string | undefined;
60
+ parentId?: string | undefined;
30
61
  };
31
62
  output: {
63
+ name: string;
32
64
  id: string;
33
65
  createdAt: Date;
34
66
  updatedAt: Date;
35
67
  ownerId: string;
36
- title: string;
37
- description: string | null;
38
- folderId: string | null;
68
+ parentId: string | null;
39
69
  };
40
70
  meta: object;
41
71
  }>;
@@ -44,6 +74,42 @@ export declare const workspace: import("@trpc/server").TRPCBuiltRouter<{
44
74
  id: string;
45
75
  };
46
76
  output: {
77
+ folder: {
78
+ name: string;
79
+ id: string;
80
+ createdAt: Date;
81
+ updatedAt: Date;
82
+ ownerId: string;
83
+ parentId: string | null;
84
+ } | null;
85
+ uploads: {
86
+ meta: import("@prisma/client/runtime/library").JsonValue | null;
87
+ name: string;
88
+ id: string;
89
+ createdAt: Date;
90
+ userId: string;
91
+ workspaceId: string;
92
+ mimeType: string;
93
+ size: number;
94
+ bucket: string | null;
95
+ objectKey: string | null;
96
+ url: string | null;
97
+ checksum: string | null;
98
+ }[];
99
+ artifacts: {
100
+ id: string;
101
+ createdAt: Date;
102
+ updatedAt: Date;
103
+ title: string;
104
+ description: string | null;
105
+ workspaceId: string;
106
+ type: import("@prisma/client").$Enums.ArtifactType;
107
+ isArchived: boolean;
108
+ difficulty: import("@prisma/client").$Enums.Difficulty | null;
109
+ estimatedTime: string | null;
110
+ createdById: string | null;
111
+ }[];
112
+ } & {
47
113
  id: string;
48
114
  createdAt: Date;
49
115
  updatedAt: Date;
@@ -51,6 +117,30 @@ export declare const workspace: import("@trpc/server").TRPCBuiltRouter<{
51
117
  title: string;
52
118
  description: string | null;
53
119
  folderId: string | null;
120
+ shareLink: string | null;
121
+ };
122
+ meta: object;
123
+ }>;
124
+ share: import("@trpc/server").TRPCQueryProcedure<{
125
+ input: {
126
+ id: string;
127
+ };
128
+ output: {
129
+ shareLink: string | null;
130
+ } | undefined;
131
+ meta: object;
132
+ }>;
133
+ join: import("@trpc/server").TRPCMutationProcedure<{
134
+ input: {
135
+ shareLink: string;
136
+ };
137
+ output: {
138
+ id: string;
139
+ title: string;
140
+ description: string | null;
141
+ ownerId: string;
142
+ createdAt: Date;
143
+ updatedAt: Date;
54
144
  };
55
145
  meta: object;
56
146
  }>;
@@ -68,6 +158,7 @@ export declare const workspace: import("@trpc/server").TRPCBuiltRouter<{
68
158
  title: string;
69
159
  description: string | null;
70
160
  folderId: string | null;
161
+ shareLink: string | null;
71
162
  };
72
163
  meta: object;
73
164
  }>;
@@ -78,6 +169,30 @@ export declare const workspace: import("@trpc/server").TRPCBuiltRouter<{
78
169
  output: boolean;
79
170
  meta: object;
80
171
  }>;
172
+ getFolderInformation: import("@trpc/server").TRPCQueryProcedure<{
173
+ input: {
174
+ id: string;
175
+ };
176
+ output: {
177
+ folder: {
178
+ name: string;
179
+ id: string;
180
+ createdAt: Date;
181
+ updatedAt: Date;
182
+ ownerId: string;
183
+ parentId: string | null;
184
+ };
185
+ parents: {
186
+ name: string;
187
+ id: string;
188
+ createdAt: Date;
189
+ updatedAt: Date;
190
+ ownerId: string;
191
+ parentId: string | null;
192
+ }[];
193
+ };
194
+ meta: object;
195
+ }>;
81
196
  uploadFiles: import("@trpc/server").TRPCMutationProcedure<{
82
197
  input: {
83
198
  id: string;
@@ -101,4 +216,44 @@ export declare const workspace: import("@trpc/server").TRPCBuiltRouter<{
101
216
  output: boolean;
102
217
  meta: object;
103
218
  }>;
219
+ uploadAndAnalyzeMedia: import("@trpc/server").TRPCMutationProcedure<{
220
+ input: {
221
+ workspaceId: string;
222
+ file: {
223
+ filename: string;
224
+ contentType: string;
225
+ size: number;
226
+ content: string;
227
+ };
228
+ generateStudyGuide?: boolean | undefined;
229
+ generateFlashcards?: boolean | undefined;
230
+ generateWorksheet?: boolean | undefined;
231
+ };
232
+ output: {
233
+ filename: string;
234
+ artifacts: {
235
+ studyGuide: any | null;
236
+ flashcards: any | null;
237
+ worksheet: any | null;
238
+ };
239
+ };
240
+ meta: object;
241
+ }>;
242
+ search: import("@trpc/server").TRPCQueryProcedure<{
243
+ input: {
244
+ query: string;
245
+ limit?: number | undefined;
246
+ };
247
+ output: {
248
+ id: string;
249
+ createdAt: Date;
250
+ updatedAt: Date;
251
+ ownerId: string;
252
+ title: string;
253
+ description: string | null;
254
+ folderId: string | null;
255
+ shareLink: string | null;
256
+ }[];
257
+ meta: object;
258
+ }>;
104
259
  }>>;