@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.
Files changed (36) hide show
  1. package/dist/lib/ai-session.d.ts +13 -3
  2. package/dist/lib/ai-session.js +66 -146
  3. package/dist/lib/pusher.js +1 -1
  4. package/dist/routers/_app.d.ts +114 -7
  5. package/dist/routers/chat.js +2 -23
  6. package/dist/routers/flashcards.d.ts +25 -1
  7. package/dist/routers/flashcards.js +0 -14
  8. package/dist/routers/members.d.ts +18 -0
  9. package/dist/routers/members.js +14 -1
  10. package/dist/routers/worksheets.js +5 -4
  11. package/dist/routers/workspace.d.ts +89 -6
  12. package/dist/routers/workspace.js +389 -259
  13. package/dist/services/flashcard-progress.service.d.ts +25 -1
  14. package/dist/services/flashcard-progress.service.js +70 -31
  15. package/package.json +3 -2
  16. package/prisma/schema.prisma +196 -184
  17. package/src/lib/ai-session.ts +3 -21
  18. package/src/routers/auth.ts +50 -2
  19. package/src/routers/flashcards.ts +0 -16
  20. package/src/routers/members.ts +27 -6
  21. package/src/routers/workspace.ts +468 -439
  22. package/src/server.ts +13 -0
  23. package/ANALYSIS_PROGRESS_SPEC.md +0 -463
  24. package/PROGRESS_QUICK_REFERENCE.md +0 -239
  25. package/dist/lib/podcast-prompts.d.ts +0 -43
  26. package/dist/lib/podcast-prompts.js +0 -135
  27. package/dist/routers/ai-session.d.ts +0 -0
  28. package/dist/routers/ai-session.js +0 -1
  29. package/dist/services/flashcard.service.d.ts +0 -183
  30. package/dist/services/flashcard.service.js +0 -224
  31. package/dist/services/podcast-segment-reorder.d.ts +0 -0
  32. package/dist/services/podcast-segment-reorder.js +0 -107
  33. package/dist/services/podcast.service.d.ts +0 -0
  34. package/dist/services/podcast.service.js +0 -326
  35. package/dist/services/worksheet.service.d.ts +0 -0
  36. package/dist/services/worksheet.service.js +0 -295
@@ -3,6 +3,8 @@ import { router, publicProcedure, authedProcedure } from '../trpc.js';
3
3
  import bcrypt from 'bcryptjs';
4
4
  import { serialize } from 'cookie';
5
5
  import crypto from 'node:crypto';
6
+ import { TRPCError } from '@trpc/server';
7
+ import { supabaseClient } from 'src/lib/storage.js';
6
8
 
7
9
  // Helper to create custom auth token
8
10
  function createCustomAuthToken(userId: string): string {
@@ -19,6 +21,54 @@ function createCustomAuthToken(userId: string): string {
19
21
  }
20
22
 
21
23
  export const auth = router({
24
+ updateProfile: publicProcedure
25
+ .input(z.object({
26
+ name: z.string().min(1),
27
+ }))
28
+ .mutation(async ({ctx, input}) => {
29
+ const { name } = input;
30
+
31
+ await ctx.db.user.update({
32
+ where: {
33
+ id: ctx.session.user.id,
34
+ },
35
+ data: {
36
+ name: name,
37
+ }
38
+ });
39
+
40
+ return {
41
+ success: true,
42
+ message: 'Profile updated successfully',
43
+ };
44
+ }),
45
+ uploadProfilePicture: publicProcedure
46
+ .mutation(async ({ctx, input}) => {
47
+ const objectKey = `profile_picture_${ctx.session.user.id}`;
48
+ const { data: signedUrlData, error: signedUrlError } = await supabaseClient.storage
49
+ .from('media')
50
+ .createSignedUploadUrl(objectKey); // 5 minutes
51
+ if (signedUrlError) {
52
+ throw new TRPCError({ code: 'INTERNAL_SERVER_ERROR', message: `Failed to generate upload URL: ${signedUrlError.message}` });
53
+ }
54
+
55
+ await ctx.db.fileAsset.create({
56
+ data: {
57
+ userId: ctx.session.user.id,
58
+ name: 'Profile Picture',
59
+ mimeType: 'image/jpeg',
60
+ size: 0,
61
+ bucket: 'media',
62
+ objectKey: objectKey,
63
+ },
64
+ });
65
+
66
+ return {
67
+ success: true,
68
+ message: 'Profile picture uploaded successfully',
69
+ signedUrl: signedUrlData.signedUrl,
70
+ };
71
+ }),
22
72
  signup: publicProcedure
23
73
  .input(z.object({
24
74
  name: z.string().min(1),
@@ -85,7 +135,6 @@ export const auth = router({
85
135
  id: user.id,
86
136
  email: user.email,
87
137
  name: user.name,
88
- image: user.image,
89
138
  token: authToken
90
139
  };
91
140
  }),
@@ -108,7 +157,6 @@ export const auth = router({
108
157
  id: user.id,
109
158
  email: user.email,
110
159
  name: user.name,
111
- image: user.image
112
160
  }
113
161
  };
114
162
  }),
@@ -177,22 +177,6 @@ export const flashcards = router({
177
177
 
178
178
  await PusherService.emitTaskComplete(input.workspaceId, 'flash_card_info', { status: 'generating', numCards: input.numCards, difficulty: input.difficulty });
179
179
 
180
- const formattedPreviousCards = flashcardCurrent?.flashcards.map((card) => ({
181
- front: card.front,
182
- back: card.back,
183
- }));
184
-
185
-
186
- const partialPrompt = `
187
- This is the users previous flashcards, avoid repeating any existing cards.
188
- Please generate ${input.numCards} new cards,
189
- Of a ${input.difficulty} difficulty,
190
- Of a ${input.tags?.join(', ')} tag,
191
- Of a ${input.title} title.
192
- ${formattedPreviousCards?.map((card) => `Front: ${card.front}\nBack: ${card.back}`).join('\n')}
193
-
194
- The user has also left you this prompt: ${input.prompt}
195
- `
196
180
  const artifact = await ctx.db.artifact.create({
197
181
  data: {
198
182
  workspaceId: input.workspaceId,
@@ -38,7 +38,13 @@ export const members = router({
38
38
  id: true,
39
39
  name: true,
40
40
  email: true,
41
- image: true,
41
+ profilePicture: {
42
+ select: {
43
+ id: true,
44
+ name: true,
45
+ url: true,
46
+ }
47
+ }
42
48
  }
43
49
  },
44
50
  members: {
@@ -48,7 +54,13 @@ export const members = router({
48
54
  id: true,
49
55
  name: true,
50
56
  email: true,
51
- image: true,
57
+ profilePicture: {
58
+ select: {
59
+ id: true,
60
+ name: true,
61
+ url: true,
62
+ }
63
+ }
52
64
  }
53
65
  }
54
66
  }
@@ -69,7 +81,6 @@ export const members = router({
69
81
  id: workspace.owner.id,
70
82
  name: workspace.owner.name || 'Unknown',
71
83
  email: workspace.owner.email || '',
72
- image: workspace.owner.image,
73
84
  role: 'owner' as const,
74
85
  joinedAt: workspace.createdAt,
75
86
  },
@@ -77,7 +88,6 @@ export const members = router({
77
88
  id: membership.user.id,
78
89
  name: membership.user.name || 'Unknown',
79
90
  email: membership.user.email || '',
80
- image: membership.user.image,
81
91
  role: membership.role as 'admin' | 'member',
82
92
  joinedAt: membership.joinedAt,
83
93
  }))
@@ -230,7 +240,16 @@ export const members = router({
230
240
  invitedByName: invitation.workspace.owner.name || invitation.workspace.owner.email,
231
241
  };
232
242
  }),
233
-
243
+ getInvitations: authedProcedure
244
+ .input(z.object({
245
+ workspaceId: z.string(),
246
+ }))
247
+ .query(async ({ ctx, input }) => {
248
+ const invitations = await ctx.db.workspaceInvitation.findMany({
249
+ where: { workspaceId: input.workspaceId },
250
+ });
251
+ return invitations;
252
+ }),
234
253
  /**
235
254
  * Accept an invitation (public endpoint)
236
255
  */
@@ -277,8 +296,10 @@ export const members = router({
277
296
  });
278
297
  }
279
298
 
299
+ const user = await ctx.db.user.findFirst({ where: { id: ctx.session.user.id } });
300
+ if (!user || !user.email) throw new TRPCError({ code: 'NOT_FOUND' });
280
301
  // Check if the email matches the user's email
281
- if (ctx.session.user.email !== invitation.email) {
302
+ if (user.email !== invitation.email) {
282
303
  throw new TRPCError({
283
304
  code: 'BAD_REQUEST',
284
305
  message: 'This invitation was sent to a different email address'