@goscribe/server 1.5.0 → 1.7.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.
Files changed (321) hide show
  1. package/dist/context.d.ts +14 -1
  2. package/dist/context.js +23 -2
  3. package/dist/generated/prisma/client.d.ts +224 -0
  4. package/dist/generated/prisma/client.js +34 -0
  5. package/dist/generated/prisma/commonInputTypes.d.ts +941 -0
  6. package/dist/generated/prisma/commonInputTypes.js +10 -0
  7. package/dist/generated/prisma/enums.d.ts +67 -0
  8. package/dist/generated/prisma/enums.js +66 -0
  9. package/dist/generated/prisma/internal/class.d.ts +539 -0
  10. package/dist/generated/prisma/internal/class.js +49 -0
  11. package/dist/generated/prisma/internal/prismaNamespace.d.ts +3924 -0
  12. package/dist/generated/prisma/internal/prismaNamespace.js +557 -0
  13. package/dist/generated/prisma/models/ActivityLog.d.ts +1847 -0
  14. package/dist/generated/prisma/models/ActivityLog.js +1 -0
  15. package/dist/generated/prisma/models/Artifact.d.ts +2345 -0
  16. package/dist/generated/prisma/models/Artifact.js +1 -0
  17. package/dist/generated/prisma/models/ArtifactVersion.d.ts +1550 -0
  18. package/dist/generated/prisma/models/ArtifactVersion.js +1 -0
  19. package/dist/generated/prisma/models/Channel.d.ts +1257 -0
  20. package/dist/generated/prisma/models/Channel.js +1 -0
  21. package/dist/generated/prisma/models/Chat.d.ts +1339 -0
  22. package/dist/generated/prisma/models/Chat.js +1 -0
  23. package/dist/generated/prisma/models/CopilotConversation.d.ts +1450 -0
  24. package/dist/generated/prisma/models/CopilotConversation.js +1 -0
  25. package/dist/generated/prisma/models/CopilotMessage.d.ts +1179 -0
  26. package/dist/generated/prisma/models/CopilotMessage.js +1 -0
  27. package/dist/generated/prisma/models/FileAsset.d.ts +1832 -0
  28. package/dist/generated/prisma/models/FileAsset.js +1 -0
  29. package/dist/generated/prisma/models/Flashcard.d.ts +1460 -0
  30. package/dist/generated/prisma/models/Flashcard.js +1 -0
  31. package/dist/generated/prisma/models/FlashcardProgress.d.ts +1782 -0
  32. package/dist/generated/prisma/models/FlashcardProgress.js +1 -0
  33. package/dist/generated/prisma/models/Folder.d.ts +1685 -0
  34. package/dist/generated/prisma/models/Folder.js +1 -0
  35. package/dist/generated/prisma/models/IdempotencyRecord.d.ts +1319 -0
  36. package/dist/generated/prisma/models/IdempotencyRecord.js +1 -0
  37. package/dist/generated/prisma/models/Invoice.d.ts +1586 -0
  38. package/dist/generated/prisma/models/Invoice.js +1 -0
  39. package/dist/generated/prisma/models/KnowledgeBase.d.ts +1721 -0
  40. package/dist/generated/prisma/models/KnowledgeBase.js +1 -0
  41. package/dist/generated/prisma/models/KnowledgeBaseChunk.d.ts +1333 -0
  42. package/dist/generated/prisma/models/KnowledgeBaseChunk.js +1 -0
  43. package/dist/generated/prisma/models/KnowledgeBaseDocument.d.ts +1695 -0
  44. package/dist/generated/prisma/models/KnowledgeBaseDocument.js +1 -0
  45. package/dist/generated/prisma/models/Notification.d.ts +1992 -0
  46. package/dist/generated/prisma/models/Notification.js +1 -0
  47. package/dist/generated/prisma/models/PasswordResetToken.d.ts +1210 -0
  48. package/dist/generated/prisma/models/PasswordResetToken.js +1 -0
  49. package/dist/generated/prisma/models/Plan.d.ts +1431 -0
  50. package/dist/generated/prisma/models/Plan.js +1 -0
  51. package/dist/generated/prisma/models/PlanLimit.d.ts +1328 -0
  52. package/dist/generated/prisma/models/PlanLimit.js +1 -0
  53. package/dist/generated/prisma/models/PodcastSegment.d.ts +1564 -0
  54. package/dist/generated/prisma/models/PodcastSegment.js +1 -0
  55. package/dist/generated/prisma/models/ResourcePrice.d.ts +1008 -0
  56. package/dist/generated/prisma/models/ResourcePrice.js +1 -0
  57. package/dist/generated/prisma/models/Role.d.ts +1065 -0
  58. package/dist/generated/prisma/models/Role.js +1 -0
  59. package/dist/generated/prisma/models/Session.d.ts +1105 -0
  60. package/dist/generated/prisma/models/Session.js +1 -0
  61. package/dist/generated/prisma/models/StripeEvent.d.ts +1081 -0
  62. package/dist/generated/prisma/models/StripeEvent.js +1 -0
  63. package/dist/generated/prisma/models/StudyGuideComment.d.ts +1321 -0
  64. package/dist/generated/prisma/models/StudyGuideComment.js +1 -0
  65. package/dist/generated/prisma/models/StudyGuideHighlight.d.ts +1629 -0
  66. package/dist/generated/prisma/models/StudyGuideHighlight.js +1 -0
  67. package/dist/generated/prisma/models/Subscription.d.ts +1677 -0
  68. package/dist/generated/prisma/models/Subscription.js +1 -0
  69. package/dist/generated/prisma/models/User.d.ts +7559 -0
  70. package/dist/generated/prisma/models/User.js +1 -0
  71. package/dist/generated/prisma/models/UserCredit.d.ts +1249 -0
  72. package/dist/generated/prisma/models/UserCredit.js +1 -0
  73. package/dist/generated/prisma/models/VerificationToken.d.ts +946 -0
  74. package/dist/generated/prisma/models/VerificationToken.js +1 -0
  75. package/dist/generated/prisma/models/WorksheetPreset.d.ts +1433 -0
  76. package/dist/generated/prisma/models/WorksheetPreset.js +1 -0
  77. package/dist/generated/prisma/models/WorksheetQuestion.d.ts +1491 -0
  78. package/dist/generated/prisma/models/WorksheetQuestion.js +1 -0
  79. package/dist/generated/prisma/models/WorksheetQuestionProgress.d.ts +1620 -0
  80. package/dist/generated/prisma/models/WorksheetQuestionProgress.js +1 -0
  81. package/dist/generated/prisma/models/Workspace.d.ts +3620 -0
  82. package/dist/generated/prisma/models/Workspace.js +1 -0
  83. package/dist/generated/prisma/models/WorkspaceInvitation.d.ts +1490 -0
  84. package/dist/generated/prisma/models/WorkspaceInvitation.js +1 -0
  85. package/dist/generated/prisma/models/WorkspaceKnowledgeBase.d.ts +1410 -0
  86. package/dist/generated/prisma/models/WorkspaceKnowledgeBase.js +1 -0
  87. package/dist/generated/prisma/models/WorkspaceMember.d.ts +1326 -0
  88. package/dist/generated/prisma/models/WorkspaceMember.js +1 -0
  89. package/dist/generated/prisma/models.d.ts +39 -0
  90. package/dist/generated/prisma/models.js +1 -0
  91. package/dist/lib/ai/index.d.ts +3 -2
  92. package/dist/lib/ai/index.js +3 -2
  93. package/dist/lib/ai/llm-client.d.ts +1 -0
  94. package/dist/lib/ai/llm-client.js +17 -0
  95. package/dist/routers/_app.d.ts +40 -80
  96. package/dist/routers/auth.js +1 -1
  97. package/dist/routers/flashcards.d.ts +12 -1
  98. package/dist/routers/payment.d.ts +1 -12
  99. package/dist/routers/workspace.d.ts +27 -67
  100. package/dist/routers/workspace.js +1 -0
  101. package/dist/services/billing/payment.service.d.ts +1 -12
  102. package/dist/services/billing/payment.service.js +3 -6
  103. package/dist/services/billing/usage.service.d.ts +30 -10
  104. package/dist/services/billing/usage.service.js +87 -15
  105. package/dist/services/content/copilot.service.js +15 -29
  106. package/dist/services/content/flashcard-progress.service.js +9 -9
  107. package/dist/services/content/flashcard.service.d.ts +45 -1
  108. package/dist/services/content/flashcard.service.js +81 -68
  109. package/dist/services/content/media-analysis.service.js +27 -27
  110. package/dist/services/content/worksheet-generation.service.test.js +2 -2
  111. package/dist/services/workspace/workspace.service.d.ts +23 -67
  112. package/dist/services/workspace/workspace.service.js +69 -62
  113. package/dist/src/context.d.ts +27 -0
  114. package/dist/src/context.js +33 -0
  115. package/dist/src/index.d.ts +3 -0
  116. package/dist/src/index.js +1 -0
  117. package/dist/src/lib/ai/config.d.ts +20 -0
  118. package/dist/src/lib/ai/config.js +31 -0
  119. package/dist/src/lib/ai/embedding-client.d.ts +8 -0
  120. package/dist/src/lib/ai/embedding-client.js +30 -0
  121. package/dist/src/lib/ai/index.d.ts +48 -0
  122. package/dist/src/lib/ai/index.js +29 -0
  123. package/dist/src/lib/ai/inference-backend/client.d.ts +28 -0
  124. package/dist/src/lib/ai/inference-backend/client.js +301 -0
  125. package/dist/src/lib/ai/inference-backend/mocks.d.ts +12 -0
  126. package/dist/src/lib/ai/inference-backend/mocks.js +133 -0
  127. package/dist/src/lib/ai/inference-backend/types.d.ts +44 -0
  128. package/dist/src/lib/ai/inference-backend/types.js +1 -0
  129. package/dist/src/lib/ai/json-parse.d.ts +2 -0
  130. package/dist/src/lib/ai/json-parse.js +34 -0
  131. package/dist/src/lib/ai/llm-client.d.ts +7 -0
  132. package/dist/src/lib/ai/llm-client.js +36 -0
  133. package/dist/src/lib/ai/mock.d.ts +2 -0
  134. package/dist/src/lib/ai/mock.js +10 -0
  135. package/dist/src/lib/ai/types.d.ts +9 -0
  136. package/dist/src/lib/ai/types.js +1 -0
  137. package/dist/src/lib/auth.d.ts +36 -0
  138. package/dist/src/lib/auth.js +117 -0
  139. package/dist/src/lib/chunking.d.ts +19 -0
  140. package/dist/src/lib/chunking.js +47 -0
  141. package/dist/src/lib/constants.d.ts +13 -0
  142. package/dist/src/lib/constants.js +12 -0
  143. package/dist/src/lib/curated-kb-seed.d.ts +12 -0
  144. package/dist/src/lib/curated-kb-seed.js +155 -0
  145. package/dist/src/lib/email.d.ts +11 -0
  146. package/dist/src/lib/email.js +152 -0
  147. package/dist/src/lib/embeddings.d.ts +2 -0
  148. package/dist/src/lib/embeddings.js +1 -0
  149. package/dist/src/lib/ensure-curated-kb-catalog.d.ts +6 -0
  150. package/dist/src/lib/ensure-curated-kb-catalog.js +53 -0
  151. package/dist/src/lib/env.d.ts +41 -0
  152. package/dist/src/lib/env.js +57 -0
  153. package/dist/src/lib/errors.d.ts +33 -0
  154. package/dist/src/lib/errors.js +78 -0
  155. package/dist/src/lib/file.d.ts +0 -0
  156. package/dist/src/lib/file.js +1 -0
  157. package/dist/src/lib/inference.d.ts +1 -0
  158. package/dist/src/lib/inference.js +1 -0
  159. package/dist/src/lib/kb-meta.d.ts +8 -0
  160. package/dist/src/lib/kb-meta.js +77 -0
  161. package/dist/src/lib/logger.d.ts +62 -0
  162. package/dist/src/lib/logger.js +364 -0
  163. package/dist/src/lib/pdf.d.ts +11 -0
  164. package/dist/src/lib/pdf.js +11 -0
  165. package/dist/src/lib/prisma.d.ts +3 -0
  166. package/dist/src/lib/prisma.js +15 -0
  167. package/dist/src/lib/pusher.d.ts +38 -0
  168. package/dist/src/lib/pusher.js +170 -0
  169. package/dist/src/lib/retry.d.ts +15 -0
  170. package/dist/src/lib/retry.js +37 -0
  171. package/dist/src/lib/storage.d.ts +11 -0
  172. package/dist/src/lib/storage.js +71 -0
  173. package/dist/src/lib/stripe.d.ts +10 -0
  174. package/dist/src/lib/stripe.js +36 -0
  175. package/dist/src/lib/validation.d.ts +51 -0
  176. package/dist/src/lib/validation.js +64 -0
  177. package/dist/src/lib/workspace-kb.d.ts +5 -0
  178. package/dist/src/lib/workspace-kb.js +7 -0
  179. package/dist/src/repositories/artifact.repository.d.ts +64 -0
  180. package/dist/src/repositories/artifact.repository.js +40 -0
  181. package/dist/src/repositories/base.repository.d.ts +14 -0
  182. package/dist/src/repositories/base.repository.js +14 -0
  183. package/dist/src/repositories/invitation.repository.d.ts +104 -0
  184. package/dist/src/repositories/invitation.repository.js +44 -0
  185. package/dist/src/repositories/notification.repository.d.ts +76 -0
  186. package/dist/src/repositories/notification.repository.js +44 -0
  187. package/dist/src/repositories/user.repository.d.ts +84 -0
  188. package/dist/src/repositories/user.repository.js +37 -0
  189. package/dist/src/repositories/workspace-member.repository.d.ts +35 -0
  190. package/dist/src/repositories/workspace-member.repository.js +31 -0
  191. package/dist/src/repositories/workspace.repository.d.ts +101 -0
  192. package/dist/src/repositories/workspace.repository.js +79 -0
  193. package/dist/src/routers/_app.d.ts +3464 -0
  194. package/dist/src/routers/_app.js +36 -0
  195. package/dist/src/routers/admin.d.ts +358 -0
  196. package/dist/src/routers/admin.js +105 -0
  197. package/dist/src/routers/annotations.d.ts +219 -0
  198. package/dist/src/routers/annotations.js +29 -0
  199. package/dist/src/routers/artifactVersions.d.ts +65 -0
  200. package/dist/src/routers/artifactVersions.js +14 -0
  201. package/dist/src/routers/auth.d.ts +161 -0
  202. package/dist/src/routers/auth.js +97 -0
  203. package/dist/src/routers/chat.d.ts +170 -0
  204. package/dist/src/routers/chat.js +32 -0
  205. package/dist/src/routers/copilot.d.ts +200 -0
  206. package/dist/src/routers/copilot.js +52 -0
  207. package/dist/src/routers/flashcards.d.ts +336 -0
  208. package/dist/src/routers/flashcards.js +93 -0
  209. package/dist/src/routers/knowledgeBase.d.ts +421 -0
  210. package/dist/src/routers/knowledgeBase.js +118 -0
  211. package/dist/src/routers/members.d.ts +169 -0
  212. package/dist/src/routers/members.js +47 -0
  213. package/dist/src/routers/notifications.d.ts +99 -0
  214. package/dist/src/routers/notifications.js +25 -0
  215. package/dist/src/routers/payment.d.ts +80 -0
  216. package/dist/src/routers/payment.js +21 -0
  217. package/dist/src/routers/podcast.d.ts +287 -0
  218. package/dist/src/routers/podcast.js +34 -0
  219. package/dist/src/routers/studyguide.d.ts +36 -0
  220. package/dist/src/routers/studyguide.js +8 -0
  221. package/dist/src/routers/worksheets.d.ts +429 -0
  222. package/dist/src/routers/worksheets.js +139 -0
  223. package/dist/src/routers/workspace.d.ts +563 -0
  224. package/dist/src/routers/workspace.js +104 -0
  225. package/dist/src/scripts/purge-deleted-users.d.ts +1 -0
  226. package/dist/src/scripts/purge-deleted-users.js +148 -0
  227. package/dist/src/server.d.ts +1 -0
  228. package/dist/src/server.js +190 -0
  229. package/dist/src/services/activity/activity-human-description.service.d.ts +13 -0
  230. package/dist/src/services/activity/activity-human-description.service.js +221 -0
  231. package/dist/src/services/activity/activity-human-description.service.test.d.ts +1 -0
  232. package/dist/src/services/activity/activity-human-description.service.test.js +16 -0
  233. package/dist/src/services/activity/activity-log.service.d.ts +87 -0
  234. package/dist/src/services/activity/activity-log.service.js +276 -0
  235. package/dist/src/services/activity/activity-log.service.test.d.ts +1 -0
  236. package/dist/src/services/activity/activity-log.service.test.js +27 -0
  237. package/dist/src/services/admin/admin.service.d.ts +270 -0
  238. package/dist/src/services/admin/admin.service.js +476 -0
  239. package/dist/src/services/ai/ai-session.service.d.ts +5 -0
  240. package/dist/src/services/ai/ai-session.service.js +4 -0
  241. package/dist/src/services/artifacts/annotation.service.d.ts +177 -0
  242. package/dist/src/services/artifacts/annotation.service.js +154 -0
  243. package/dist/src/services/artifacts/artifact-version.service.d.ts +38 -0
  244. package/dist/src/services/artifacts/artifact-version.service.js +129 -0
  245. package/dist/src/services/artifacts/chat.service.d.ts +127 -0
  246. package/dist/src/services/artifacts/chat.service.js +182 -0
  247. package/dist/src/services/artifacts/study-guide.service.d.ts +18 -0
  248. package/dist/src/services/artifacts/study-guide.service.js +65 -0
  249. package/dist/src/services/auth/auth.service.d.ts +94 -0
  250. package/dist/src/services/auth/auth.service.js +368 -0
  251. package/dist/src/services/base.service.d.ts +14 -0
  252. package/dist/src/services/base.service.js +14 -0
  253. package/dist/src/services/billing/payment.service.d.ts +44 -0
  254. package/dist/src/services/billing/payment.service.js +365 -0
  255. package/dist/src/services/billing/subscription.service.d.ts +37 -0
  256. package/dist/src/services/billing/subscription.service.js +654 -0
  257. package/dist/src/services/billing/usage.service.d.ts +47 -0
  258. package/dist/src/services/billing/usage.service.js +149 -0
  259. package/dist/src/services/content/copilot.service.d.ts +113 -0
  260. package/dist/src/services/content/copilot.service.js +439 -0
  261. package/dist/src/services/content/flashcard-progress.service.d.ts +159 -0
  262. package/dist/src/services/content/flashcard-progress.service.js +432 -0
  263. package/dist/src/services/content/flashcard.service.d.ts +184 -0
  264. package/dist/src/services/content/flashcard.service.js +339 -0
  265. package/dist/src/services/content/media-analysis.service.d.ts +23 -0
  266. package/dist/src/services/content/media-analysis.service.js +404 -0
  267. package/dist/src/services/content/podcast.service.d.ts +267 -0
  268. package/dist/src/services/content/podcast.service.js +653 -0
  269. package/dist/src/services/content/worksheet-content.service.d.ts +37 -0
  270. package/dist/src/services/content/worksheet-content.service.js +84 -0
  271. package/dist/src/services/content/worksheet-content.service.test.d.ts +1 -0
  272. package/dist/src/services/content/worksheet-content.service.test.js +69 -0
  273. package/dist/src/services/content/worksheet-generation.service.d.ts +91 -0
  274. package/dist/src/services/content/worksheet-generation.service.js +95 -0
  275. package/dist/src/services/content/worksheet-generation.service.test.d.ts +1 -0
  276. package/dist/src/services/content/worksheet-generation.service.test.js +20 -0
  277. package/dist/src/services/content/worksheet.service.d.ts +347 -0
  278. package/dist/src/services/content/worksheet.service.js +599 -0
  279. package/dist/src/services/knowledge/knowledge-base.service.d.ts +316 -0
  280. package/dist/src/services/knowledge/knowledge-base.service.js +544 -0
  281. package/dist/src/services/members/invitation.service.d.ts +66 -0
  282. package/dist/src/services/members/invitation.service.js +348 -0
  283. package/dist/src/services/members/member.service.d.ts +36 -0
  284. package/dist/src/services/members/member.service.js +193 -0
  285. package/dist/src/services/notifications/notification.service.d.ts +214 -0
  286. package/dist/src/services/notifications/notification.service.js +550 -0
  287. package/dist/src/services/notifications/notification.service.test.d.ts +1 -0
  288. package/dist/src/services/notifications/notification.service.test.js +87 -0
  289. package/dist/src/services/workspace/workspace-analytics.service.d.ts +24 -0
  290. package/dist/src/services/workspace/workspace-analytics.service.js +95 -0
  291. package/dist/src/services/workspace/workspace-kb.service.d.ts +40 -0
  292. package/dist/src/services/workspace/workspace-kb.service.js +184 -0
  293. package/dist/src/services/workspace/workspace.service.d.ts +263 -0
  294. package/dist/src/services/workspace/workspace.service.js +401 -0
  295. package/dist/src/trpc.d.ts +60 -0
  296. package/dist/src/trpc.js +217 -0
  297. package/dist/src/types/index.d.ts +126 -0
  298. package/dist/src/types/index.js +1 -0
  299. package/dist/trpc.d.ts +12 -4
  300. package/dist/trpc.js +5 -11
  301. package/package.json +8 -9
  302. package/prisma/schema.prisma +3 -4
  303. package/prisma/seed.mjs +5 -2
  304. package/prisma.config.ts +16 -0
  305. package/src/context.ts +33 -3
  306. package/src/lib/ai/index.ts +3 -0
  307. package/src/lib/ai/llm-client.ts +23 -0
  308. package/src/lib/prisma.ts +18 -9
  309. package/src/routers/auth.ts +1 -1
  310. package/src/routers/workspace.ts +4 -0
  311. package/src/scripts/purge-deleted-users.ts +1 -3
  312. package/src/services/billing/payment.service.ts +3 -6
  313. package/src/services/billing/usage.service.ts +190 -77
  314. package/src/services/content/copilot.service.ts +23 -32
  315. package/src/services/content/flashcard-progress.service.ts +12 -9
  316. package/src/services/content/flashcard.service.ts +89 -66
  317. package/src/services/content/media-analysis.service.ts +34 -29
  318. package/src/services/content/worksheet-generation.service.test.ts +2 -2
  319. package/src/services/workspace/workspace.service.ts +73 -66
  320. package/src/trpc.ts +5 -13
  321. package/tsconfig.json +3 -0
@@ -0,0 +1,71 @@
1
+ // src/server/lib/storage.ts
2
+ import { createClient } from '@supabase/supabase-js';
3
+ import { v4 as uuidv4 } from 'uuid';
4
+ // Initialize Supabase Storage
5
+ const supabaseUrl = process.env.SUPABASE_URL;
6
+ const supabaseServiceKey = process.env.SUPABASE_SERVICE_ROLE_KEY;
7
+ if (!supabaseUrl || !supabaseServiceKey) {
8
+ throw new Error('Missing required Supabase environment variables: SUPABASE_URL and SUPABASE_SERVICE_ROLE_KEY');
9
+ }
10
+ const supabase = createClient(supabaseUrl, supabaseServiceKey);
11
+ const bucketName = process.env.SUPABASE_BUCKET || 'media';
12
+ export async function uploadToSupabase(fileBuffer, fileName, contentType, makePublic = false) {
13
+ const objectKey = `podcasts/${uuidv4()}_${fileName}`;
14
+ // Upload the file to Supabase Storage
15
+ const { data, error } = await supabase.storage
16
+ .from(bucketName)
17
+ .upload(objectKey, fileBuffer, {
18
+ contentType,
19
+ upsert: false,
20
+ });
21
+ if (error) {
22
+ throw new Error(`Failed to upload file to Supabase: ${error.message}`);
23
+ }
24
+ const url = `${supabaseUrl}/storage/v1/object/public/${bucketName}/${objectKey}`;
25
+ // Generate signed URL for private files
26
+ let signedUrl;
27
+ if (!makePublic) {
28
+ const { data: signedUrlData, error: signedUrlError } = await supabase.storage
29
+ .from(bucketName)
30
+ .createSignedUrl(objectKey, 24 * 60 * 60); // 24 hours
31
+ if (signedUrlError) {
32
+ throw new Error(`Failed to generate signed URL: ${signedUrlError.message}`);
33
+ }
34
+ signedUrl = signedUrlData.signedUrl;
35
+ }
36
+ return {
37
+ url,
38
+ signedUrl,
39
+ objectKey,
40
+ };
41
+ }
42
+ export async function generateSignedUrl(objectKey, expiresInHours = 24) {
43
+ const { data, error } = await supabase.storage
44
+ .from(bucketName)
45
+ .createSignedUrl(objectKey, expiresInHours * 60 * 60);
46
+ if (error) {
47
+ throw new Error(`Failed to generate signed URL: ${error.message}`);
48
+ }
49
+ return data.signedUrl;
50
+ }
51
+ export async function deleteFromSupabase(objectKey) {
52
+ const { error } = await supabase.storage
53
+ .from(bucketName)
54
+ .remove([objectKey]);
55
+ if (error) {
56
+ throw new Error(`Failed to delete file from Supabase: ${error.message}`);
57
+ }
58
+ }
59
+ export async function makeFilePublic(objectKey) {
60
+ // In Supabase, files are public by default when uploaded to public buckets
61
+ // For private buckets, you would need to update the bucket policy
62
+ // This function is kept for compatibility but may not be needed
63
+ // File is already public in Supabase Storage
64
+ }
65
+ export async function makeFilePrivate(objectKey) {
66
+ // In Supabase, you would need to update the bucket policy to make files private
67
+ // This function is kept for compatibility but may not be needed
68
+ // File privacy is controlled by bucket policy in Supabase Storage
69
+ }
70
+ // Export supabase client for direct access if needed
71
+ export const supabaseClient = supabase;
@@ -0,0 +1,10 @@
1
+ import Stripe from 'stripe';
2
+ export declare const stripe: Stripe | null;
3
+ /**
4
+ * Creates a Stripe customer for a user.
5
+ *
6
+ * @param email - User's email
7
+ * @param name - User's name
8
+ * @returns The Stripe customer ID
9
+ */
10
+ export declare function createStripeCustomer(email: string, name?: string): Promise<string | null>;
@@ -0,0 +1,36 @@
1
+ import Stripe from 'stripe';
2
+ import { env } from './env.js';
3
+ import { logger } from './logger.js';
4
+ if (!env.STRIPE_SECRET_KEY) {
5
+ logger.warn('STRIPE_SECRET_KEY is not set. Stripe functionality will be disabled.', 'STRIPE');
6
+ }
7
+ export const stripe = env.STRIPE_SECRET_KEY
8
+ ? new Stripe(env.STRIPE_SECRET_KEY, {
9
+ apiVersion: '2026-02-25.clover',
10
+ })
11
+ : null;
12
+ /**
13
+ * Creates a Stripe customer for a user.
14
+ *
15
+ * @param email - User's email
16
+ * @param name - User's name
17
+ * @returns The Stripe customer ID
18
+ */
19
+ export async function createStripeCustomer(email, name) {
20
+ if (!stripe) {
21
+ logger.error('Stripe is not initialized. Cannot create customer.', 'STRIPE');
22
+ return null;
23
+ }
24
+ try {
25
+ const customer = await stripe.customers.create({
26
+ email,
27
+ name,
28
+ });
29
+ logger.info(`Stripe customer created for ${email}: ${customer.id}`, 'STRIPE');
30
+ return customer.id;
31
+ }
32
+ catch (error) {
33
+ logger.error(`Failed to create Stripe customer for ${email}: ${error.message}`, 'STRIPE');
34
+ return null;
35
+ }
36
+ }
@@ -0,0 +1,51 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Common validation schemas
4
+ */
5
+ export declare const commonSchemas: {
6
+ id: z.ZodString;
7
+ email: z.ZodString;
8
+ url: z.ZodString;
9
+ pagination: z.ZodObject<{
10
+ page: z.ZodDefault<z.ZodNumber>;
11
+ limit: z.ZodDefault<z.ZodNumber>;
12
+ }, z.core.$strip>;
13
+ search: z.ZodObject<{
14
+ query: z.ZodString;
15
+ }, z.core.$strip>;
16
+ };
17
+ /**
18
+ * Enums for type safety
19
+ */
20
+ export declare const ArtifactType: z.ZodEnum<{
21
+ WORKSHEET: "WORKSHEET";
22
+ STUDY_GUIDE: "STUDY_GUIDE";
23
+ FLASHCARD_SET: "FLASHCARD_SET";
24
+ MEETING_SUMMARY: "MEETING_SUMMARY";
25
+ PODCAST_EPISODE: "PODCAST_EPISODE";
26
+ }>;
27
+ export declare const Difficulty: z.ZodEnum<{
28
+ EASY: "EASY";
29
+ MEDIUM: "MEDIUM";
30
+ HARD: "HARD";
31
+ }>;
32
+ export declare const QuestionType: z.ZodEnum<{
33
+ MULTIPLE_CHOICE: "MULTIPLE_CHOICE";
34
+ TEXT: "TEXT";
35
+ NUMERIC: "NUMERIC";
36
+ TRUE_FALSE: "TRUE_FALSE";
37
+ MATCHING: "MATCHING";
38
+ FILL_IN_THE_BLANK: "FILL_IN_THE_BLANK";
39
+ }>;
40
+ /**
41
+ * Validation helper that throws ValidationError
42
+ */
43
+ export declare function validateSchema<T extends z.ZodType>(schema: T, data: unknown): z.infer<T>;
44
+ /**
45
+ * Sanitize string inputs
46
+ */
47
+ export declare function sanitizeString(input: string, maxLength?: number): string;
48
+ /**
49
+ * Validate ownership
50
+ */
51
+ export declare function validateOwnership(ownerId: string, userId: string): void;
@@ -0,0 +1,64 @@
1
+ import { z } from 'zod';
2
+ import { ValidationError } from './errors.js';
3
+ /**
4
+ * Common validation schemas
5
+ */
6
+ export const commonSchemas = {
7
+ id: z.string().cuid(),
8
+ email: z.string().email(),
9
+ url: z.string().url(),
10
+ pagination: z.object({
11
+ page: z.number().int().positive().default(1),
12
+ limit: z.number().int().positive().max(100).default(20),
13
+ }),
14
+ search: z.object({
15
+ query: z.string().min(1).max(200),
16
+ }),
17
+ };
18
+ /**
19
+ * Enums for type safety
20
+ */
21
+ export const ArtifactType = z.enum([
22
+ 'STUDY_GUIDE',
23
+ 'FLASHCARD_SET',
24
+ 'WORKSHEET',
25
+ 'MEETING_SUMMARY',
26
+ 'PODCAST_EPISODE',
27
+ ]);
28
+ export const Difficulty = z.enum(['EASY', 'MEDIUM', 'HARD']);
29
+ export const QuestionType = z.enum([
30
+ 'MULTIPLE_CHOICE',
31
+ 'TEXT',
32
+ 'NUMERIC',
33
+ 'TRUE_FALSE',
34
+ 'MATCHING',
35
+ 'FILL_IN_THE_BLANK',
36
+ ]);
37
+ /**
38
+ * Validation helper that throws ValidationError
39
+ */
40
+ export function validateSchema(schema, data) {
41
+ const result = schema.safeParse(data);
42
+ if (!result.success) {
43
+ const errors = result.error.message;
44
+ throw new ValidationError(`Validation failed: ${errors}`);
45
+ }
46
+ return result.data;
47
+ }
48
+ /**
49
+ * Sanitize string inputs
50
+ */
51
+ export function sanitizeString(input, maxLength = 10000) {
52
+ return input
53
+ .trim()
54
+ .slice(0, maxLength)
55
+ .replace(/[<>]/g, ''); // Basic XSS prevention
56
+ }
57
+ /**
58
+ * Validate ownership
59
+ */
60
+ export function validateOwnership(ownerId, userId) {
61
+ if (ownerId !== userId) {
62
+ throw new ValidationError('You do not have permission to access this resource');
63
+ }
64
+ }
@@ -0,0 +1,5 @@
1
+ /** Meta.kind value for the private, auto-managed KB attached to each workspace. */
2
+ export declare const WORKSPACE_KB_KIND = "workspace";
3
+ export declare function isWorkspaceManagedKb(kb: {
4
+ meta: unknown;
5
+ }): boolean;
@@ -0,0 +1,7 @@
1
+ /** Meta.kind value for the private, auto-managed KB attached to each workspace. */
2
+ export const WORKSPACE_KB_KIND = 'workspace';
3
+ export function isWorkspaceManagedKb(kb) {
4
+ if (!kb.meta || typeof kb.meta !== 'object')
5
+ return false;
6
+ return kb.meta.kind === WORKSPACE_KB_KIND;
7
+ }
@@ -0,0 +1,64 @@
1
+ import type { ArtifactType, Prisma, PrismaClient } from '@prisma/client';
2
+ import { BaseRepository } from './base.repository.js';
3
+ export declare class ArtifactRepository extends BaseRepository {
4
+ constructor(db: PrismaClient);
5
+ /**
6
+ * Fetch an artifact if the user can access the containing workspace
7
+ * (owner or member).
8
+ */
9
+ findByIdAccessible(artifactId: string, userId: string, include?: Prisma.ArtifactInclude): Prisma.Prisma__ArtifactClient<{
10
+ id: string;
11
+ createdAt: Date;
12
+ updatedAt: Date;
13
+ title: string;
14
+ description: string | null;
15
+ createdById: string | null;
16
+ type: ArtifactType;
17
+ workspaceId: string;
18
+ difficulty: import("@prisma/client").Difficulty | null;
19
+ estimatedTime: string | null;
20
+ isArchived: boolean;
21
+ generating: boolean;
22
+ generatingMetadata: import("@prisma/client/runtime/client").JsonValue | null;
23
+ worksheetConfig: import("@prisma/client/runtime/client").JsonValue | null;
24
+ imageObjectKey: string | null;
25
+ } | null, null, import("@prisma/client/runtime/client").DefaultArgs, {
26
+ omit: Prisma.GlobalOmitConfig | undefined;
27
+ }>;
28
+ findByIdAndTypeAccessible(artifactId: string, type: ArtifactType, userId: string, include?: Prisma.ArtifactInclude): Prisma.Prisma__ArtifactClient<{
29
+ id: string;
30
+ createdAt: Date;
31
+ updatedAt: Date;
32
+ title: string;
33
+ description: string | null;
34
+ createdById: string | null;
35
+ type: ArtifactType;
36
+ workspaceId: string;
37
+ difficulty: import("@prisma/client").Difficulty | null;
38
+ estimatedTime: string | null;
39
+ isArchived: boolean;
40
+ generating: boolean;
41
+ generatingMetadata: import("@prisma/client/runtime/client").JsonValue | null;
42
+ worksheetConfig: import("@prisma/client/runtime/client").JsonValue | null;
43
+ imageObjectKey: string | null;
44
+ } | null, null, import("@prisma/client/runtime/client").DefaultArgs, {
45
+ omit: Prisma.GlobalOmitConfig | undefined;
46
+ }>;
47
+ listByWorkspaceAndType(workspaceId: string, type: ArtifactType, userId: string, args?: Omit<Prisma.ArtifactFindManyArgs, 'where'>): Prisma.PrismaPromise<{
48
+ id: string;
49
+ createdAt: Date;
50
+ updatedAt: Date;
51
+ title: string;
52
+ description: string | null;
53
+ createdById: string | null;
54
+ type: ArtifactType;
55
+ workspaceId: string;
56
+ difficulty: import("@prisma/client").Difficulty | null;
57
+ estimatedTime: string | null;
58
+ isArchived: boolean;
59
+ generating: boolean;
60
+ generatingMetadata: import("@prisma/client/runtime/client").JsonValue | null;
61
+ worksheetConfig: import("@prisma/client/runtime/client").JsonValue | null;
62
+ imageObjectKey: string | null;
63
+ }[]>;
64
+ }
@@ -0,0 +1,40 @@
1
+ import { BaseRepository } from './base.repository.js';
2
+ import { workspaceAccessWhere } from './workspace.repository.js';
3
+ export class ArtifactRepository extends BaseRepository {
4
+ constructor(db) {
5
+ super(db);
6
+ }
7
+ /**
8
+ * Fetch an artifact if the user can access the containing workspace
9
+ * (owner or member).
10
+ */
11
+ findByIdAccessible(artifactId, userId, include) {
12
+ return this.db.artifact.findFirst({
13
+ where: {
14
+ id: artifactId,
15
+ workspace: workspaceAccessWhere(userId),
16
+ },
17
+ include,
18
+ });
19
+ }
20
+ findByIdAndTypeAccessible(artifactId, type, userId, include) {
21
+ return this.db.artifact.findFirst({
22
+ where: {
23
+ id: artifactId,
24
+ type,
25
+ workspace: workspaceAccessWhere(userId),
26
+ },
27
+ include,
28
+ });
29
+ }
30
+ listByWorkspaceAndType(workspaceId, type, userId, args) {
31
+ return this.db.artifact.findMany({
32
+ ...args,
33
+ where: {
34
+ workspaceId,
35
+ type,
36
+ workspace: workspaceAccessWhere(userId),
37
+ },
38
+ });
39
+ }
40
+ }
@@ -0,0 +1,14 @@
1
+ import type { PrismaClient } from '@prisma/client';
2
+ import { logger } from '../lib/logger.js';
3
+ /**
4
+ * Shared base class for repositories.
5
+ *
6
+ * Repositories own data access. They wrap a Prisma client and expose
7
+ * intent-revealing methods (e.g. `findAccessibleById(workspaceId, userId)`)
8
+ * so that the shape of `where` clauses doesn't leak into services/routers.
9
+ */
10
+ export declare abstract class BaseRepository {
11
+ protected readonly db: PrismaClient;
12
+ protected readonly logger: typeof logger;
13
+ constructor(db: PrismaClient);
14
+ }
@@ -0,0 +1,14 @@
1
+ import { logger } from '../lib/logger.js';
2
+ /**
3
+ * Shared base class for repositories.
4
+ *
5
+ * Repositories own data access. They wrap a Prisma client and expose
6
+ * intent-revealing methods (e.g. `findAccessibleById(workspaceId, userId)`)
7
+ * so that the shape of `where` clauses doesn't leak into services/routers.
8
+ */
9
+ export class BaseRepository {
10
+ constructor(db) {
11
+ this.db = db;
12
+ this.logger = logger;
13
+ }
14
+ }
@@ -0,0 +1,104 @@
1
+ import type { Prisma, PrismaClient } from '@prisma/client';
2
+ import { BaseRepository } from './base.repository.js';
3
+ /**
4
+ * Data access for `WorkspaceInvitation`. Members router currently performs
5
+ * invitation CRUD + token validation directly against Prisma — this
6
+ * repository is the target of that extraction during Phase 4.
7
+ */
8
+ export declare class InvitationRepository extends BaseRepository {
9
+ constructor(db: PrismaClient);
10
+ findById(id: string, include?: Prisma.WorkspaceInvitationInclude): Prisma.Prisma__WorkspaceInvitationClient<{
11
+ id: string;
12
+ email: string;
13
+ createdAt: Date;
14
+ updatedAt: Date;
15
+ role: string;
16
+ token: string;
17
+ workspaceId: string;
18
+ invitedById: string;
19
+ acceptedAt: Date | null;
20
+ expiresAt: Date;
21
+ } | null, null, import("@prisma/client/runtime/client").DefaultArgs, {
22
+ omit: Prisma.GlobalOmitConfig | undefined;
23
+ }>;
24
+ findFirst(args: Prisma.WorkspaceInvitationFindFirstArgs): Prisma.Prisma__WorkspaceInvitationClient<{
25
+ id: string;
26
+ email: string;
27
+ createdAt: Date;
28
+ updatedAt: Date;
29
+ role: string;
30
+ token: string;
31
+ workspaceId: string;
32
+ invitedById: string;
33
+ acceptedAt: Date | null;
34
+ expiresAt: Date;
35
+ } | null, null, import("@prisma/client/runtime/client").DefaultArgs, {
36
+ omit: Prisma.GlobalOmitConfig | undefined;
37
+ }>;
38
+ listByWorkspace(workspaceId: string, args?: Omit<Prisma.WorkspaceInvitationFindManyArgs, 'where'>): Prisma.PrismaPromise<{
39
+ id: string;
40
+ email: string;
41
+ createdAt: Date;
42
+ updatedAt: Date;
43
+ role: string;
44
+ token: string;
45
+ workspaceId: string;
46
+ invitedById: string;
47
+ acceptedAt: Date | null;
48
+ expiresAt: Date;
49
+ }[]>;
50
+ listForUserEmail(email: string, args?: Omit<Prisma.WorkspaceInvitationFindManyArgs, 'where'>): Prisma.PrismaPromise<{
51
+ id: string;
52
+ email: string;
53
+ createdAt: Date;
54
+ updatedAt: Date;
55
+ role: string;
56
+ token: string;
57
+ workspaceId: string;
58
+ invitedById: string;
59
+ acceptedAt: Date | null;
60
+ expiresAt: Date;
61
+ }[]>;
62
+ create(data: Prisma.WorkspaceInvitationCreateInput): Prisma.Prisma__WorkspaceInvitationClient<{
63
+ id: string;
64
+ email: string;
65
+ createdAt: Date;
66
+ updatedAt: Date;
67
+ role: string;
68
+ token: string;
69
+ workspaceId: string;
70
+ invitedById: string;
71
+ acceptedAt: Date | null;
72
+ expiresAt: Date;
73
+ }, never, import("@prisma/client/runtime/client").DefaultArgs, {
74
+ omit: Prisma.GlobalOmitConfig | undefined;
75
+ }>;
76
+ update(id: string, data: Prisma.WorkspaceInvitationUpdateInput): Prisma.Prisma__WorkspaceInvitationClient<{
77
+ id: string;
78
+ email: string;
79
+ createdAt: Date;
80
+ updatedAt: Date;
81
+ role: string;
82
+ token: string;
83
+ workspaceId: string;
84
+ invitedById: string;
85
+ acceptedAt: Date | null;
86
+ expiresAt: Date;
87
+ }, never, import("@prisma/client/runtime/client").DefaultArgs, {
88
+ omit: Prisma.GlobalOmitConfig | undefined;
89
+ }>;
90
+ delete(id: string): Prisma.Prisma__WorkspaceInvitationClient<{
91
+ id: string;
92
+ email: string;
93
+ createdAt: Date;
94
+ updatedAt: Date;
95
+ role: string;
96
+ token: string;
97
+ workspaceId: string;
98
+ invitedById: string;
99
+ acceptedAt: Date | null;
100
+ expiresAt: Date;
101
+ }, never, import("@prisma/client/runtime/client").DefaultArgs, {
102
+ omit: Prisma.GlobalOmitConfig | undefined;
103
+ }>;
104
+ }
@@ -0,0 +1,44 @@
1
+ import { BaseRepository } from './base.repository.js';
2
+ /**
3
+ * Data access for `WorkspaceInvitation`. Members router currently performs
4
+ * invitation CRUD + token validation directly against Prisma — this
5
+ * repository is the target of that extraction during Phase 4.
6
+ */
7
+ export class InvitationRepository extends BaseRepository {
8
+ constructor(db) {
9
+ super(db);
10
+ }
11
+ findById(id, include) {
12
+ return this.db.workspaceInvitation.findFirst({
13
+ where: { id },
14
+ include,
15
+ });
16
+ }
17
+ findFirst(args) {
18
+ return this.db.workspaceInvitation.findFirst(args);
19
+ }
20
+ listByWorkspace(workspaceId, args) {
21
+ return this.db.workspaceInvitation.findMany({
22
+ ...args,
23
+ where: { workspaceId },
24
+ });
25
+ }
26
+ listForUserEmail(email, args) {
27
+ return this.db.workspaceInvitation.findMany({
28
+ ...args,
29
+ where: { email },
30
+ });
31
+ }
32
+ create(data) {
33
+ return this.db.workspaceInvitation.create({ data });
34
+ }
35
+ update(id, data) {
36
+ return this.db.workspaceInvitation.update({
37
+ where: { id },
38
+ data,
39
+ });
40
+ }
41
+ delete(id) {
42
+ return this.db.workspaceInvitation.delete({ where: { id } });
43
+ }
44
+ }
@@ -0,0 +1,76 @@
1
+ import type { Prisma, PrismaClient } from '@prisma/client';
2
+ import { BaseRepository } from './base.repository.js';
3
+ /**
4
+ * Thin data-access wrapper around `Notification`. `NotificationService`
5
+ * currently calls `ctx.db.notification.*` directly; Phase 4 will migrate it
6
+ * to use this repository so services don't need Prisma-specific types at
7
+ * their API boundary.
8
+ */
9
+ export declare class NotificationRepository extends BaseRepository {
10
+ constructor(db: PrismaClient);
11
+ findFirst(args: Prisma.NotificationFindFirstArgs): Prisma.Prisma__NotificationClient<{
12
+ userId: string;
13
+ id: string;
14
+ createdAt: Date;
15
+ updatedAt: Date;
16
+ title: string;
17
+ type: string;
18
+ workspaceId: string | null;
19
+ metadata: import("@prisma/client/runtime/client").JsonValue | null;
20
+ actorUserId: string | null;
21
+ body: string;
22
+ actionUrl: string | null;
23
+ priority: import("@prisma/client").NotificationPriority;
24
+ sourceId: string | null;
25
+ content: string | null;
26
+ read: boolean;
27
+ readAt: Date | null;
28
+ deliveredAt: Date | null;
29
+ } | null, null, import("@prisma/client/runtime/client").DefaultArgs, {
30
+ omit: Prisma.GlobalOmitConfig | undefined;
31
+ }>;
32
+ listByUser(userId: string, args?: Omit<Prisma.NotificationFindManyArgs, 'where'>): Prisma.PrismaPromise<{
33
+ userId: string;
34
+ id: string;
35
+ createdAt: Date;
36
+ updatedAt: Date;
37
+ title: string;
38
+ type: string;
39
+ workspaceId: string | null;
40
+ metadata: import("@prisma/client/runtime/client").JsonValue | null;
41
+ actorUserId: string | null;
42
+ body: string;
43
+ actionUrl: string | null;
44
+ priority: import("@prisma/client").NotificationPriority;
45
+ sourceId: string | null;
46
+ content: string | null;
47
+ read: boolean;
48
+ readAt: Date | null;
49
+ deliveredAt: Date | null;
50
+ }[]>;
51
+ count(args: Prisma.NotificationCountArgs): Prisma.PrismaPromise<number>;
52
+ create(data: Prisma.NotificationCreateInput): Prisma.Prisma__NotificationClient<{
53
+ userId: string;
54
+ id: string;
55
+ createdAt: Date;
56
+ updatedAt: Date;
57
+ title: string;
58
+ type: string;
59
+ workspaceId: string | null;
60
+ metadata: import("@prisma/client/runtime/client").JsonValue | null;
61
+ actorUserId: string | null;
62
+ body: string;
63
+ actionUrl: string | null;
64
+ priority: import("@prisma/client").NotificationPriority;
65
+ sourceId: string | null;
66
+ content: string | null;
67
+ read: boolean;
68
+ readAt: Date | null;
69
+ deliveredAt: Date | null;
70
+ }, never, import("@prisma/client/runtime/client").DefaultArgs, {
71
+ omit: Prisma.GlobalOmitConfig | undefined;
72
+ }>;
73
+ markRead(id: string, userId: string): Prisma.PrismaPromise<Prisma.BatchPayload>;
74
+ markAllRead(userId: string): Prisma.PrismaPromise<Prisma.BatchPayload>;
75
+ delete(id: string, userId: string): Prisma.PrismaPromise<Prisma.BatchPayload>;
76
+ }
@@ -0,0 +1,44 @@
1
+ import { BaseRepository } from './base.repository.js';
2
+ /**
3
+ * Thin data-access wrapper around `Notification`. `NotificationService`
4
+ * currently calls `ctx.db.notification.*` directly; Phase 4 will migrate it
5
+ * to use this repository so services don't need Prisma-specific types at
6
+ * their API boundary.
7
+ */
8
+ export class NotificationRepository extends BaseRepository {
9
+ constructor(db) {
10
+ super(db);
11
+ }
12
+ findFirst(args) {
13
+ return this.db.notification.findFirst(args);
14
+ }
15
+ listByUser(userId, args) {
16
+ return this.db.notification.findMany({
17
+ ...args,
18
+ where: { userId },
19
+ });
20
+ }
21
+ count(args) {
22
+ return this.db.notification.count(args);
23
+ }
24
+ create(data) {
25
+ return this.db.notification.create({ data });
26
+ }
27
+ markRead(id, userId) {
28
+ return this.db.notification.updateMany({
29
+ where: { id, userId },
30
+ data: { read: true },
31
+ });
32
+ }
33
+ markAllRead(userId) {
34
+ return this.db.notification.updateMany({
35
+ where: { userId, read: false },
36
+ data: { read: true },
37
+ });
38
+ }
39
+ delete(id, userId) {
40
+ return this.db.notification.deleteMany({
41
+ where: { id, userId },
42
+ });
43
+ }
44
+ }