@studious-lms/server 1.0.7 → 1.1.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 (71) hide show
  1. package/API_SPECIFICATION.md +352 -8
  2. package/dist/exportType.d.ts +3 -3
  3. package/dist/exportType.d.ts.map +1 -1
  4. package/dist/index.js +4 -4
  5. package/dist/lib/fileUpload.js +3 -3
  6. package/dist/lib/thumbnailGenerator.js +2 -2
  7. package/dist/middleware/auth.js +1 -1
  8. package/dist/middleware/logging.js +1 -1
  9. package/dist/routers/_app.d.ts +64 -64
  10. package/dist/routers/_app.js +14 -14
  11. package/dist/routers/agenda.d.ts +2 -2
  12. package/dist/routers/agenda.js +2 -2
  13. package/dist/routers/announcement.d.ts +2 -2
  14. package/dist/routers/announcement.js +2 -2
  15. package/dist/routers/assignment.d.ts +2 -2
  16. package/dist/routers/assignment.js +4 -4
  17. package/dist/routers/attendance.d.ts +2 -2
  18. package/dist/routers/attendance.js +2 -2
  19. package/dist/routers/auth.d.ts +2 -2
  20. package/dist/routers/auth.js +3 -3
  21. package/dist/routers/class.d.ts +7 -7
  22. package/dist/routers/class.d.ts.map +1 -1
  23. package/dist/routers/class.js +21 -13
  24. package/dist/routers/event.d.ts +2 -2
  25. package/dist/routers/event.js +2 -2
  26. package/dist/routers/file.d.ts +2 -2
  27. package/dist/routers/file.d.ts.map +1 -1
  28. package/dist/routers/file.js +4 -11
  29. package/dist/routers/folder.d.ts +3 -3
  30. package/dist/routers/folder.js +5 -5
  31. package/dist/routers/notifications.d.ts +2 -2
  32. package/dist/routers/notifications.js +2 -2
  33. package/dist/routers/section.d.ts +2 -2
  34. package/dist/routers/section.js +2 -2
  35. package/dist/routers/user.d.ts +2 -2
  36. package/dist/routers/user.js +3 -3
  37. package/dist/seedDatabase.d.ts.map +1 -1
  38. package/dist/seedDatabase.js +21 -3
  39. package/dist/socket/handlers.js +1 -1
  40. package/dist/trpc.d.ts +1 -1
  41. package/dist/trpc.d.ts.map +1 -1
  42. package/dist/trpc.js +5 -5
  43. package/dist/types/trpc.d.ts +1 -1
  44. package/dist/types/trpc.d.ts.map +1 -1
  45. package/dist/utils/prismaWrapper.js +1 -1
  46. package/package.json +4 -3
  47. package/prisma/schema.prisma +2 -2
  48. package/src/exportType.ts +3 -3
  49. package/src/index.ts +4 -4
  50. package/src/lib/fileUpload.ts +3 -3
  51. package/src/lib/thumbnailGenerator.ts +2 -2
  52. package/src/middleware/auth.ts +2 -2
  53. package/src/middleware/logging.ts +2 -2
  54. package/src/routers/_app.ts +14 -14
  55. package/src/routers/agenda.ts +2 -2
  56. package/src/routers/announcement.ts +2 -2
  57. package/src/routers/assignment.ts +4 -4
  58. package/src/routers/attendance.ts +2 -2
  59. package/src/routers/auth.ts +4 -4
  60. package/src/routers/class.ts +25 -14
  61. package/src/routers/event.ts +2 -2
  62. package/src/routers/file.ts +4 -12
  63. package/src/routers/folder.ts +5 -5
  64. package/src/routers/notifications.ts +2 -2
  65. package/src/routers/section.ts +2 -2
  66. package/src/routers/user.ts +3 -3
  67. package/src/seedDatabase.ts +25 -3
  68. package/src/socket/handlers.ts +1 -1
  69. package/src/trpc.ts +5 -5
  70. package/src/types/trpc.ts +1 -1
  71. package/src/utils/prismaWrapper.ts +1 -1
@@ -1,8 +1,8 @@
1
1
  import { z } from "zod";
2
- import { createTRPCRouter, protectedProcedure, protectedTeacherProcedure, protectedClassMemberProcedure } from "../trpc";
3
- import { prisma } from "../lib/prisma";
2
+ import { createTRPCRouter, protectedProcedure, protectedTeacherProcedure, protectedClassMemberProcedure } from "../trpc.js";
3
+ import { prisma } from "../lib/prisma.js";
4
4
  import { TRPCError } from "@trpc/server";
5
- import { generateInviteCode } from "../utils/generateInviteCode";
5
+ import { generateInviteCode } from "../utils/generateInviteCode.js";
6
6
 
7
7
  export const classRouter = createTRPCRouter({
8
8
  getAll: protectedProcedure
@@ -168,25 +168,30 @@ export const classRouter = createTRPCRouter({
168
168
  },
169
169
  });
170
170
 
171
+
172
+ if (!classData) {
173
+ throw new Error('Class not found');
174
+ }
175
+
176
+ const formattedClassData = {
177
+ ...classData,
178
+ assignments: classData.assignments.map(assignment => ({
179
+ ...assignment,
180
+ late: assignment.dueDate < new Date(),
181
+ submitted: assignment.submissions.some(submission => submission.studentId === ctx.user?.id),
182
+ returned: assignment.submissions.some(submission => submission.studentId === ctx.user?.id && submission.returned),
183
+ })),
184
+ }
185
+
171
186
  const sections = await prisma.section.findMany({
172
187
  where: {
173
188
  classId: classId,
174
189
  },
175
190
  });
176
191
 
177
- if (!classData) {
178
- throw new Error('Class not found');
179
- }
180
-
181
192
  return {
182
193
  class: {
183
- ...classData,
184
- assignments: classData.assignments.map(assignment => ({
185
- ...assignment,
186
- late: assignment.dueDate < new Date(),
187
- submitted: assignment.submissions.some(submission => submission.studentId === ctx.user?.id),
188
- returned: assignment.submissions.some(submission => submission.studentId === ctx.user?.id && submission.returned),
189
- })),
194
+ ...formattedClassData,
190
195
  sections,
191
196
  },
192
197
  };
@@ -482,6 +487,12 @@ export const classRouter = createTRPCRouter({
482
487
  .mutation(async ({ ctx, input }) => {
483
488
  const { classId } = input;
484
489
 
490
+ await prisma.session.deleteMany({
491
+ where: {
492
+ classId,
493
+ },
494
+ });
495
+
485
496
  // Create a new session for the invite code
486
497
  const session = await prisma.session.create({
487
498
  data: {
@@ -1,7 +1,7 @@
1
1
  import { z } from "zod";
2
- import { createTRPCRouter, protectedProcedure } from "../trpc";
2
+ import { createTRPCRouter, protectedProcedure } from "../trpc.js";
3
3
  import { TRPCError } from "@trpc/server";
4
- import { prisma } from "../lib/prisma";
4
+ import { prisma } from "../lib/prisma.js";
5
5
  import { parseISO } from "date-fns";
6
6
 
7
7
  const eventSchema = z.object({
@@ -1,10 +1,10 @@
1
1
  import { z } from "zod";
2
- import { createTRPCRouter, protectedProcedure, protectedTeacherProcedure } from "../trpc";
2
+ import { createTRPCRouter, protectedProcedure, protectedTeacherProcedure } from "../trpc.js";
3
3
  import { TRPCError } from "@trpc/server";
4
- import { getSignedUrl, deleteFile } from "../lib/googleCloudStorage";
4
+ import { getSignedUrl, deleteFile } from "../lib/googleCloudStorage.js";
5
5
  import type { User } from "@prisma/client";
6
- import { prisma } from "../lib/prisma";
7
- import { logger } from "../utils/logger";
6
+ import { prisma } from "../lib/prisma.js";
7
+ import { logger } from "../utils/logger.js";
8
8
 
9
9
  export const fileRouter = createTRPCRouter({
10
10
  getSignedUrl: protectedProcedure
@@ -246,14 +246,6 @@ export const fileRouter = createTRPCRouter({
246
246
  });
247
247
  }
248
248
 
249
- // Verify the file belongs to this class
250
- if (file.folder?.classId !== classId) {
251
- throw new TRPCError({
252
- code: "FORBIDDEN",
253
- message: "File does not belong to this class",
254
- });
255
- }
256
-
257
249
  // Validate new name
258
250
  if (!newName.trim()) {
259
251
  throw new TRPCError({
@@ -1,8 +1,8 @@
1
1
  import { z } from "zod";
2
- import { createTRPCRouter, protectedProcedure, protectedClassMemberProcedure, protectedTeacherProcedure } from "../trpc";
2
+ import { createTRPCRouter, protectedProcedure, protectedClassMemberProcedure, protectedTeacherProcedure } from "../trpc.js";
3
3
  import { TRPCError } from "@trpc/server";
4
- import { prisma } from "../lib/prisma";
5
- import { uploadFiles, type UploadedFile } from "../lib/fileUpload";
4
+ import { prisma } from "../lib/prisma.js";
5
+ import { uploadFiles, type UploadedFile } from "../lib/fileUpload.js";
6
6
 
7
7
  const fileSchema = z.object({
8
8
  name: z.string(),
@@ -548,7 +548,7 @@ export const folderRouter = createTRPCRouter({
548
548
  move: protectedTeacherProcedure
549
549
  .input(z.object({
550
550
  folderId: z.string(),
551
- targetParentFolderId: z.string().optional(),
551
+ targetParentFolderId: z.string(),
552
552
  classId: z.string(),
553
553
  }))
554
554
  .mutation(async ({ ctx, input }) => {
@@ -646,7 +646,7 @@ export const folderRouter = createTRPCRouter({
646
646
  const updatedFolder = await prisma.folder.update({
647
647
  where: { id: folderId },
648
648
  data: {
649
- parentFolderId: targetParentFolderId || null,
649
+ parentFolderId: targetParentFolderId,
650
650
  },
651
651
  include: {
652
652
  files: {
@@ -1,5 +1,5 @@
1
- import { createTRPCRouter, protectedProcedure } from "../trpc";
2
- import { prisma } from "../lib/prisma";
1
+ import { createTRPCRouter, protectedProcedure } from "../trpc.js";
2
+ import { prisma } from "../lib/prisma.js";
3
3
  import { z } from "zod";
4
4
 
5
5
  export const notificationRouter = createTRPCRouter({
@@ -1,7 +1,7 @@
1
1
  import { z } from "zod";
2
- import { createTRPCRouter, protectedProcedure } from "../trpc";
2
+ import { createTRPCRouter, protectedProcedure } from "../trpc.js";
3
3
  import { TRPCError } from "@trpc/server";
4
- import { prisma } from "../lib/prisma";
4
+ import { prisma } from "../lib/prisma.js";
5
5
 
6
6
  const createSectionSchema = z.object({
7
7
  classId: z.string(),
@@ -1,8 +1,8 @@
1
1
  import { z } from "zod";
2
- import { createTRPCRouter, protectedProcedure } from "../trpc";
2
+ import { createTRPCRouter, protectedProcedure } from "../trpc.js";
3
3
  import { TRPCError } from "@trpc/server";
4
- import { prisma } from "../lib/prisma";
5
- import { uploadFiles, type UploadedFile } from "../lib/fileUpload";
4
+ import { prisma } from "../lib/prisma.js";
5
+ import { uploadFiles, type UploadedFile } from "../lib/fileUpload.js";
6
6
 
7
7
  const fileSchema = z.object({
8
8
  name: z.string(),
@@ -1,12 +1,34 @@
1
- import { prisma } from "./lib/prisma";
1
+ import { prisma } from "./lib/prisma.js";
2
2
  import { hash } from "bcryptjs";
3
- import { logger } from "./utils/logger";
3
+ import { logger } from "./utils/logger.js";
4
4
 
5
5
  export async function clearDatabase() {
6
+ // Delete in order to respect foreign key constraints
7
+ // Delete notifications first (they reference users)
8
+ await prisma.notification.deleteMany();
9
+
10
+ // Delete other records that reference users
11
+ await prisma.submission.deleteMany();
12
+ await prisma.assignment.deleteMany();
13
+ await prisma.announcement.deleteMany();
14
+ await prisma.event.deleteMany();
15
+ await prisma.attendance.deleteMany();
16
+ await prisma.file.deleteMany();
17
+
18
+ // Delete class-related records
19
+ await prisma.section.deleteMany();
20
+ await prisma.markScheme.deleteMany();
21
+ await prisma.gradingBoundary.deleteMany();
22
+ await prisma.folder.deleteMany();
6
23
  await prisma.class.deleteMany();
7
- await prisma.userProfile.deleteMany();
24
+
25
+ // Delete user-related records
8
26
  await prisma.session.deleteMany();
27
+ await prisma.userProfile.deleteMany();
28
+
29
+ // Finally delete users and schools
9
30
  await prisma.user.deleteMany();
31
+ await prisma.school.deleteMany();
10
32
  }
11
33
 
12
34
  export async function createUser(email: string, password: string, username: string) {
@@ -1,5 +1,5 @@
1
1
  import { Socket, Server } from 'socket.io';
2
- import { logger } from '../utils/logger';
2
+ import { logger } from '../utils/logger.js';
3
3
 
4
4
  export const setupSocketHandlers = (io: Server) => {
5
5
  io.on('connection', (socket: Socket) => {
package/src/trpc.ts CHANGED
@@ -1,12 +1,12 @@
1
1
  import { initTRPC, TRPCError } from '@trpc/server';
2
2
  import { ZodError } from 'zod';
3
- import { logger } from './utils/logger';
4
- import { prisma } from './lib/prisma';
5
- import { createLoggingMiddleware } from './middleware/logging';
6
- import { createAuthMiddleware } from './middleware/auth';
3
+ import { logger } from './utils/logger.js';
4
+ import { prisma } from './lib/prisma.js';
5
+ import { createLoggingMiddleware } from './middleware/logging.js';
6
+ import { createAuthMiddleware } from './middleware/auth.js';
7
7
  import { Request, Response } from 'express';
8
8
  import { z } from 'zod';
9
- import { handlePrismaError, PrismaErrorInfo } from './utils/prismaErrorHandler';
9
+ import { handlePrismaError, PrismaErrorInfo } from './utils/prismaErrorHandler.js';
10
10
 
11
11
  interface CreateContextOptions {
12
12
  req: Request;
package/src/types/trpc.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { inferAsyncReturnType } from '@trpc/server';
2
- import { createTRPCContext } from '../trpc';
2
+ import { createTRPCContext } from '../trpc.js';
3
3
 
4
4
  export type Context = inferAsyncReturnType<typeof createTRPCContext> & {
5
5
  isTeacher?: boolean;
@@ -1,5 +1,5 @@
1
1
  import { TRPCError } from '@trpc/server';
2
- import { handlePrismaError } from './prismaErrorHandler';
2
+ import { handlePrismaError } from './prismaErrorHandler.js';
3
3
 
4
4
  export async function withPrismaErrorHandling<T>(
5
5
  operation: () => Promise<T>,