@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
@@ -0,0 +1,54 @@
1
+ export declare const studyguide: import("@trpc/server").TRPCBuiltRouter<{
2
+ ctx: {
3
+ db: import("@prisma/client").PrismaClient<import("@prisma/client").Prisma.PrismaClientOptions, never, import("@prisma/client/runtime/library").DefaultArgs>;
4
+ session: any;
5
+ req: import("express").Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>;
6
+ res: import("express").Response<any, Record<string, any>>;
7
+ cookies: Record<string, string | undefined>;
8
+ };
9
+ meta: object;
10
+ errorShape: import("@trpc/server").TRPCDefaultErrorShape;
11
+ transformer: true;
12
+ }, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
13
+ get: import("@trpc/server").TRPCQueryProcedure<{
14
+ input: {
15
+ workspaceId: string;
16
+ };
17
+ output: {
18
+ artifactId: string;
19
+ title: string;
20
+ latestVersion: {
21
+ id: string;
22
+ createdAt: Date;
23
+ createdById: string | null;
24
+ artifactId: string;
25
+ content: string;
26
+ data: import("@prisma/client/runtime/library").JsonValue | null;
27
+ version: number;
28
+ };
29
+ };
30
+ meta: object;
31
+ }>;
32
+ edit: import("@trpc/server").TRPCMutationProcedure<{
33
+ input: {
34
+ workspaceId: string;
35
+ content: string;
36
+ studyGuideId?: string | undefined;
37
+ data?: Record<string, unknown> | undefined;
38
+ title?: string | undefined;
39
+ };
40
+ output: {
41
+ artifactId: string;
42
+ version: {
43
+ id: string;
44
+ createdAt: Date;
45
+ createdById: string | null;
46
+ artifactId: string;
47
+ content: string;
48
+ data: import("@prisma/client/runtime/library").JsonValue | null;
49
+ version: number;
50
+ };
51
+ };
52
+ meta: object;
53
+ }>;
54
+ }>>;
@@ -0,0 +1,125 @@
1
+ import { z } from 'zod';
2
+ import { router, authedProcedure } from '../trpc.js';
3
+ // Mirror Prisma enum to avoid direct type import
4
+ const ArtifactType = {
5
+ STUDY_GUIDE: 'STUDY_GUIDE',
6
+ };
7
+ const initializeEditorJsEmptyBlock = () => ({
8
+ time: Date.now(),
9
+ blocks: [
10
+ {
11
+ id: 'initial',
12
+ type: 'paragraph',
13
+ data: { text: 'Start writing your study guide...' },
14
+ },
15
+ ],
16
+ version: '2.27.0',
17
+ });
18
+ export const studyguide = router({
19
+ // Get latest study guide for a workspace or a specific study guide by ID
20
+ get: authedProcedure
21
+ .input(z.object({
22
+ workspaceId: z.string(),
23
+ }))
24
+ .query(async ({ ctx, input }) => {
25
+ // by studyGuideId (artifact id)
26
+ let artifact = await ctx.db.artifact.findFirst({
27
+ where: {
28
+ workspaceId: input.workspaceId,
29
+ type: ArtifactType.STUDY_GUIDE,
30
+ workspace: { ownerId: ctx.session.user.id },
31
+ },
32
+ include: {
33
+ versions: { orderBy: { version: 'desc' }, take: 1 },
34
+ },
35
+ });
36
+ console.log('artifact', artifact);
37
+ if (!artifact) {
38
+ artifact = await ctx.db.artifact.create({
39
+ data: {
40
+ workspaceId: input.workspaceId,
41
+ type: ArtifactType.STUDY_GUIDE,
42
+ title: 'Study Guide',
43
+ createdById: ctx.session.user.id,
44
+ versions: {
45
+ create: {
46
+ content: `${JSON.stringify(initializeEditorJsEmptyBlock())}`,
47
+ version: 1,
48
+ createdById: ctx.session.user.id,
49
+ }
50
+ }
51
+ },
52
+ include: {
53
+ versions: { orderBy: { version: 'desc' }, take: 1 },
54
+ }
55
+ });
56
+ }
57
+ const latestVersion = artifact.versions[0] ?? null;
58
+ return { artifactId: artifact.id, title: artifact.title, latestVersion };
59
+ }),
60
+ // Edit study guide content by creating a new version, or create if doesn't exist
61
+ edit: authedProcedure
62
+ .input(z.object({
63
+ workspaceId: z.string(),
64
+ studyGuideId: z.string().optional(),
65
+ content: z.string().min(1),
66
+ data: z.record(z.string(), z.unknown()).optional(),
67
+ title: z.string().min(1).optional(),
68
+ }))
69
+ .mutation(async ({ ctx, input }) => {
70
+ let artifact;
71
+ if (input.studyGuideId) {
72
+ // Try to find existing study guide
73
+ artifact = await ctx.db.artifact.findFirst({
74
+ where: {
75
+ id: input.studyGuideId,
76
+ type: ArtifactType.STUDY_GUIDE,
77
+ workspace: { ownerId: ctx.session.user.id },
78
+ },
79
+ });
80
+ }
81
+ else {
82
+ // Find by workspace if no specific studyGuideId provided
83
+ artifact = await ctx.db.artifact.findFirst({
84
+ where: {
85
+ workspaceId: input.workspaceId,
86
+ type: ArtifactType.STUDY_GUIDE,
87
+ workspace: { ownerId: ctx.session.user.id },
88
+ },
89
+ });
90
+ }
91
+ // If no study guide found, create a new one
92
+ if (!artifact) {
93
+ artifact = await ctx.db.artifact.create({
94
+ data: {
95
+ workspaceId: input.workspaceId,
96
+ type: ArtifactType.STUDY_GUIDE,
97
+ title: 'Study Guide',
98
+ createdById: ctx.session.user.id,
99
+ },
100
+ });
101
+ }
102
+ const last = await ctx.db.artifactVersion.findFirst({
103
+ where: { artifactId: artifact.id },
104
+ orderBy: { version: 'desc' },
105
+ });
106
+ if (input.title && input.title !== artifact.title) {
107
+ console.log('rename');
108
+ await ctx.db.artifact.update({
109
+ where: { id: artifact.id },
110
+ data: { title: input.title },
111
+ });
112
+ }
113
+ const nextVersion = (last?.version ?? 0) + 1;
114
+ const version = await ctx.db.artifactVersion.create({
115
+ data: {
116
+ artifactId: artifact.id,
117
+ content: input.content,
118
+ data: input.data,
119
+ version: nextVersion,
120
+ createdById: ctx.session.user.id,
121
+ },
122
+ });
123
+ return { artifactId: artifact.id, version };
124
+ }),
125
+ });
@@ -14,87 +14,63 @@ export declare const worksheets: import("@trpc/server").TRPCBuiltRouter<{
14
14
  input: {
15
15
  workspaceId: string;
16
16
  };
17
- output: ({
18
- versions: {
19
- id: string;
20
- createdAt: Date;
21
- createdById: string | null;
22
- artifactId: string;
23
- content: string;
24
- data: import("@prisma/client/runtime/library").JsonValue | null;
25
- version: number;
26
- }[];
27
- questions: {
28
- meta: import("@prisma/client/runtime/library").JsonValue | null;
29
- id: string;
30
- createdAt: Date;
31
- artifactId: string;
32
- order: number;
33
- prompt: string;
34
- answer: string | null;
35
- difficulty: import("@prisma/client").$Enums.Difficulty;
36
- }[];
37
- } & {
38
- id: string;
39
- createdAt: Date;
40
- updatedAt: Date;
41
- title: string;
42
- workspaceId: string;
43
- type: import("@prisma/client").$Enums.ArtifactType;
44
- isArchived: boolean;
45
- createdById: string | null;
46
- })[];
17
+ output: any;
47
18
  meta: object;
48
19
  }>;
49
- createWorksheet: import("@trpc/server").TRPCMutationProcedure<{
20
+ create: import("@trpc/server").TRPCMutationProcedure<{
50
21
  input: {
51
22
  workspaceId: string;
52
23
  title: string;
53
- };
54
- output: {
55
- id: string;
56
- createdAt: Date;
57
- updatedAt: Date;
58
- title: string;
59
- workspaceId: string;
60
- type: import("@prisma/client").$Enums.ArtifactType;
61
- isArchived: boolean;
62
- createdById: string | null;
63
- };
64
- meta: object;
65
- }>;
66
- get: import("@trpc/server").TRPCQueryProcedure<{
67
- input: {
68
- worksheetId: string;
24
+ description?: string | undefined;
25
+ difficulty?: "EASY" | "MEDIUM" | "HARD" | undefined;
26
+ estimatedTime?: string | undefined;
27
+ problems?: {
28
+ question: string;
29
+ answer: string;
30
+ type?: "TEXT" | "MULTIPLE_CHOICE" | "NUMERIC" | "TRUE_FALSE" | "MATCHING" | "FILL_IN_THE_BLANK" | undefined;
31
+ options?: string[] | undefined;
32
+ }[] | undefined;
69
33
  };
70
34
  output: {
71
35
  questions: {
72
36
  meta: import("@prisma/client/runtime/library").JsonValue | null;
73
37
  id: string;
74
38
  createdAt: Date;
39
+ type: import("@prisma/client").$Enums.QuestionType;
40
+ difficulty: import("@prisma/client").$Enums.Difficulty;
75
41
  artifactId: string;
76
42
  order: number;
77
43
  prompt: string;
78
44
  answer: string | null;
79
- difficulty: import("@prisma/client").$Enums.Difficulty;
80
45
  }[];
81
46
  } & {
82
47
  id: string;
83
48
  createdAt: Date;
84
49
  updatedAt: Date;
85
50
  title: string;
51
+ description: string | null;
86
52
  workspaceId: string;
87
53
  type: import("@prisma/client").$Enums.ArtifactType;
88
54
  isArchived: boolean;
55
+ difficulty: import("@prisma/client").$Enums.Difficulty | null;
56
+ estimatedTime: string | null;
89
57
  createdById: string | null;
90
58
  };
91
59
  meta: object;
92
60
  }>;
61
+ get: import("@trpc/server").TRPCQueryProcedure<{
62
+ input: {
63
+ worksheetId: string;
64
+ };
65
+ output: any;
66
+ meta: object;
67
+ }>;
93
68
  createWorksheetQuestion: import("@trpc/server").TRPCMutationProcedure<{
94
69
  input: {
95
70
  worksheetId: string;
96
71
  prompt: string;
97
72
  answer?: string | undefined;
73
+ type?: "TEXT" | "MULTIPLE_CHOICE" | "NUMERIC" | "TRUE_FALSE" | "MATCHING" | "FILL_IN_THE_BLANK" | undefined;
98
74
  difficulty?: "EASY" | "MEDIUM" | "HARD" | undefined;
99
75
  order?: number | undefined;
100
76
  meta?: Record<string, unknown> | undefined;
@@ -103,11 +79,12 @@ export declare const worksheets: import("@trpc/server").TRPCBuiltRouter<{
103
79
  meta: import("@prisma/client/runtime/library").JsonValue | null;
104
80
  id: string;
105
81
  createdAt: Date;
82
+ type: import("@prisma/client").$Enums.QuestionType;
83
+ difficulty: import("@prisma/client").$Enums.Difficulty;
106
84
  artifactId: string;
107
85
  order: number;
108
86
  prompt: string;
109
87
  answer: string | null;
110
- difficulty: import("@prisma/client").$Enums.Difficulty;
111
88
  };
112
89
  meta: object;
113
90
  }>;
@@ -116,6 +93,7 @@ export declare const worksheets: import("@trpc/server").TRPCBuiltRouter<{
116
93
  worksheetQuestionId: string;
117
94
  prompt?: string | undefined;
118
95
  answer?: string | undefined;
96
+ type?: "TEXT" | "MULTIPLE_CHOICE" | "NUMERIC" | "TRUE_FALSE" | "MATCHING" | "FILL_IN_THE_BLANK" | undefined;
119
97
  difficulty?: "EASY" | "MEDIUM" | "HARD" | undefined;
120
98
  order?: number | undefined;
121
99
  meta?: Record<string, unknown> | undefined;
@@ -124,11 +102,12 @@ export declare const worksheets: import("@trpc/server").TRPCBuiltRouter<{
124
102
  meta: import("@prisma/client/runtime/library").JsonValue | null;
125
103
  id: string;
126
104
  createdAt: Date;
105
+ type: import("@prisma/client").$Enums.QuestionType;
106
+ difficulty: import("@prisma/client").$Enums.Difficulty;
127
107
  artifactId: string;
128
108
  order: number;
129
109
  prompt: string;
130
110
  answer: string | null;
131
- difficulty: import("@prisma/client").$Enums.Difficulty;
132
111
  };
133
112
  meta: object;
134
113
  }>;
@@ -139,11 +118,119 @@ export declare const worksheets: import("@trpc/server").TRPCBuiltRouter<{
139
118
  output: boolean;
140
119
  meta: object;
141
120
  }>;
142
- deleteWorksheet: import("@trpc/server").TRPCMutationProcedure<{
121
+ updateProblemStatus: import("@trpc/server").TRPCMutationProcedure<{
122
+ input: {
123
+ problemId: string;
124
+ completed: boolean;
125
+ answer?: string | undefined;
126
+ };
127
+ output: {
128
+ meta: import("@prisma/client/runtime/library").JsonValue | null;
129
+ id: string;
130
+ createdAt: Date;
131
+ updatedAt: Date;
132
+ userId: string;
133
+ worksheetQuestionId: string;
134
+ completed: boolean;
135
+ userAnswer: string | null;
136
+ completedAt: Date | null;
137
+ attempts: number;
138
+ timeSpentSec: number | null;
139
+ };
140
+ meta: object;
141
+ }>;
142
+ getProgress: import("@trpc/server").TRPCQueryProcedure<{
143
143
  input: {
144
144
  worksheetId: string;
145
145
  };
146
+ output: {
147
+ meta: import("@prisma/client/runtime/library").JsonValue | null;
148
+ id: string;
149
+ createdAt: Date;
150
+ updatedAt: Date;
151
+ userId: string;
152
+ worksheetQuestionId: string;
153
+ completed: boolean;
154
+ userAnswer: string | null;
155
+ completedAt: Date | null;
156
+ attempts: number;
157
+ timeSpentSec: number | null;
158
+ }[];
159
+ meta: object;
160
+ }>;
161
+ update: import("@trpc/server").TRPCMutationProcedure<{
162
+ input: {
163
+ id: string;
164
+ title?: string | undefined;
165
+ description?: string | undefined;
166
+ difficulty?: "EASY" | "MEDIUM" | "HARD" | undefined;
167
+ estimatedTime?: string | undefined;
168
+ problems?: {
169
+ question: string;
170
+ answer: string;
171
+ id?: string | undefined;
172
+ type?: "TEXT" | "MULTIPLE_CHOICE" | "NUMERIC" | "TRUE_FALSE" | "MATCHING" | "FILL_IN_THE_BLANK" | undefined;
173
+ options?: string[] | undefined;
174
+ }[] | undefined;
175
+ };
176
+ output: {
177
+ questions: {
178
+ meta: import("@prisma/client/runtime/library").JsonValue | null;
179
+ id: string;
180
+ createdAt: Date;
181
+ type: import("@prisma/client").$Enums.QuestionType;
182
+ difficulty: import("@prisma/client").$Enums.Difficulty;
183
+ artifactId: string;
184
+ order: number;
185
+ prompt: string;
186
+ answer: string | null;
187
+ }[];
188
+ } & {
189
+ id: string;
190
+ createdAt: Date;
191
+ updatedAt: Date;
192
+ title: string;
193
+ description: string | null;
194
+ workspaceId: string;
195
+ type: import("@prisma/client").$Enums.ArtifactType;
196
+ isArchived: boolean;
197
+ difficulty: import("@prisma/client").$Enums.Difficulty | null;
198
+ estimatedTime: string | null;
199
+ createdById: string | null;
200
+ };
201
+ meta: object;
202
+ }>;
203
+ delete: import("@trpc/server").TRPCMutationProcedure<{
204
+ input: {
205
+ id: string;
206
+ };
146
207
  output: boolean;
147
208
  meta: object;
148
209
  }>;
210
+ generateFromPrompt: import("@trpc/server").TRPCMutationProcedure<{
211
+ input: {
212
+ workspaceId: string;
213
+ prompt: string;
214
+ numQuestions?: number | undefined;
215
+ difficulty?: "easy" | "medium" | "hard" | undefined;
216
+ title?: string | undefined;
217
+ estimatedTime?: string | undefined;
218
+ };
219
+ output: {
220
+ artifact: {
221
+ id: string;
222
+ createdAt: Date;
223
+ updatedAt: Date;
224
+ title: string;
225
+ description: string | null;
226
+ workspaceId: string;
227
+ type: import("@prisma/client").$Enums.ArtifactType;
228
+ isArchived: boolean;
229
+ difficulty: import("@prisma/client").$Enums.Difficulty | null;
230
+ estimatedTime: string | null;
231
+ createdById: string | null;
232
+ };
233
+ };
234
+ meta: object;
235
+ }>;
149
236
  }>>;