@studious-lms/server 1.16.0 → 1.16.1

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 (151) hide show
  1. package/.github/workflows/deploy.yml +1 -1
  2. package/dist/instrument.js +3 -3
  3. package/dist/instrument.js.map +1 -1
  4. package/dist/lib/chatAttachmentPrompt.d.ts +47 -0
  5. package/dist/lib/chatAttachmentPrompt.d.ts.map +1 -0
  6. package/dist/lib/chatAttachmentPrompt.js +190 -0
  7. package/dist/lib/chatAttachmentPrompt.js.map +1 -0
  8. package/dist/lib/inferDocumentFormat.js +3 -3
  9. package/dist/lib/inferDocumentFormat.js.map +1 -1
  10. package/dist/lib/legal.d.ts +3 -0
  11. package/dist/lib/legal.d.ts.map +1 -0
  12. package/dist/lib/legal.js +6 -0
  13. package/dist/lib/legal.js.map +1 -0
  14. package/dist/models/announcement.d.ts +2 -0
  15. package/dist/models/announcement.d.ts.map +1 -1
  16. package/dist/models/auth.d.ts +8 -0
  17. package/dist/models/auth.d.ts.map +1 -1
  18. package/dist/models/auth.js +4 -2
  19. package/dist/models/auth.js.map +1 -1
  20. package/dist/models/event.d.ts +2 -0
  21. package/dist/models/event.d.ts.map +1 -1
  22. package/dist/models/file.d.ts +24 -0
  23. package/dist/models/file.d.ts.map +1 -1
  24. package/dist/models/marketing.d.ts +2 -15
  25. package/dist/models/marketing.d.ts.map +1 -1
  26. package/dist/models/marketing.js +12 -4
  27. package/dist/models/marketing.js.map +1 -1
  28. package/dist/pipelines/aiLabChat.d.ts.map +1 -1
  29. package/dist/pipelines/aiLabChat.js +39 -59
  30. package/dist/pipelines/aiLabChat.js.map +1 -1
  31. package/dist/pipelines/aiLabChatContract.d.ts +2 -2
  32. package/dist/pipelines/aiNewtonChat.d.ts +1 -1
  33. package/dist/pipelines/aiNewtonChat.d.ts.map +1 -1
  34. package/dist/pipelines/aiNewtonChat.js +20 -19
  35. package/dist/pipelines/aiNewtonChat.js.map +1 -1
  36. package/dist/pipelines/gradeWorksheet.d.ts +1 -0
  37. package/dist/pipelines/gradeWorksheet.d.ts.map +1 -1
  38. package/dist/pipelines/gradeWorksheet.js +84 -13
  39. package/dist/pipelines/gradeWorksheet.js.map +1 -1
  40. package/dist/pipelines/labChatPrompt.d.ts +4 -20
  41. package/dist/pipelines/labChatPrompt.d.ts.map +1 -1
  42. package/dist/pipelines/labChatPrompt.js +24 -64
  43. package/dist/pipelines/labChatPrompt.js.map +1 -1
  44. package/dist/routers/_app.d.ts +236 -26
  45. package/dist/routers/_app.d.ts.map +1 -1
  46. package/dist/routers/assignment.d.ts +10 -0
  47. package/dist/routers/assignment.d.ts.map +1 -1
  48. package/dist/routers/auth.d.ts +2 -0
  49. package/dist/routers/auth.d.ts.map +1 -1
  50. package/dist/routers/auth.js +15 -2
  51. package/dist/routers/auth.js.map +1 -1
  52. package/dist/routers/class.d.ts +4 -0
  53. package/dist/routers/class.d.ts.map +1 -1
  54. package/dist/routers/event.d.ts +2 -0
  55. package/dist/routers/event.d.ts.map +1 -1
  56. package/dist/routers/marketing.d.ts +0 -13
  57. package/dist/routers/marketing.d.ts.map +1 -1
  58. package/dist/routers/school.d.ts +4 -0
  59. package/dist/routers/school.d.ts.map +1 -1
  60. package/dist/routers/user.d.ts +89 -0
  61. package/dist/routers/user.d.ts.map +1 -1
  62. package/dist/routers/user.js +19 -2
  63. package/dist/routers/user.js.map +1 -1
  64. package/dist/routers/worksheet.d.ts +7 -0
  65. package/dist/routers/worksheet.d.ts.map +1 -1
  66. package/dist/routers/worksheet.js +8 -3
  67. package/dist/routers/worksheet.js.map +1 -1
  68. package/dist/seedDatabase.d.ts +2 -0
  69. package/dist/seedDatabase.d.ts.map +1 -1
  70. package/dist/services/aiChatStream.d.ts +2 -0
  71. package/dist/services/aiChatStream.d.ts.map +1 -1
  72. package/dist/services/aiChatStream.js +31 -4
  73. package/dist/services/aiChatStream.js.map +1 -1
  74. package/dist/services/aiProposalTools.d.ts.map +1 -1
  75. package/dist/services/aiProposalTools.js +9 -9
  76. package/dist/services/aiProposalTools.js.map +1 -1
  77. package/dist/services/aiTools.js +3 -3
  78. package/dist/services/aiTools.js.map +1 -1
  79. package/dist/services/assignment.d.ts +10 -0
  80. package/dist/services/assignment.d.ts.map +1 -1
  81. package/dist/services/auth.d.ts +2 -0
  82. package/dist/services/auth.d.ts.map +1 -1
  83. package/dist/services/auth.js +13 -4
  84. package/dist/services/auth.js.map +1 -1
  85. package/dist/services/class.d.ts +4 -0
  86. package/dist/services/class.d.ts.map +1 -1
  87. package/dist/services/event.d.ts +2 -0
  88. package/dist/services/event.d.ts.map +1 -1
  89. package/dist/services/marketing.d.ts +1 -14
  90. package/dist/services/marketing.d.ts.map +1 -1
  91. package/dist/services/marketing.js +5 -5
  92. package/dist/services/marketing.js.map +1 -1
  93. package/dist/services/newtonChat.d.ts.map +1 -1
  94. package/dist/services/newtonChat.js +2 -8
  95. package/dist/services/newtonChat.js.map +1 -1
  96. package/dist/services/openaiDocumentGen.d.ts +12 -0
  97. package/dist/services/openaiDocumentGen.d.ts.map +1 -1
  98. package/dist/services/openaiDocumentGen.js +173 -65
  99. package/dist/services/openaiDocumentGen.js.map +1 -1
  100. package/dist/services/school.d.ts +4 -0
  101. package/dist/services/school.d.ts.map +1 -1
  102. package/dist/services/userPrivacy.d.ts +86 -0
  103. package/dist/services/userPrivacy.d.ts.map +1 -0
  104. package/dist/services/userPrivacy.js +184 -0
  105. package/dist/services/userPrivacy.js.map +1 -0
  106. package/dist/services/worksheet.d.ts +1 -0
  107. package/dist/services/worksheet.d.ts.map +1 -1
  108. package/dist/services/worksheet.js +13 -3
  109. package/dist/services/worksheet.js.map +1 -1
  110. package/dist/utils/email.d.ts.map +1 -1
  111. package/dist/utils/email.js +7 -3
  112. package/dist/utils/email.js.map +1 -1
  113. package/dist/workers/processors/aiNewtonChat.d.ts.map +1 -1
  114. package/dist/workers/processors/aiNewtonChat.js +3 -3
  115. package/dist/workers/processors/aiNewtonChat.js.map +1 -1
  116. package/package.json +2 -1
  117. package/prisma/migrations/20260611120000_add_user_terms_acceptance/migration.sql +3 -0
  118. package/prisma/schema.prisma +3 -0
  119. package/src/instrument.ts +1 -1
  120. package/src/lib/chatAttachmentPrompt.ts +270 -0
  121. package/src/lib/inferDocumentFormat.ts +1 -1
  122. package/src/lib/legal.ts +2 -0
  123. package/src/models/auth.ts +4 -0
  124. package/src/models/marketing.ts +10 -2
  125. package/src/pipelines/aiLabChat.ts +46 -71
  126. package/src/pipelines/aiNewtonChat.ts +20 -23
  127. package/src/pipelines/gradeWorksheet.ts +87 -11
  128. package/src/pipelines/labChatPrompt.ts +29 -98
  129. package/src/routers/auth.ts +13 -0
  130. package/src/routers/user.ts +26 -0
  131. package/src/routers/worksheet.ts +11 -0
  132. package/src/services/aiChatStream.ts +30 -3
  133. package/src/services/aiProposalTools.ts +8 -7
  134. package/src/services/aiTools.ts +1 -1
  135. package/src/services/auth.ts +14 -2
  136. package/src/services/marketing.ts +3 -3
  137. package/src/services/newtonChat.ts +0 -7
  138. package/src/services/openaiDocumentGen.ts +190 -66
  139. package/src/services/userPrivacy.ts +196 -0
  140. package/src/services/worksheet.ts +20 -1
  141. package/src/utils/email.ts +5 -1
  142. package/src/workers/processors/aiNewtonChat.ts +0 -1
  143. package/tests/helpers/registerInput.ts +20 -0
  144. package/tests/integration/globalSetup.ts +10 -18
  145. package/tests/integration/routers/auth.test.ts +13 -18
  146. package/tests/integration/routers/newtonChat.test.ts +9 -8
  147. package/tests/unit/lib/chatAttachmentPrompt.test.ts +135 -0
  148. package/tests/unit/lib/inferDocumentFormat.test.ts +10 -0
  149. package/tests/unit/pipelines/labChatPrompt.test.ts +6 -6
  150. package/tests/unit/services/aiChatStream.test.ts +92 -0
  151. package/tests/unit/services/openaiDocumentGen.test.ts +65 -0
@@ -698,6 +698,8 @@ export declare function updateAssignmentRecord(userId: string, input: {
698
698
  email: string;
699
699
  password: string;
700
700
  verified: boolean;
701
+ termsAcceptedAt: Date | null;
702
+ termsVersion: string | null;
701
703
  schoolId: string | null;
702
704
  };
703
705
  }>;
@@ -1194,6 +1196,8 @@ export declare function attachMarkSchemeRecord(teacherId: string, assignmentId:
1194
1196
  email: string;
1195
1197
  password: string;
1196
1198
  verified: boolean;
1199
+ termsAcceptedAt: Date | null;
1200
+ termsVersion: string | null;
1197
1201
  schoolId: string | null;
1198
1202
  };
1199
1203
  eventAttached: {
@@ -1284,6 +1288,8 @@ export declare function detachMarkSchemeRecord(teacherId: string, assignmentId:
1284
1288
  email: string;
1285
1289
  password: string;
1286
1290
  verified: boolean;
1291
+ termsAcceptedAt: Date | null;
1292
+ termsVersion: string | null;
1287
1293
  schoolId: string | null;
1288
1294
  };
1289
1295
  eventAttached: {
@@ -1374,6 +1380,8 @@ export declare function attachGradingBoundaryRecord(teacherId: string, assignmen
1374
1380
  email: string;
1375
1381
  password: string;
1376
1382
  verified: boolean;
1383
+ termsAcceptedAt: Date | null;
1384
+ termsVersion: string | null;
1377
1385
  schoolId: string | null;
1378
1386
  };
1379
1387
  eventAttached: {
@@ -1464,6 +1472,8 @@ export declare function detachGradingBoundaryRecord(teacherId: string, assignmen
1464
1472
  email: string;
1465
1473
  password: string;
1466
1474
  verified: boolean;
1475
+ termsAcceptedAt: Date | null;
1476
+ termsVersion: string | null;
1467
1477
  schoolId: string | null;
1468
1478
  };
1469
1479
  eventAttached: {
@@ -1 +1 @@
1
- {"version":3,"file":"assignment.d.ts","sourceRoot":"/","sources":["services/assignment.ts"],"names":[],"mappings":"AA+BA,wBAAsB,gBAAgB,CAAC,EAAE,EAAE,MAAM,oBAGhD;AAED,wBAAsB,WAAW;;;;;;;;;;;KAMhC;AAED,wBAAsB,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAU/D;AAED,wBAAsB,aAAa,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAa1E;AAED,wBAAsB,iBAAiB,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAY5F;AAED,wBAAsB,cAAc,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAM3E;AAED,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,MAAM,EACd,KAAK,EAAE;IACL,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACvD,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;;;;;;;;;;;;;;;;;;;;;;;;;;GAiNF;AAED;;;GAGG;AACH,wBAAsB,yBAAyB,CAC7C,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;GAmCf;AAED,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,MAAM,EACd,KAAK,EAAE;IACL,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACvD,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwNF;AAED,wBAAsB,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;;GAsCxF;AAED,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,MAAM,EACd,KAAK,EAAE;IACL,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,cAAc,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAChE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC/B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8IF;AA2BD,wBAAsB,+BAA+B,CACnD,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE;IACL,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,cAAc,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAChE,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,YAAY,CAAC,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACnG,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6FF;AAED,wBAAsB,6BAA6B,CACjD,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BhB;AAED,wBAAsB,+BAA+B,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAW5F;AAED,wBAAsB,+BAA+B,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM;;;;;;;;;;GAW5F;AAED,wBAAsB,sBAAsB,CAC1C,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,MAAM,GAAG,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqC5B;AAED,wBAAsB,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoBnF;AAED,wBAAsB,2BAA2B,CAC/C,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,iBAAiB,EAAE,MAAM,GAAG,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCjC;AAED,wBAAsB,2BAA2B,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoBxF;AAiED,wBAAsB,uBAAuB,CAC3C,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE;IACL,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,CAAC;IAC/C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;;;;;;;;;;;;;;;;;;;;;;;;;UA4EF;AAED,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE;IACL,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;;;;;;;;;;;;;;;;;;;;;;;;;UAmCF"}
1
+ {"version":3,"file":"assignment.d.ts","sourceRoot":"/","sources":["services/assignment.ts"],"names":[],"mappings":"AA+BA,wBAAsB,gBAAgB,CAAC,EAAE,EAAE,MAAM,oBAGhD;AAED,wBAAsB,WAAW;;;;;;;;;;;KAMhC;AAED,wBAAsB,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAU/D;AAED,wBAAsB,aAAa,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAa1E;AAED,wBAAsB,iBAAiB,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAY5F;AAED,wBAAsB,cAAc,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAM3E;AAED,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,MAAM,EACd,KAAK,EAAE;IACL,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACvD,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;;;;;;;;;;;;;;;;;;;;;;;;;;GAiNF;AAED;;;GAGG;AACH,wBAAsB,yBAAyB,CAC7C,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;GAmCf;AAED,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,MAAM,EACd,KAAK,EAAE;IACL,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACvD,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwNF;AAED,wBAAsB,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;;GAsCxF;AAED,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,MAAM,EACd,KAAK,EAAE;IACL,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,cAAc,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAChE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC/B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8IF;AA2BD,wBAAsB,+BAA+B,CACnD,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE;IACL,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,cAAc,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAChE,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,YAAY,CAAC,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACnG,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6FF;AAED,wBAAsB,6BAA6B,CACjD,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BhB;AAED,wBAAsB,+BAA+B,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAW5F;AAED,wBAAsB,+BAA+B,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM;;;;;;;;;;GAW5F;AAED,wBAAsB,sBAAsB,CAC1C,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,MAAM,GAAG,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqC5B;AAED,wBAAsB,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoBnF;AAED,wBAAsB,2BAA2B,CAC/C,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,iBAAiB,EAAE,MAAM,GAAG,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCjC;AAED,wBAAsB,2BAA2B,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoBxF;AAiED,wBAAsB,uBAAuB,CAC3C,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE;IACL,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,CAAC;IAC/C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;;;;;;;;;;;;;;;;;;;;;;;;;UA4EF;AAED,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE;IACL,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;;;;;;;;;;;;;;;;;;;;;;;;;UAmCF"}
@@ -3,6 +3,8 @@ export declare function register(input: {
3
3
  username: string;
4
4
  email: string;
5
5
  password: string;
6
+ agreeToTerms: true;
7
+ termsVersion: string;
6
8
  }): Promise<{
7
9
  user: {
8
10
  id: string;
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"/","sources":["services/auth.ts"],"names":[],"mappings":"AA6BA,qFAAqF;AACrF,wBAAsB,QAAQ,CAAC,KAAK,EAAE;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;;;;;GAqEA;AAED,8DAA8D;AAC9D,wBAAsB,KAAK,CAAC,KAAK,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE;;;;;;;;;;;;;;;;GAoCxE;AAED,iEAAiE;AACjE,wBAAsB,MAAM,CAAC,MAAM,EAAE,MAAM;;GAG1C;AAED,0EAA0E;AAC1E,wBAAsB,KAAK,CAAC,MAAM,EAAE,MAAM;;;;;;;;;;;;;;GASzC;AAED,gFAAgF;AAChF,wBAAsB,uBAAuB,CAAC,KAAK,EAAE,MAAM;;GAiC1D;AAED,8EAA8E;AAC9E,wBAAsB,MAAM,CAAC,KAAK,EAAE,MAAM;;GA+BzC;AAED,kFAAkF;AAClF,wBAAsB,oBAAoB,CAAC,KAAK,EAAE,MAAM;;GA+BvD;AAED,mFAAmF;AACnF,wBAAsB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;;GAuBlE"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"/","sources":["services/auth.ts"],"names":[],"mappings":"AA8BA,qFAAqF;AACrF,wBAAsB,QAAQ,CAAC,KAAK,EAAE;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,IAAI,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB;;;;;GA8EA;AAED,8DAA8D;AAC9D,wBAAsB,KAAK,CAAC,KAAK,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE;;;;;;;;;;;;;;;;GAoCxE;AAED,iEAAiE;AACjE,wBAAsB,MAAM,CAAC,MAAM,EAAE,MAAM;;GAG1C;AAED,0EAA0E;AAC1E,wBAAsB,KAAK,CAAC,MAAM,EAAE,MAAM;;;;;;;;;;;;;;GASzC;AAED,gFAAgF;AAChF,wBAAsB,uBAAuB,CAAC,KAAK,EAAE,MAAM;;GAiC1D;AAED,8EAA8E;AAC9E,wBAAsB,MAAM,CAAC,KAAK,EAAE,MAAM;;GA+BzC;AAED,kFAAkF;AAClF,wBAAsB,oBAAoB,CAAC,KAAK,EAAE,MAAM;;GA+BvD;AAED,mFAAmF;AACnF,wBAAsB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;;GAuBlE"}
@@ -3,7 +3,7 @@
3
3
  * Handles session creation, Redis caching, and email notifications.
4
4
  */
5
5
 
6
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="7c41f210-458c-593a-8fe2-a8ecbc675245")}catch(e){}}();
6
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="d8981916-8875-5f33-b907-7e722e9a3ce9")}catch(e){}}();
7
7
  import { SessionType } from "@prisma/client";
8
8
  import { TRPCError } from "@trpc/server";
9
9
  import { v4 as uuidv4 } from "uuid";
@@ -12,10 +12,17 @@ import { sendMail } from "../utils/email.js";
12
12
  import { prismaWrapper } from "../utils/prismaWrapper.js";
13
13
  import { env } from "../lib/config/env.js";
14
14
  import { logger } from "../utils/logger.js";
15
+ import { CURRENT_TERMS_VERSION } from "../lib/legal.js";
15
16
  import { findUserByUsername, findUserByUsernameOrEmail, findUserByEmail, findUserById, createUser, createSession, deleteSessionsByUserId, deleteShortLivedSessionsByUserId, deleteUserById, findSessionByIdAndType, findSessionByIdWithUserAndType, updateUserVerified, updateUserPassword, deleteSessionById, } from "../models/auth.js";
16
17
  /** Register a new user, create verification session, and send verification email. */
17
18
  export async function register(input) {
18
- const { username, email, password } = input;
19
+ const { username, email, password, termsVersion } = input;
20
+ if (termsVersion !== CURRENT_TERMS_VERSION) {
21
+ throw new TRPCError({
22
+ code: "BAD_REQUEST",
23
+ message: "Please accept the current Terms of Service and Privacy Policy.",
24
+ });
25
+ }
19
26
  const existingUser = await prismaWrapper.findFirst(() => findUserByUsernameOrEmail(username, email), "checking for existing user during registration");
20
27
  if (existingUser && existingUser.verified) {
21
28
  if (existingUser.username === username) {
@@ -39,7 +46,9 @@ export async function register(input) {
39
46
  username,
40
47
  email,
41
48
  password: await hash(password, 10),
42
- verified: true,
49
+ verified: false,
50
+ termsAcceptedAt: new Date(),
51
+ termsVersion,
43
52
  }), "creating new user during registration");
44
53
  const verificationToken = await prismaWrapper.create(() => createSession({
45
54
  id: uuidv4(),
@@ -222,4 +231,4 @@ export async function resetPassword(token, password) {
222
231
  return { success: true };
223
232
  }
224
233
  //# sourceMappingURL=auth.js.map
225
- //# debugId=7c41f210-458c-593a-8fe2-a8ecbc675245
234
+ //# debugId=d8981916-8875-5f33-b907-7e722e9a3ce9
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sources":["services/auth.ts"],"sourceRoot":"/","sourcesContent":["/**\n * Auth service – user registration, login, logout, verification, and password reset.\n * Handles session creation, Redis caching, and email notifications.\n */\nimport { SessionType } from \"@prisma/client\";\nimport { TRPCError } from \"@trpc/server\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport { compare, hash } from \"bcryptjs\";\nimport { sendMail } from \"../utils/email.js\";\nimport { prismaWrapper } from \"../utils/prismaWrapper.js\";\nimport { env } from \"../lib/config/env.js\";\nimport { logger } from \"../utils/logger.js\";\nimport {\n findUserByUsername,\n findUserByUsernameOrEmail,\n findUserByEmail,\n findUserById,\n createUser,\n createSession,\n deleteSessionsByUserId,\n deleteShortLivedSessionsByUserId,\n deleteUserById,\n findSessionByIdAndType,\n findSessionByIdWithUserAndType,\n updateUserVerified,\n updateUserPassword,\n deleteSessionById,\n} from \"../models/auth.js\";\n\n/** Register a new user, create verification session, and send verification email. */\nexport async function register(input: {\n username: string;\n email: string;\n password: string;\n}) {\n const { username, email, password } = input;\n\n const existingUser = await prismaWrapper.findFirst(\n () => findUserByUsernameOrEmail(username, email),\n \"checking for existing user during registration\"\n );\n\n if (existingUser && existingUser.verified) {\n if (existingUser.username === username) {\n throw new TRPCError({\n code: \"CONFLICT\",\n message: \"Username already exists\",\n });\n }\n if (existingUser.email === email) {\n throw new TRPCError({\n code: \"CONFLICT\",\n message: \"Email already exists\",\n });\n }\n } else if (existingUser && !existingUser.verified) {\n await prismaWrapper.deleteMany(\n () => deleteSessionsByUserId(existingUser.id),\n \"deleting existing sessions for unverified user\"\n );\n await prismaWrapper.delete(\n () => deleteUserById(existingUser.id),\n \"deleting unverified user\"\n );\n }\n\n const user = await prismaWrapper.create(\n async () =>\n createUser({\n username,\n email,\n password: await hash(password, 10),\n verified: true,\n }),\n \"creating new user during registration\"\n );\n\n const verificationToken = await prismaWrapper.create(\n () =>\n createSession({\n id: uuidv4(),\n type: SessionType.EMAIL_VERIFICATION,\n userId: user.id,\n expiresAt: new Date(Date.now() + 1000 * 60 * 60 * 24 * 30),\n }),\n \"creating verification token\"\n );\n\n try {\n await sendMail({\n from: \"hello@studious.sh\",\n to: user.email,\n subject: \"Verify your email\",\n text: `Click the link to verify your email: ${env.NEXT_PUBLIC_APP_URL}/verify/${verificationToken.id}`,\n });\n } catch (err) {\n logger.error(\"Failed to send verification email\", {\n email: user.email,\n err,\n });\n }\n\n return { user: { id: user.id, username: user.username } };\n}\n\n/** Authenticate user by username/password, create session. */\nexport async function login(input: { username: string; password: string }) {\n const { username, password } = input;\n\n const user = await findUserByUsername(username);\n if (!user) {\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"Invalid username or password\",\n });\n }\n\n if (!(await compare(password, user.password))) {\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"Invalid username or password\",\n });\n }\n\n if (!user.verified) {\n return {\n verified: false,\n user: { email: user.email },\n };\n }\n\n const session = await createSession({\n id: uuidv4(),\n type: SessionType.AUTH,\n userId: user.id,\n expiresAt: new Date(Date.now() + 1000 * 60 * 60 * 24 * 30),\n });\n\n return {\n token: session.id,\n user: { id: user.id, username: user.username },\n };\n}\n\n/** Delete all sessions for a user (logs them out everywhere). */\nexport async function logout(userId: string) {\n await deleteSessionsByUserId(userId);\n return { success: true };\n}\n\n/** Verify user exists and return profile. Used for session validation. */\nexport async function check(userId: string) {\n const user = await findUserById(userId);\n if (!user) {\n throw new TRPCError({\n code: \"NOT_FOUND\",\n message: \"User not found\",\n });\n }\n return { user };\n}\n\n/** Resend verification email. Replaces existing sessions and sends new link. */\nexport async function resendVerificationEmail(email: string) {\n const user = await findUserByEmail(email);\n if (!user) {\n throw new TRPCError({\n code: \"NOT_FOUND\",\n message: \"User not found\",\n });\n }\n\n await deleteSessionsByUserId(user.id);\n\n const verificationToken = await createSession({\n id: uuidv4(),\n type: SessionType.EMAIL_VERIFICATION,\n userId: user.id,\n expiresAt: new Date(Date.now() + 1000 * 60 * 60 * 24 * 30),\n });\n\n try {\n await sendMail({\n from: \"hello@studious.sh\",\n to: user.email,\n subject: \"Verify your email\",\n text: `Click the link to verify your email: ${env.NEXT_PUBLIC_APP_URL}/verify/${verificationToken.id}`,\n });\n } catch (err) {\n logger.error(\"Failed to send verification email\", {\n email: user.email,\n err,\n });\n }\n\n return { success: true };\n}\n\n/** Verify email via token. Marks user as verified and deletes the session. */\nexport async function verify(token: string) {\n const session = await findSessionByIdAndType(\n token,\n SessionType.EMAIL_VERIFICATION\n );\n if (!session) {\n throw new TRPCError({\n code: \"NOT_FOUND\",\n message: \"Session not found\",\n });\n }\n\n if (session.expiresAt && session.expiresAt < new Date()) {\n await deleteSessionById(token);\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"Session expired\",\n });\n }\n\n if (!session.userId) {\n await deleteSessionById(token);\n throw new TRPCError({\n code: \"BAD_REQUEST\",\n message: \"Invalid session state\",\n });\n }\n\n await updateUserVerified(session.userId, true);\n await deleteSessionById(token);\n return { success: true };\n}\n\n/** Send password reset email. Silently succeeds if email not found (security). */\nexport async function requestPasswordReset(email: string) {\n const user = await findUserByEmail(email);\n if (!user) {\n return { success: true };\n }\n\n const twoHoursFromNow = new Date(Date.now() + 1000 * 60 * 60 * 2);\n await deleteShortLivedSessionsByUserId(user.id, twoHoursFromNow);\n\n const resetToken = await createSession({\n id: uuidv4(),\n type: SessionType.PASSWORD_RESET,\n userId: user.id,\n expiresAt: new Date(Date.now() + 1000 * 60 * 60),\n });\n\n try {\n await sendMail({\n from: \"hello@studious.sh\",\n to: user.email,\n subject: \"Reset your password\",\n text: `Click the link to reset your password: ${env.NEXT_PUBLIC_APP_URL}/reset-password/${resetToken.id}`,\n });\n } catch (err) {\n logger.error(\"Failed to send password reset email\", {\n email: user.email,\n err,\n });\n }\n\n return { success: true };\n}\n\n/** Reset password using token from email. Validates token and updates password. */\nexport async function resetPassword(token: string, password: string) {\n const session = await findSessionByIdWithUserAndType(\n token,\n SessionType.PASSWORD_RESET\n );\n if (!session || !session.userId) {\n throw new TRPCError({\n code: \"NOT_FOUND\",\n message: \"Invalid or expired reset token\",\n });\n }\n\n if (session.expiresAt && session.expiresAt < new Date()) {\n await deleteSessionById(token);\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"Reset token has expired\",\n });\n }\n\n await updateUserPassword(session.userId, await hash(password, 10));\n await deleteSessionById(token);\n return { success: true };\n}\n"],"names":[],"mappings":"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","debug_id":"7c41f210-458c-593a-8fe2-a8ecbc675245"}
1
+ {"version":3,"file":"auth.js","sources":["services/auth.ts"],"sourceRoot":"/","sourcesContent":["/**\n * Auth service – user registration, login, logout, verification, and password reset.\n * Handles session creation, Redis caching, and email notifications.\n */\nimport { SessionType } from \"@prisma/client\";\nimport { TRPCError } from \"@trpc/server\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport { compare, hash } from \"bcryptjs\";\nimport { sendMail } from \"../utils/email.js\";\nimport { prismaWrapper } from \"../utils/prismaWrapper.js\";\nimport { env } from \"../lib/config/env.js\";\nimport { logger } from \"../utils/logger.js\";\nimport { CURRENT_TERMS_VERSION } from \"../lib/legal.js\";\nimport {\n findUserByUsername,\n findUserByUsernameOrEmail,\n findUserByEmail,\n findUserById,\n createUser,\n createSession,\n deleteSessionsByUserId,\n deleteShortLivedSessionsByUserId,\n deleteUserById,\n findSessionByIdAndType,\n findSessionByIdWithUserAndType,\n updateUserVerified,\n updateUserPassword,\n deleteSessionById,\n} from \"../models/auth.js\";\n\n/** Register a new user, create verification session, and send verification email. */\nexport async function register(input: {\n username: string;\n email: string;\n password: string;\n agreeToTerms: true;\n termsVersion: string;\n}) {\n const { username, email, password, termsVersion } = input;\n\n if (termsVersion !== CURRENT_TERMS_VERSION) {\n throw new TRPCError({\n code: \"BAD_REQUEST\",\n message: \"Please accept the current Terms of Service and Privacy Policy.\",\n });\n }\n\n const existingUser = await prismaWrapper.findFirst(\n () => findUserByUsernameOrEmail(username, email),\n \"checking for existing user during registration\"\n );\n\n if (existingUser && existingUser.verified) {\n if (existingUser.username === username) {\n throw new TRPCError({\n code: \"CONFLICT\",\n message: \"Username already exists\",\n });\n }\n if (existingUser.email === email) {\n throw new TRPCError({\n code: \"CONFLICT\",\n message: \"Email already exists\",\n });\n }\n } else if (existingUser && !existingUser.verified) {\n await prismaWrapper.deleteMany(\n () => deleteSessionsByUserId(existingUser.id),\n \"deleting existing sessions for unverified user\"\n );\n await prismaWrapper.delete(\n () => deleteUserById(existingUser.id),\n \"deleting unverified user\"\n );\n }\n\n const user = await prismaWrapper.create(\n async () =>\n createUser({\n username,\n email,\n password: await hash(password, 10),\n verified: false,\n termsAcceptedAt: new Date(),\n termsVersion,\n }),\n \"creating new user during registration\"\n );\n\n const verificationToken = await prismaWrapper.create(\n () =>\n createSession({\n id: uuidv4(),\n type: SessionType.EMAIL_VERIFICATION,\n userId: user.id,\n expiresAt: new Date(Date.now() + 1000 * 60 * 60 * 24 * 30),\n }),\n \"creating verification token\"\n );\n\n try {\n await sendMail({\n from: \"hello@studious.sh\",\n to: user.email,\n subject: \"Verify your email\",\n text: `Click the link to verify your email: ${env.NEXT_PUBLIC_APP_URL}/verify/${verificationToken.id}`,\n });\n } catch (err) {\n logger.error(\"Failed to send verification email\", {\n email: user.email,\n err,\n });\n }\n\n return { user: { id: user.id, username: user.username } };\n}\n\n/** Authenticate user by username/password, create session. */\nexport async function login(input: { username: string; password: string }) {\n const { username, password } = input;\n\n const user = await findUserByUsername(username);\n if (!user) {\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"Invalid username or password\",\n });\n }\n\n if (!(await compare(password, user.password))) {\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"Invalid username or password\",\n });\n }\n\n if (!user.verified) {\n return {\n verified: false,\n user: { email: user.email },\n };\n }\n\n const session = await createSession({\n id: uuidv4(),\n type: SessionType.AUTH,\n userId: user.id,\n expiresAt: new Date(Date.now() + 1000 * 60 * 60 * 24 * 30),\n });\n\n return {\n token: session.id,\n user: { id: user.id, username: user.username },\n };\n}\n\n/** Delete all sessions for a user (logs them out everywhere). */\nexport async function logout(userId: string) {\n await deleteSessionsByUserId(userId);\n return { success: true };\n}\n\n/** Verify user exists and return profile. Used for session validation. */\nexport async function check(userId: string) {\n const user = await findUserById(userId);\n if (!user) {\n throw new TRPCError({\n code: \"NOT_FOUND\",\n message: \"User not found\",\n });\n }\n return { user };\n}\n\n/** Resend verification email. Replaces existing sessions and sends new link. */\nexport async function resendVerificationEmail(email: string) {\n const user = await findUserByEmail(email);\n if (!user) {\n throw new TRPCError({\n code: \"NOT_FOUND\",\n message: \"User not found\",\n });\n }\n\n await deleteSessionsByUserId(user.id);\n\n const verificationToken = await createSession({\n id: uuidv4(),\n type: SessionType.EMAIL_VERIFICATION,\n userId: user.id,\n expiresAt: new Date(Date.now() + 1000 * 60 * 60 * 24 * 30),\n });\n\n try {\n await sendMail({\n from: \"hello@studious.sh\",\n to: user.email,\n subject: \"Verify your email\",\n text: `Click the link to verify your email: ${env.NEXT_PUBLIC_APP_URL}/verify/${verificationToken.id}`,\n });\n } catch (err) {\n logger.error(\"Failed to send verification email\", {\n email: user.email,\n err,\n });\n }\n\n return { success: true };\n}\n\n/** Verify email via token. Marks user as verified and deletes the session. */\nexport async function verify(token: string) {\n const session = await findSessionByIdAndType(\n token,\n SessionType.EMAIL_VERIFICATION\n );\n if (!session) {\n throw new TRPCError({\n code: \"NOT_FOUND\",\n message: \"Session not found\",\n });\n }\n\n if (session.expiresAt && session.expiresAt < new Date()) {\n await deleteSessionById(token);\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"Session expired\",\n });\n }\n\n if (!session.userId) {\n await deleteSessionById(token);\n throw new TRPCError({\n code: \"BAD_REQUEST\",\n message: \"Invalid session state\",\n });\n }\n\n await updateUserVerified(session.userId, true);\n await deleteSessionById(token);\n return { success: true };\n}\n\n/** Send password reset email. Silently succeeds if email not found (security). */\nexport async function requestPasswordReset(email: string) {\n const user = await findUserByEmail(email);\n if (!user) {\n return { success: true };\n }\n\n const twoHoursFromNow = new Date(Date.now() + 1000 * 60 * 60 * 2);\n await deleteShortLivedSessionsByUserId(user.id, twoHoursFromNow);\n\n const resetToken = await createSession({\n id: uuidv4(),\n type: SessionType.PASSWORD_RESET,\n userId: user.id,\n expiresAt: new Date(Date.now() + 1000 * 60 * 60),\n });\n\n try {\n await sendMail({\n from: \"hello@studious.sh\",\n to: user.email,\n subject: \"Reset your password\",\n text: `Click the link to reset your password: ${env.NEXT_PUBLIC_APP_URL}/reset-password/${resetToken.id}`,\n });\n } catch (err) {\n logger.error(\"Failed to send password reset email\", {\n email: user.email,\n err,\n });\n }\n\n return { success: true };\n}\n\n/** Reset password using token from email. Validates token and updates password. */\nexport async function resetPassword(token: string, password: string) {\n const session = await findSessionByIdWithUserAndType(\n token,\n SessionType.PASSWORD_RESET\n );\n if (!session || !session.userId) {\n throw new TRPCError({\n code: \"NOT_FOUND\",\n message: \"Invalid or expired reset token\",\n });\n }\n\n if (session.expiresAt && session.expiresAt < new Date()) {\n await deleteSessionById(token);\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"Reset token has expired\",\n });\n }\n\n await updateUserPassword(session.userId, await hash(password, 10));\n await deleteSessionById(token);\n return { success: true };\n}\n"],"names":[],"mappings":"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","debug_id":"d8981916-8875-5f33-b907-7e722e9a3ce9"}
@@ -263,6 +263,8 @@ export declare function createClass(userId: string, input: {
263
263
  email: string;
264
264
  password: string;
265
265
  verified: boolean;
266
+ termsAcceptedAt: Date | null;
267
+ termsVersion: string | null;
266
268
  schoolId: string | null;
267
269
  }[];
268
270
  students: {
@@ -271,6 +273,8 @@ export declare function createClass(userId: string, input: {
271
273
  email: string;
272
274
  password: string;
273
275
  verified: boolean;
276
+ termsAcceptedAt: Date | null;
277
+ termsVersion: string | null;
274
278
  schoolId: string | null;
275
279
  }[];
276
280
  } & {
@@ -1 +1 @@
1
- {"version":3,"file":"class.d.ts","sourceRoot":"/","sources":["services/class.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"class.d.ts","sourceRoot":"/","sources":["services/class.ts"],"names":[],"mappings":"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"}
@@ -7,6 +7,8 @@ export declare function getEvent(userId: string, id: string): Promise<{
7
7
  email: string;
8
8
  password: string;
9
9
  verified: boolean;
10
+ termsAcceptedAt: Date | null;
11
+ termsVersion: string | null;
10
12
  schoolId: string | null;
11
13
  } | null;
12
14
  class: ({
@@ -1 +1 @@
1
- {"version":3,"file":"event.d.ts","sourceRoot":"/","sources":["services/event.ts"],"names":[],"mappings":"AAmBA,6DAA6D;AAC7D,wBAAsB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAexD;AAED,wCAAwC;AACxC,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE;IACL,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;;;;;;;;;;;;;;;;GAwBF;AAED,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,MAAM,EACd,EAAE,EAAE,MAAM,EACV,IAAI,EAAE;IACJ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;;;;;;;;;;;;GA2BF;AAED,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;;GAiBjE;AAuBD,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CrB;AAED,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkBrB;AAED,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;GAkBhB"}
1
+ {"version":3,"file":"event.d.ts","sourceRoot":"/","sources":["services/event.ts"],"names":[],"mappings":"AAmBA,6DAA6D;AAC7D,wBAAsB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAexD;AAED,wCAAwC;AACxC,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE;IACL,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;;;;;;;;;;;;;;;;GAwBF;AAED,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,MAAM,EACd,EAAE,EAAE,MAAM,EACV,IAAI,EAAE;IACJ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;;;;;;;;;;;;GA2BF;AAED,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;;GAiBjE;AAuBD,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CrB;AAED,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkBrB;AAED,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;GAkBhB"}
@@ -18,27 +18,14 @@ export declare function createSchoolDevelopmentProgramRecord(input: {
18
18
  }): Promise<{
19
19
  id: string;
20
20
  }>;
21
- /** Look up a school development program by ID. */
21
+ /** Public application status lookup (no contact PII). */
22
22
  export declare function searchSchoolDevelopmentPrograms(id: string): Promise<{
23
- type: string;
24
23
  status: string;
25
24
  id: string;
26
- website: string | null;
27
25
  name: string;
28
26
  submittedAt: Date | null;
29
- address: string;
30
27
  city: string;
31
28
  country: string;
32
- numberOfStudents: number;
33
- numberOfTeachers: number;
34
- contactName: string | null;
35
- contactRole: string | null;
36
- contactEmail: string | null;
37
- contactPhone: string | null;
38
- eligibilityInformation: string | null;
39
- whyHelp: string | null;
40
- additionalInformation: string | null;
41
- reviewedAt: Date | null;
42
29
  } | null>;
43
30
  /** Create an early access request. */
44
31
  export declare function createEarlyAccessRequestRecord(input: {
@@ -1 +1 @@
1
- {"version":3,"file":"marketing.d.ts","sourceRoot":"/","sources":["services/marketing.ts"],"names":[],"mappings":"AAUA,4EAA4E;AAC5E,wBAAsB,oCAAoC,CAAC,KAAK,EAAE;IAChE,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;;GAeA;AAED,kDAAkD;AAClD,wBAAsB,+BAA+B,CAAC,EAAE,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;UAE/D;AAED,sCAAsC;AACtC,wBAAsB,8BAA8B,CAAC,KAAK,EAAE;IAC1D,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;CACzB;;GAGA"}
1
+ {"version":3,"file":"marketing.d.ts","sourceRoot":"/","sources":["services/marketing.ts"],"names":[],"mappings":"AAUA,4EAA4E;AAC5E,wBAAsB,oCAAoC,CAAC,KAAK,EAAE;IAChE,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;;GAeA;AAED,yDAAyD;AACzD,wBAAsB,+BAA+B,CAAC,EAAE,EAAE,MAAM;;;;;;;UAE/D;AAED,sCAAsC;AACtC,wBAAsB,8BAA8B,CAAC,KAAK,EAAE;IAC1D,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;CACzB;;GAGA"}
@@ -2,9 +2,9 @@
2
2
  * Marketing service – school development programs and early access requests.
3
3
  */
4
4
 
5
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="a1e245e4-bd37-50ba-b330-218c8f3789ea")}catch(e){}}();
5
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="d5fcb374-2047-58b8-8257-6cca05559642")}catch(e){}}();
6
6
  import { v4 } from "uuid";
7
- import { createSchoolDevelopmentProgram, findSchoolDevelopmentProgramById, createEarlyAccessRequest, } from "../models/marketing.js";
7
+ import { createSchoolDevelopmentProgram, findSchoolDevelopmentProgramStatusById, createEarlyAccessRequest, } from "../models/marketing.js";
8
8
  /** Create a school development program application. Generates unique ID. */
9
9
  export async function createSchoolDevelopmentProgramRecord(input) {
10
10
  const date = new Date();
@@ -19,9 +19,9 @@ export async function createSchoolDevelopmentProgramRecord(input) {
19
19
  });
20
20
  return { id: program.id };
21
21
  }
22
- /** Look up a school development program by ID. */
22
+ /** Public application status lookup (no contact PII). */
23
23
  export async function searchSchoolDevelopmentPrograms(id) {
24
- return findSchoolDevelopmentProgramById(id);
24
+ return findSchoolDevelopmentProgramStatusById(id);
25
25
  }
26
26
  /** Create an early access request. */
27
27
  export async function createEarlyAccessRequestRecord(input) {
@@ -29,4 +29,4 @@ export async function createEarlyAccessRequestRecord(input) {
29
29
  return { id: record.id };
30
30
  }
31
31
  //# sourceMappingURL=marketing.js.map
32
- //# debugId=a1e245e4-bd37-50ba-b330-218c8f3789ea
32
+ //# debugId=d5fcb374-2047-58b8-8257-6cca05559642
@@ -1 +1 @@
1
- {"version":3,"file":"marketing.js","sources":["services/marketing.ts"],"sourceRoot":"/","sourcesContent":["/**\n * Marketing service – school development programs and early access requests.\n */\nimport { v4 } from \"uuid\";\nimport {\n createSchoolDevelopmentProgram,\n findSchoolDevelopmentProgramById,\n createEarlyAccessRequest,\n} from \"../models/marketing.js\";\n\n/** Create a school development program application. Generates unique ID. */\nexport async function createSchoolDevelopmentProgramRecord(input: {\n name: string;\n type: string;\n address: string;\n city: string;\n country: string;\n numberOfStudents: number;\n numberOfTeachers: number;\n website?: string;\n contactName?: string;\n contactRole?: string;\n contactEmail?: string;\n contactPhone?: string;\n eligibilityInformation?: string;\n whyHelp?: string;\n additionalInformation?: string;\n}) {\n const date = new Date();\n const id =\n input.name.slice(0, 3).toUpperCase() +\n \"-\" +\n date.getFullYear() +\n \"-\" +\n v4().slice(0, 4).toUpperCase();\n\n const program = await createSchoolDevelopmentProgram({\n id,\n ...input,\n });\n\n return { id: program.id };\n}\n\n/** Look up a school development program by ID. */\nexport async function searchSchoolDevelopmentPrograms(id: string) {\n return findSchoolDevelopmentProgramById(id);\n}\n\n/** Create an early access request. */\nexport async function createEarlyAccessRequestRecord(input: {\n email: string;\n institutionSize: string;\n}) {\n const record = await createEarlyAccessRequest(input);\n return { id: record.id };\n}\n"],"names":[],"mappings":"AAAA;;GAEG;;;AACH,OAAO,EAAE,EAAE,EAAE,MAAM,MAAM,CAAC;AAC1B,OAAO,EACL,8BAA8B,EAC9B,gCAAgC,EAChC,wBAAwB,GACzB,MAAM,wBAAwB,CAAC;AAEhC,4EAA4E;AAC5E,MAAM,CAAC,KAAK,UAAU,oCAAoC,CAAC,KAgB1D;IACC,MAAM,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;IACxB,MAAM,EAAE,GACN,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE;QACpC,GAAG;QACH,IAAI,CAAC,WAAW,EAAE;QAClB,GAAG;QACH,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IAEjC,MAAM,OAAO,GAAG,MAAM,8BAA8B,CAAC;QACnD,EAAE;QACF,GAAG,KAAK;KACT,CAAC,CAAC;IAEH,OAAO,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC;AAC5B,CAAC;AAED,kDAAkD;AAClD,MAAM,CAAC,KAAK,UAAU,+BAA+B,CAAC,EAAU;IAC9D,OAAO,gCAAgC,CAAC,EAAE,CAAC,CAAC;AAC9C,CAAC;AAED,sCAAsC;AACtC,MAAM,CAAC,KAAK,UAAU,8BAA8B,CAAC,KAGpD;IACC,MAAM,MAAM,GAAG,MAAM,wBAAwB,CAAC,KAAK,CAAC,CAAC;IACrD,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC;AAC3B,CAAC","debug_id":"a1e245e4-bd37-50ba-b330-218c8f3789ea"}
1
+ {"version":3,"file":"marketing.js","sources":["services/marketing.ts"],"sourceRoot":"/","sourcesContent":["/**\n * Marketing service – school development programs and early access requests.\n */\nimport { v4 } from \"uuid\";\nimport {\n createSchoolDevelopmentProgram,\n findSchoolDevelopmentProgramStatusById,\n createEarlyAccessRequest,\n} from \"../models/marketing.js\";\n\n/** Create a school development program application. Generates unique ID. */\nexport async function createSchoolDevelopmentProgramRecord(input: {\n name: string;\n type: string;\n address: string;\n city: string;\n country: string;\n numberOfStudents: number;\n numberOfTeachers: number;\n website?: string;\n contactName?: string;\n contactRole?: string;\n contactEmail?: string;\n contactPhone?: string;\n eligibilityInformation?: string;\n whyHelp?: string;\n additionalInformation?: string;\n}) {\n const date = new Date();\n const id =\n input.name.slice(0, 3).toUpperCase() +\n \"-\" +\n date.getFullYear() +\n \"-\" +\n v4().slice(0, 4).toUpperCase();\n\n const program = await createSchoolDevelopmentProgram({\n id,\n ...input,\n });\n\n return { id: program.id };\n}\n\n/** Public application status lookup (no contact PII). */\nexport async function searchSchoolDevelopmentPrograms(id: string) {\n return findSchoolDevelopmentProgramStatusById(id);\n}\n\n/** Create an early access request. */\nexport async function createEarlyAccessRequestRecord(input: {\n email: string;\n institutionSize: string;\n}) {\n const record = await createEarlyAccessRequest(input);\n return { id: record.id };\n}\n"],"names":[],"mappings":"AAAA;;GAEG;;;AACH,OAAO,EAAE,EAAE,EAAE,MAAM,MAAM,CAAC;AAC1B,OAAO,EACL,8BAA8B,EAC9B,sCAAsC,EACtC,wBAAwB,GACzB,MAAM,wBAAwB,CAAC;AAEhC,4EAA4E;AAC5E,MAAM,CAAC,KAAK,UAAU,oCAAoC,CAAC,KAgB1D;IACC,MAAM,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;IACxB,MAAM,EAAE,GACN,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE;QACpC,GAAG;QACH,IAAI,CAAC,WAAW,EAAE;QAClB,GAAG;QACH,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IAEjC,MAAM,OAAO,GAAG,MAAM,8BAA8B,CAAC;QACnD,EAAE;QACF,GAAG,KAAK;KACT,CAAC,CAAC;IAEH,OAAO,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC;AAC5B,CAAC;AAED,yDAAyD;AACzD,MAAM,CAAC,KAAK,UAAU,+BAA+B,CAAC,EAAU;IAC9D,OAAO,sCAAsC,CAAC,EAAE,CAAC,CAAC;AACpD,CAAC;AAED,sCAAsC;AACtC,MAAM,CAAC,KAAK,UAAU,8BAA8B,CAAC,KAGpD;IACC,MAAM,MAAM,GAAG,MAAM,wBAAwB,CAAC,KAAK,CAAC,CAAC;IACrD,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC;AAC3B,CAAC","debug_id":"d5fcb374-2047-58b8-8257-6cca05559642"}
@@ -1 +1 @@
1
- {"version":3,"file":"newtonChat.d.ts","sourceRoot":"/","sources":["services/newtonChat.ts"],"names":[],"mappings":"AAuBA,8EAA8E;AAC9E,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM;;;GAqGhB;AAED,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,EACf,gBAAgB,GAAE,MAAM,EAAO,EAC/B,OAAO,GAAE,MAAM,EAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0IvB"}
1
+ {"version":3,"file":"newtonChat.d.ts","sourceRoot":"/","sources":["services/newtonChat.ts"],"names":[],"mappings":"AAuBA,8EAA8E;AAC9E,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM;;;GAqGhB;AAED,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,EACf,gBAAgB,GAAE,MAAM,EAAO,EAC/B,OAAO,GAAE,MAAM,EAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmIvB"}
@@ -3,7 +3,7 @@
3
3
  * tutor session, post messages, trigger AI responses. Broadcasts via Pusher.
4
4
  */
5
5
 
6
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="0575644e-e077-5f74-8b0c-a6feb71814e9")}catch(e){}}();
6
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="39ab2fff-5212-508b-bb38-849fb5430153")}catch(e){}}();
7
7
  import { TRPCError } from "@trpc/server";
8
8
  import { logger } from "../utils/logger.js";
9
9
  import { chatChannel, pusher } from "../lib/pusher.js";
@@ -119,12 +119,6 @@ export async function postToNewtonChat(userId, newtonChatId, content, mentionedU
119
119
  }
120
120
  ensureMessageHasContentOrAttachments(content, fileIds);
121
121
  const normalizedContent = content.trim();
122
- if (!normalizedContent) {
123
- throw new TRPCError({
124
- code: "BAD_REQUEST",
125
- message: "Newton chat messages must include text content",
126
- });
127
- }
128
122
  const result = await prisma.$transaction(async (tx) => {
129
123
  const message = await tx.message.create({
130
124
  data: {
@@ -213,4 +207,4 @@ export async function postToNewtonChat(userId, newtonChatId, content, mentionedU
213
207
  };
214
208
  }
215
209
  //# sourceMappingURL=newtonChat.js.map
216
- //# debugId=0575644e-e077-5f74-8b0c-a6feb71814e9
210
+ //# debugId=39ab2fff-5212-508b-bb38-849fb5430153
@@ -1 +1 @@
1
- {"version":3,"file":"newtonChat.js","sources":["services/newtonChat.ts"],"sourceRoot":"/","sourcesContent":["/**\n * Newton chat service – AI tutor conversations for assignments. Get or create\n * tutor session, post messages, trigger AI responses. Broadcasts via Pusher.\n */\nimport { TRPCError } from \"@trpc/server\";\nimport { logger } from \"../utils/logger.js\";\nimport { chatChannel, pusher } from \"../lib/pusher.js\";\nimport { isAIUser } from \"../utils/aiUser.js\";\nimport { createPendingAIMessage } from \"../utils/inference.js\";\nimport { enqueueRunJob } from \"../workers/queues.js\";\nimport {\n claimMessageAttachments,\n ensureMessageHasContentOrAttachments,\n} from \"./message.js\";\nimport { messageFileSelect } from \"../models/message.js\";\nimport {\n findClassWithStudent,\n findSubmissionByAssignmentAndStudent,\n findNewtonChatByIdAndMember,\n findConversationMembersByUserIds,\n} from \"../models/newtonChat.js\";\nimport { prisma } from \"../lib/prisma.js\";\n\n/** Get or create Newton tutor conversation for a submission. Student-only. */\nexport async function getTutorConversation(\n userId: string,\n assignmentId: string,\n classId: string\n) {\n const classMembership = await findClassWithStudent(classId, userId);\n if (!classMembership) {\n throw new TRPCError({\n code: \"FORBIDDEN\",\n message: \"Not a student in this class\",\n });\n }\n\n const submission = await findSubmissionByAssignmentAndStudent(\n assignmentId,\n userId\n );\n if (!submission) {\n throw new TRPCError({\n code: \"NOT_FOUND\",\n message: \"Submission not found. Please create a submission first.\",\n });\n }\n\n const { chat, isNew } = await prisma.$transaction(async (tx) => {\n const existingNewtonChat = await tx.newtonChat.findFirst({\n where: { submissionId: submission.id },\n include: {\n conversation: {\n include: {\n members: {\n where: { userId },\n },\n },\n },\n },\n orderBy: { createdAt: \"desc\" },\n });\n\n if (existingNewtonChat && existingNewtonChat.conversation.members.length > 0) {\n return { chat: existingNewtonChat, isNew: false };\n }\n\n if (existingNewtonChat) {\n await tx.conversationMember.create({\n data: {\n userId,\n conversationId: existingNewtonChat.conversationId,\n role: \"MEMBER\",\n },\n });\n return { chat: existingNewtonChat, isNew: false };\n }\n\n const conversation = await tx.conversation.create({\n data: {\n type: \"DM\",\n name: \"Session with Newton Tutor\",\n displayInChat: false,\n },\n });\n\n await tx.conversationMember.create({\n data: {\n userId,\n conversationId: conversation.id,\n role: \"MEMBER\",\n },\n });\n\n const newtonChat = await tx.newtonChat.create({\n data: {\n submissionId: submission.id,\n conversationId: conversation.id,\n title: \"Session with Newton Tutor\",\n },\n });\n\n return { chat: newtonChat, isNew: true };\n });\n\n if (isNew) {\n // Create the AI introduction placeholder and enqueue OUTSIDE the\n // transaction — a tx rollback would otherwise orphan a job pointing at\n // a non-existent NewtonChat / Message row.\n try {\n const aiPlaceholder = await createPendingAIMessage(chat.conversationId);\n await enqueueRunJob(\n \"AI_NEWTON_CHAT\",\n { conversationId: chat.conversationId, aiMessageId: aiPlaceholder.id },\n { userId },\n );\n } catch (error) {\n logger.error(\"Failed to enqueue Newton introduction\", {\n error,\n newtonChatId: chat.id,\n });\n }\n }\n\n return {\n conversationId: chat.conversationId,\n newtonChatId: chat.id,\n };\n}\n\nexport async function postToNewtonChat(\n userId: string,\n newtonChatId: string,\n content: string,\n mentionedUserIds: string[] = [],\n fileIds: string[] = []\n) {\n const newtonChat = await findNewtonChatByIdAndMember(newtonChatId, userId);\n if (!newtonChat) {\n throw new TRPCError({\n code: \"FORBIDDEN\",\n message: \"Newton chat not found or access denied\",\n });\n }\n\n if (mentionedUserIds.length > 0) {\n const mentionedMemberships = await findConversationMembersByUserIds(\n newtonChat.conversationId,\n mentionedUserIds\n );\n if (mentionedMemberships.length !== mentionedUserIds.length) {\n throw new TRPCError({\n code: \"BAD_REQUEST\",\n message: \"Some mentioned users are not members of this conversation\",\n });\n }\n }\n\n ensureMessageHasContentOrAttachments(content, fileIds);\n const normalizedContent = content.trim();\n\n if (!normalizedContent) {\n throw new TRPCError({\n code: \"BAD_REQUEST\",\n message: \"Newton chat messages must include text content\",\n });\n }\n\n const result = await prisma.$transaction(async (tx) => {\n const message = await tx.message.create({\n data: {\n content: normalizedContent,\n senderId: userId,\n conversationId: newtonChat.conversationId,\n },\n });\n\n await claimMessageAttachments(\n tx,\n userId,\n newtonChat.conversationId,\n message.id,\n fileIds\n );\n\n if (mentionedUserIds.length > 0) {\n await tx.mention.createMany({\n data: mentionedUserIds.map((mentionedUserId) => ({\n messageId: message.id,\n userId: mentionedUserId,\n })),\n });\n }\n\n await tx.newtonChat.update({\n where: { id: newtonChatId },\n data: { updatedAt: new Date() },\n });\n\n return tx.message.findUniqueOrThrow({\n where: { id: message.id },\n include: {\n sender: {\n select: {\n id: true,\n username: true,\n profile: {\n select: {\n displayName: true,\n profilePicture: true,\n },\n },\n },\n },\n attachments: {\n select: messageFileSelect,\n },\n },\n });\n });\n\n try {\n await pusher.trigger(\n chatChannel(newtonChat.conversationId),\n \"new-message\",\n {\n id: result.id,\n content: result.content,\n senderId: result.senderId,\n conversationId: result.conversationId,\n status: result.status,\n createdAt: result.createdAt,\n sender: result.sender,\n attachments: result.attachments ?? [],\n mentionedUserIds,\n meta: {},\n }\n );\n } catch (error) {\n console.error(\"Failed to broadcast newton chat message:\", error);\n }\n\n if (!isAIUser(userId)) {\n // Create the AI placeholder post-tx (so a rollback can't broadcast a\n // ghost bubble); the pipeline fills it in.\n try {\n const aiPlaceholder = await createPendingAIMessage(newtonChat.conversationId);\n await enqueueRunJob(\n \"AI_NEWTON_CHAT\",\n { conversationId: newtonChat.conversationId, aiMessageId: aiPlaceholder.id },\n { userId },\n );\n } catch (error) {\n logger.error(\"Failed to enqueue Newton response\", {\n error,\n newtonChatId,\n studentMessageId: result.id,\n conversationId: newtonChat.conversationId,\n });\n }\n }\n\n return {\n id: result.id,\n content: result.content,\n senderId: result.senderId,\n conversationId: result.conversationId,\n status: result.status,\n createdAt: result.createdAt,\n sender: result.sender,\n attachments: result.attachments ?? [],\n mentionedUserIds,\n };\n}\n"],"names":[],"mappings":"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","debug_id":"0575644e-e077-5f74-8b0c-a6feb71814e9"}
1
+ {"version":3,"file":"newtonChat.js","sources":["services/newtonChat.ts"],"sourceRoot":"/","sourcesContent":["/**\n * Newton chat service – AI tutor conversations for assignments. Get or create\n * tutor session, post messages, trigger AI responses. Broadcasts via Pusher.\n */\nimport { TRPCError } from \"@trpc/server\";\nimport { logger } from \"../utils/logger.js\";\nimport { chatChannel, pusher } from \"../lib/pusher.js\";\nimport { isAIUser } from \"../utils/aiUser.js\";\nimport { createPendingAIMessage } from \"../utils/inference.js\";\nimport { enqueueRunJob } from \"../workers/queues.js\";\nimport {\n claimMessageAttachments,\n ensureMessageHasContentOrAttachments,\n} from \"./message.js\";\nimport { messageFileSelect } from \"../models/message.js\";\nimport {\n findClassWithStudent,\n findSubmissionByAssignmentAndStudent,\n findNewtonChatByIdAndMember,\n findConversationMembersByUserIds,\n} from \"../models/newtonChat.js\";\nimport { prisma } from \"../lib/prisma.js\";\n\n/** Get or create Newton tutor conversation for a submission. Student-only. */\nexport async function getTutorConversation(\n userId: string,\n assignmentId: string,\n classId: string\n) {\n const classMembership = await findClassWithStudent(classId, userId);\n if (!classMembership) {\n throw new TRPCError({\n code: \"FORBIDDEN\",\n message: \"Not a student in this class\",\n });\n }\n\n const submission = await findSubmissionByAssignmentAndStudent(\n assignmentId,\n userId\n );\n if (!submission) {\n throw new TRPCError({\n code: \"NOT_FOUND\",\n message: \"Submission not found. Please create a submission first.\",\n });\n }\n\n const { chat, isNew } = await prisma.$transaction(async (tx) => {\n const existingNewtonChat = await tx.newtonChat.findFirst({\n where: { submissionId: submission.id },\n include: {\n conversation: {\n include: {\n members: {\n where: { userId },\n },\n },\n },\n },\n orderBy: { createdAt: \"desc\" },\n });\n\n if (existingNewtonChat && existingNewtonChat.conversation.members.length > 0) {\n return { chat: existingNewtonChat, isNew: false };\n }\n\n if (existingNewtonChat) {\n await tx.conversationMember.create({\n data: {\n userId,\n conversationId: existingNewtonChat.conversationId,\n role: \"MEMBER\",\n },\n });\n return { chat: existingNewtonChat, isNew: false };\n }\n\n const conversation = await tx.conversation.create({\n data: {\n type: \"DM\",\n name: \"Session with Newton Tutor\",\n displayInChat: false,\n },\n });\n\n await tx.conversationMember.create({\n data: {\n userId,\n conversationId: conversation.id,\n role: \"MEMBER\",\n },\n });\n\n const newtonChat = await tx.newtonChat.create({\n data: {\n submissionId: submission.id,\n conversationId: conversation.id,\n title: \"Session with Newton Tutor\",\n },\n });\n\n return { chat: newtonChat, isNew: true };\n });\n\n if (isNew) {\n // Create the AI introduction placeholder and enqueue OUTSIDE the\n // transaction — a tx rollback would otherwise orphan a job pointing at\n // a non-existent NewtonChat / Message row.\n try {\n const aiPlaceholder = await createPendingAIMessage(chat.conversationId);\n await enqueueRunJob(\n \"AI_NEWTON_CHAT\",\n { conversationId: chat.conversationId, aiMessageId: aiPlaceholder.id },\n { userId },\n );\n } catch (error) {\n logger.error(\"Failed to enqueue Newton introduction\", {\n error,\n newtonChatId: chat.id,\n });\n }\n }\n\n return {\n conversationId: chat.conversationId,\n newtonChatId: chat.id,\n };\n}\n\nexport async function postToNewtonChat(\n userId: string,\n newtonChatId: string,\n content: string,\n mentionedUserIds: string[] = [],\n fileIds: string[] = []\n) {\n const newtonChat = await findNewtonChatByIdAndMember(newtonChatId, userId);\n if (!newtonChat) {\n throw new TRPCError({\n code: \"FORBIDDEN\",\n message: \"Newton chat not found or access denied\",\n });\n }\n\n if (mentionedUserIds.length > 0) {\n const mentionedMemberships = await findConversationMembersByUserIds(\n newtonChat.conversationId,\n mentionedUserIds\n );\n if (mentionedMemberships.length !== mentionedUserIds.length) {\n throw new TRPCError({\n code: \"BAD_REQUEST\",\n message: \"Some mentioned users are not members of this conversation\",\n });\n }\n }\n\n ensureMessageHasContentOrAttachments(content, fileIds);\n const normalizedContent = content.trim();\n\n const result = await prisma.$transaction(async (tx) => {\n const message = await tx.message.create({\n data: {\n content: normalizedContent,\n senderId: userId,\n conversationId: newtonChat.conversationId,\n },\n });\n\n await claimMessageAttachments(\n tx,\n userId,\n newtonChat.conversationId,\n message.id,\n fileIds\n );\n\n if (mentionedUserIds.length > 0) {\n await tx.mention.createMany({\n data: mentionedUserIds.map((mentionedUserId) => ({\n messageId: message.id,\n userId: mentionedUserId,\n })),\n });\n }\n\n await tx.newtonChat.update({\n where: { id: newtonChatId },\n data: { updatedAt: new Date() },\n });\n\n return tx.message.findUniqueOrThrow({\n where: { id: message.id },\n include: {\n sender: {\n select: {\n id: true,\n username: true,\n profile: {\n select: {\n displayName: true,\n profilePicture: true,\n },\n },\n },\n },\n attachments: {\n select: messageFileSelect,\n },\n },\n });\n });\n\n try {\n await pusher.trigger(\n chatChannel(newtonChat.conversationId),\n \"new-message\",\n {\n id: result.id,\n content: result.content,\n senderId: result.senderId,\n conversationId: result.conversationId,\n status: result.status,\n createdAt: result.createdAt,\n sender: result.sender,\n attachments: result.attachments ?? [],\n mentionedUserIds,\n meta: {},\n }\n );\n } catch (error) {\n console.error(\"Failed to broadcast newton chat message:\", error);\n }\n\n if (!isAIUser(userId)) {\n // Create the AI placeholder post-tx (so a rollback can't broadcast a\n // ghost bubble); the pipeline fills it in.\n try {\n const aiPlaceholder = await createPendingAIMessage(newtonChat.conversationId);\n await enqueueRunJob(\n \"AI_NEWTON_CHAT\",\n { conversationId: newtonChat.conversationId, aiMessageId: aiPlaceholder.id },\n { userId },\n );\n } catch (error) {\n logger.error(\"Failed to enqueue Newton response\", {\n error,\n newtonChatId,\n studentMessageId: result.id,\n conversationId: newtonChat.conversationId,\n });\n }\n }\n\n return {\n id: result.id,\n content: result.content,\n senderId: result.senderId,\n conversationId: result.conversationId,\n status: result.status,\n createdAt: result.createdAt,\n sender: result.sender,\n attachments: result.attachments ?? [],\n mentionedUserIds,\n };\n}\n"],"names":[],"mappings":"AAAA;;;GAGG;;;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EACL,uBAAuB,EACvB,oCAAoC,GACrC,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EACL,oBAAoB,EACpB,oCAAoC,EACpC,2BAA2B,EAC3B,gCAAgC,GACjC,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,8EAA8E;AAC9E,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,MAAc,EACd,YAAoB,EACpB,OAAe;IAEf,MAAM,eAAe,GAAG,MAAM,oBAAoB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACpE,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,MAAM,IAAI,SAAS,CAAC;YAClB,IAAI,EAAE,WAAW;YACjB,OAAO,EAAE,6BAA6B;SACvC,CAAC,CAAC;IACL,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,oCAAoC,CAC3D,YAAY,EACZ,MAAM,CACP,CAAC;IACF,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,SAAS,CAAC;YAClB,IAAI,EAAE,WAAW;YACjB,OAAO,EAAE,yDAAyD;SACnE,CAAC,CAAC;IACL,CAAC;IAED,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE;QAC7D,MAAM,kBAAkB,GAAG,MAAM,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC;YACvD,KAAK,EAAE,EAAE,YAAY,EAAE,UAAU,CAAC,EAAE,EAAE;YACtC,OAAO,EAAE;gBACP,YAAY,EAAE;oBACZ,OAAO,EAAE;wBACP,OAAO,EAAE;4BACP,KAAK,EAAE,EAAE,MAAM,EAAE;yBAClB;qBACF;iBACF;aACF;YACD,OAAO,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE;SAC/B,CAAC,CAAC;QAEH,IAAI,kBAAkB,IAAI,kBAAkB,CAAC,YAAY,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7E,OAAO,EAAE,IAAI,EAAE,kBAAkB,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;QACpD,CAAC;QAED,IAAI,kBAAkB,EAAE,CAAC;YACvB,MAAM,EAAE,CAAC,kBAAkB,CAAC,MAAM,CAAC;gBACjC,IAAI,EAAE;oBACJ,MAAM;oBACN,cAAc,EAAE,kBAAkB,CAAC,cAAc;oBACjD,IAAI,EAAE,QAAQ;iBACf;aACF,CAAC,CAAC;YACH,OAAO,EAAE,IAAI,EAAE,kBAAkB,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;QACpD,CAAC;QAED,MAAM,YAAY,GAAG,MAAM,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC;YAChD,IAAI,EAAE;gBACJ,IAAI,EAAE,IAAI;gBACV,IAAI,EAAE,2BAA2B;gBACjC,aAAa,EAAE,KAAK;aACrB;SACF,CAAC,CAAC;QAEH,MAAM,EAAE,CAAC,kBAAkB,CAAC,MAAM,CAAC;YACjC,IAAI,EAAE;gBACJ,MAAM;gBACN,cAAc,EAAE,YAAY,CAAC,EAAE;gBAC/B,IAAI,EAAE,QAAQ;aACf;SACF,CAAC,CAAC;QAEH,MAAM,UAAU,GAAG,MAAM,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC;YAC5C,IAAI,EAAE;gBACJ,YAAY,EAAE,UAAU,CAAC,EAAE;gBAC3B,cAAc,EAAE,YAAY,CAAC,EAAE;gBAC/B,KAAK,EAAE,2BAA2B;aACnC;SACF,CAAC,CAAC;QAEH,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,IAAI,KAAK,EAAE,CAAC;QACV,iEAAiE;QACjE,uEAAuE;QACvE,2CAA2C;QAC3C,IAAI,CAAC;YACH,MAAM,aAAa,GAAG,MAAM,sBAAsB,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YACxE,MAAM,aAAa,CACjB,gBAAgB,EAChB,EAAE,cAAc,EAAE,IAAI,CAAC,cAAc,EAAE,WAAW,EAAE,aAAa,CAAC,EAAE,EAAE,EACtE,EAAE,MAAM,EAAE,CACX,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,uCAAuC,EAAE;gBACpD,KAAK;gBACL,YAAY,EAAE,IAAI,CAAC,EAAE;aACtB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO;QACL,cAAc,EAAE,IAAI,CAAC,cAAc;QACnC,YAAY,EAAE,IAAI,CAAC,EAAE;KACtB,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,MAAc,EACd,YAAoB,EACpB,OAAe,EACf,mBAA6B,EAAE,EAC/B,UAAoB,EAAE;IAEtB,MAAM,UAAU,GAAG,MAAM,2BAA2B,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IAC3E,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,SAAS,CAAC;YAClB,IAAI,EAAE,WAAW;YACjB,OAAO,EAAE,wCAAwC;SAClD,CAAC,CAAC;IACL,CAAC;IAED,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChC,MAAM,oBAAoB,GAAG,MAAM,gCAAgC,CACjE,UAAU,CAAC,cAAc,EACzB,gBAAgB,CACjB,CAAC;QACF,IAAI,oBAAoB,CAAC,MAAM,KAAK,gBAAgB,CAAC,MAAM,EAAE,CAAC;YAC5D,MAAM,IAAI,SAAS,CAAC;gBAClB,IAAI,EAAE,aAAa;gBACnB,OAAO,EAAE,2DAA2D;aACrE,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,oCAAoC,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACvD,MAAM,iBAAiB,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAEzC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE;QACpD,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC;YACtC,IAAI,EAAE;gBACJ,OAAO,EAAE,iBAAiB;gBAC1B,QAAQ,EAAE,MAAM;gBAChB,cAAc,EAAE,UAAU,CAAC,cAAc;aAC1C;SACF,CAAC,CAAC;QAEH,MAAM,uBAAuB,CAC3B,EAAE,EACF,MAAM,EACN,UAAU,CAAC,cAAc,EACzB,OAAO,CAAC,EAAE,EACV,OAAO,CACR,CAAC;QAEF,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChC,MAAM,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC;gBAC1B,IAAI,EAAE,gBAAgB,CAAC,GAAG,CAAC,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;oBAC/C,SAAS,EAAE,OAAO,CAAC,EAAE;oBACrB,MAAM,EAAE,eAAe;iBACxB,CAAC,CAAC;aACJ,CAAC,CAAC;QACL,CAAC;QAED,MAAM,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC;YACzB,KAAK,EAAE,EAAE,EAAE,EAAE,YAAY,EAAE;YAC3B,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,EAAE;SAChC,CAAC,CAAC;QAEH,OAAO,EAAE,CAAC,OAAO,CAAC,iBAAiB,CAAC;YAClC,KAAK,EAAE,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE;YACzB,OAAO,EAAE;gBACP,MAAM,EAAE;oBACN,MAAM,EAAE;wBACN,EAAE,EAAE,IAAI;wBACR,QAAQ,EAAE,IAAI;wBACd,OAAO,EAAE;4BACP,MAAM,EAAE;gCACN,WAAW,EAAE,IAAI;gCACjB,cAAc,EAAE,IAAI;6BACrB;yBACF;qBACF;iBACF;gBACD,WAAW,EAAE;oBACX,MAAM,EAAE,iBAAiB;iBAC1B;aACF;SACF,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,OAAO,CAClB,WAAW,CAAC,UAAU,CAAC,cAAc,CAAC,EACtC,aAAa,EACb;YACE,EAAE,EAAE,MAAM,CAAC,EAAE;YACb,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,cAAc,EAAE,MAAM,CAAC,cAAc;YACrC,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,EAAE;YACrC,gBAAgB;YAChB,IAAI,EAAE,EAAE;SACT,CACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,0CAA0C,EAAE,KAAK,CAAC,CAAC;IACnE,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACtB,qEAAqE;QACrE,2CAA2C;QAC3C,IAAI,CAAC;YACH,MAAM,aAAa,GAAG,MAAM,sBAAsB,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;YAC9E,MAAM,aAAa,CACjB,gBAAgB,EAChB,EAAE,cAAc,EAAE,UAAU,CAAC,cAAc,EAAE,WAAW,EAAE,aAAa,CAAC,EAAE,EAAE,EAC5E,EAAE,MAAM,EAAE,CACX,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,mCAAmC,EAAE;gBAChD,KAAK;gBACL,YAAY;gBACZ,gBAAgB,EAAE,MAAM,CAAC,EAAE;gBAC3B,cAAc,EAAE,UAAU,CAAC,cAAc;aAC1C,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO;QACL,EAAE,EAAE,MAAM,CAAC,EAAE;QACb,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,EAAE;QACrC,gBAAgB;KACjB,CAAC;AACJ,CAAC","debug_id":"39ab2fff-5212-508b-bb38-849fb5430153"}
@@ -1,9 +1,15 @@
1
1
  import type { Response } from 'openai/resources/responses/responses.js';
2
+ /**
3
+ * Extensions OpenAI Code Interpreter can read/write in its sandbox.
4
+ * @see https://developers.openai.com/api/docs/guides/tools-code-interpreter
5
+ */
2
6
  export declare const SUPPORTED_DOCUMENT_FORMATS: readonly ["pdf", "docx", "doc", "xlsx", "pptx", "csv", "md", "html", "txt", "json", "xml", "tex", "png", "jpeg", "jpg", "gif", "zip", "tar", "py", "js", "ts", "css", "sh"];
3
7
  export type DocumentFormat = (typeof SUPPORTED_DOCUMENT_FORMATS)[number];
4
8
  export interface GenerateDocumentInput {
5
9
  title: string;
10
+ /** Markdown or plain-text source material for the output file. */
6
11
  content: string;
12
+ /** Output format. Defaults to pdf. */
7
13
  format?: DocumentFormat | string;
8
14
  }
9
15
  export interface GeneratedDocumentResult {
@@ -19,7 +25,13 @@ export interface ContainerGeneratedFile {
19
25
  }
20
26
  export declare function normalizeDocumentFormat(format?: string | null): DocumentFormat;
21
27
  export declare function mimeTypeForFormat(format: DocumentFormat): string;
28
+ export declare function extensionForFormat(format: DocumentFormat): string;
29
+ /** Pull generated-file citations for a given extension out of a Responses output. */
22
30
  export declare function extractContainerGeneratedFiles(response: Response, extension: DocumentFormat): ContainerGeneratedFile[];
23
31
  /** Generate a file via OpenAI Code Interpreter. */
24
32
  export declare function generateDocumentWithOpenAI(input: GenerateDocumentInput): Promise<GeneratedDocumentResult | null>;
33
+ /** @deprecated Use {@link generateDocumentWithOpenAI} */
34
+ export declare function generatePdfWithOpenAI(input: Omit<GenerateDocumentInput, 'format'>): Promise<Buffer | null>;
35
+ /** @deprecated Use {@link extractContainerGeneratedFiles} */
36
+ export declare const extractContainerPdfFiles: (response: Response) => ContainerGeneratedFile[];
25
37
  //# sourceMappingURL=openaiDocumentGen.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"openaiDocumentGen.d.ts","sourceRoot":"/","sources":["services/openaiDocumentGen.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yCAAyC,CAAC;AAKxE,eAAO,MAAM,0BAA0B,6KAI7B,CAAC;AAEX,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,0BAA0B,CAAC,CAAC,MAAM,CAAC,CAAC;AAsDzE,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,cAAc,GAAG,MAAM,CAAC;CAClC;AAED,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,cAAc,CAAC;CACxB;AAED,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,uBAAuB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,cAAc,CAM9E;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAEhE;AAED,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,cAAc,GACxB,sBAAsB,EAAE,CAyB1B;AAwCD,mDAAmD;AACnD,wBAAsB,0BAA0B,CAC9C,KAAK,EAAE,qBAAqB,GAC3B,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC,CAgEzC"}
1
+ {"version":3,"file":"openaiDocumentGen.d.ts","sourceRoot":"/","sources":["services/openaiDocumentGen.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yCAAyC,CAAC;AAKxE;;;GAGG;AACH,eAAO,MAAM,0BAA0B,6KAwB7B,CAAC;AAEX,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,0BAA0B,CAAC,CAAC,MAAM,CAAC,CAAC;AA6FzE,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,kEAAkE;IAClE,OAAO,EAAE,MAAM,CAAC;IAChB,sCAAsC;IACtC,MAAM,CAAC,EAAE,cAAc,GAAG,MAAM,CAAC;CAClC;AAED,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,cAAc,CAAC;CACxB;AAED,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,uBAAuB,CACrC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GACrB,cAAc,CAMhB;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAEhE;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAEjE;AAED,qFAAqF;AACrF,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,cAAc,GACxB,sBAAsB,EAAE,CA2B1B;AA6ED,mDAAmD;AACnD,wBAAsB,0BAA0B,CAC9C,KAAK,EAAE,qBAAqB,GAC3B,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC,CAiEzC;AAED,yDAAyD;AACzD,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,IAAI,CAAC,qBAAqB,EAAE,QAAQ,CAAC,GAC3C,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAGxB;AAED,6DAA6D;AAC7D,eAAO,MAAM,wBAAwB,GAAI,UAAU,QAAQ,6BACV,CAAC"}