@studious-lms/server 1.0.7 → 1.0.8

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 +54 -54
  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 +2 -2
  22. package/dist/routers/class.d.ts.map +1 -1
  23. package/dist/routers/class.js +8 -3
  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 +9 -3
  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,11 +1,11 @@
1
1
  import { z } from "zod";
2
2
  export declare const fileRouter: import("@trpc/server").TRPCBuiltRouter<{
3
- ctx: import("../trpc").Context;
3
+ ctx: import("../trpc.js").Context;
4
4
  meta: object;
5
5
  errorShape: {
6
6
  data: {
7
7
  zodError: z.typeToFlattenedError<any, string> | null;
8
- prismaError: import("../utils/prismaErrorHandler").PrismaErrorInfo | null;
8
+ prismaError: import("../utils/prismaErrorHandler.js").PrismaErrorInfo | null;
9
9
  code: import("@trpc/server").TRPC_ERROR_CODE_KEY;
10
10
  httpStatus: number;
11
11
  path?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../../src/routers/file.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAQxB,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8VrB,CAAC"}
1
+ {"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../../src/routers/file.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAQxB,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsVrB,CAAC"}
@@ -1,9 +1,9 @@
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";
5
- import { prisma } from "../lib/prisma";
6
- import { logger } from "../utils/logger";
4
+ import { getSignedUrl, deleteFile } from "../lib/googleCloudStorage.js";
5
+ import { prisma } from "../lib/prisma.js";
6
+ import { logger } from "../utils/logger.js";
7
7
  export const fileRouter = createTRPCRouter({
8
8
  getSignedUrl: protectedProcedure
9
9
  .input(z.object({
@@ -222,13 +222,6 @@ export const fileRouter = createTRPCRouter({
222
222
  message: "File not found",
223
223
  });
224
224
  }
225
- // Verify the file belongs to this class
226
- if (file.folder?.classId !== classId) {
227
- throw new TRPCError({
228
- code: "FORBIDDEN",
229
- message: "File does not belong to this class",
230
- });
231
- }
232
225
  // Validate new name
233
226
  if (!newName.trim()) {
234
227
  throw new TRPCError({
@@ -1,11 +1,11 @@
1
1
  import { z } from "zod";
2
2
  export declare const folderRouter: import("@trpc/server").TRPCBuiltRouter<{
3
- ctx: import("../trpc").Context;
3
+ ctx: import("../trpc.js").Context;
4
4
  meta: object;
5
5
  errorShape: {
6
6
  data: {
7
7
  zodError: z.typeToFlattenedError<any, string> | null;
8
- prismaError: import("../utils/prismaErrorHandler").PrismaErrorInfo | null;
8
+ prismaError: import("../utils/prismaErrorHandler.js").PrismaErrorInfo | null;
9
9
  code: import("@trpc/server").TRPC_ERROR_CODE_KEY;
10
10
  httpStatus: number;
11
11
  path?: string;
@@ -227,7 +227,7 @@ export declare const folderRouter: import("@trpc/server").TRPCBuiltRouter<{
227
227
  [x: string]: unknown;
228
228
  classId: string;
229
229
  folderId: string;
230
- targetParentFolderId?: string | undefined;
230
+ targetParentFolderId: string;
231
231
  };
232
232
  output: {
233
233
  files: {
@@ -1,8 +1,8 @@
1
1
  import { z } from "zod";
2
- import { createTRPCRouter, protectedClassMemberProcedure, protectedTeacherProcedure } from "../trpc";
2
+ import { createTRPCRouter, protectedClassMemberProcedure, protectedTeacherProcedure } from "../trpc.js";
3
3
  import { TRPCError } from "@trpc/server";
4
- import { prisma } from "../lib/prisma";
5
- import { uploadFiles } from "../lib/fileUpload";
4
+ import { prisma } from "../lib/prisma.js";
5
+ import { uploadFiles } from "../lib/fileUpload.js";
6
6
  const fileSchema = z.object({
7
7
  name: z.string(),
8
8
  type: z.string(),
@@ -501,7 +501,7 @@ export const folderRouter = createTRPCRouter({
501
501
  move: protectedTeacherProcedure
502
502
  .input(z.object({
503
503
  folderId: z.string(),
504
- targetParentFolderId: z.string().optional(),
504
+ targetParentFolderId: z.string(),
505
505
  classId: z.string(),
506
506
  }))
507
507
  .mutation(async ({ ctx, input }) => {
@@ -591,7 +591,7 @@ export const folderRouter = createTRPCRouter({
591
591
  const updatedFolder = await prisma.folder.update({
592
592
  where: { id: folderId },
593
593
  data: {
594
- parentFolderId: targetParentFolderId || null,
594
+ parentFolderId: targetParentFolderId,
595
595
  },
596
596
  include: {
597
597
  files: {
@@ -1,11 +1,11 @@
1
1
  import { z } from "zod";
2
2
  export declare const notificationRouter: import("@trpc/server").TRPCBuiltRouter<{
3
- ctx: import("../trpc").Context;
3
+ ctx: import("../trpc.js").Context;
4
4
  meta: object;
5
5
  errorShape: {
6
6
  data: {
7
7
  zodError: z.typeToFlattenedError<any, string> | null;
8
- prismaError: import("../utils/prismaErrorHandler").PrismaErrorInfo | null;
8
+ prismaError: import("../utils/prismaErrorHandler.js").PrismaErrorInfo | null;
9
9
  code: import("@trpc/server").TRPC_ERROR_CODE_KEY;
10
10
  httpStatus: number;
11
11
  path?: string;
@@ -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
  export const notificationRouter = createTRPCRouter({
5
5
  list: protectedProcedure.query(async ({ ctx }) => {
@@ -1,11 +1,11 @@
1
1
  import { z } from "zod";
2
2
  export declare const sectionRouter: import("@trpc/server").TRPCBuiltRouter<{
3
- ctx: import("../trpc").Context;
3
+ ctx: import("../trpc.js").Context;
4
4
  meta: object;
5
5
  errorShape: {
6
6
  data: {
7
7
  zodError: z.typeToFlattenedError<any, string> | null;
8
- prismaError: import("../utils/prismaErrorHandler").PrismaErrorInfo | null;
8
+ prismaError: import("../utils/prismaErrorHandler.js").PrismaErrorInfo | null;
9
9
  code: import("@trpc/server").TRPC_ERROR_CODE_KEY;
10
10
  httpStatus: number;
11
11
  path?: string;
@@ -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
  const createSectionSchema = z.object({
6
6
  classId: z.string(),
7
7
  name: z.string(),
@@ -1,11 +1,11 @@
1
1
  import { z } from "zod";
2
2
  export declare const userRouter: import("@trpc/server").TRPCBuiltRouter<{
3
- ctx: import("../trpc").Context;
3
+ ctx: import("../trpc.js").Context;
4
4
  meta: object;
5
5
  errorShape: {
6
6
  data: {
7
7
  zodError: z.typeToFlattenedError<any, string> | null;
8
- prismaError: import("../utils/prismaErrorHandler").PrismaErrorInfo | null;
8
+ prismaError: import("../utils/prismaErrorHandler.js").PrismaErrorInfo | null;
9
9
  code: import("@trpc/server").TRPC_ERROR_CODE_KEY;
10
10
  httpStatus: number;
11
11
  path?: 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 } from "../lib/fileUpload";
4
+ import { prisma } from "../lib/prisma.js";
5
+ import { uploadFiles } from "../lib/fileUpload.js";
6
6
  const fileSchema = z.object({
7
7
  name: z.string(),
8
8
  type: z.string(),
@@ -1 +1 @@
1
- {"version":3,"file":"seedDatabase.d.ts","sourceRoot":"","sources":["../src/seedDatabase.ts"],"names":[],"mappings":"AAIA,wBAAsB,aAAa,kBAKlC;AAED,wBAAsB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;;;;;;;;;GAOjF;AAED,wBAAsB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;;;;;;;;GAQnF;AAED,eAAO,MAAM,YAAY,qBA6BxB,CAAC"}
1
+ {"version":3,"file":"seedDatabase.d.ts","sourceRoot":"","sources":["../src/seedDatabase.ts"],"names":[],"mappings":"AAIA,wBAAsB,aAAa,kBA2BlC;AAED,wBAAsB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;;;;;;;;;GAOjF;AAED,wBAAsB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;;;;;;;;GAQnF;AAED,eAAO,MAAM,YAAY,qBA6BxB,CAAC"}
@@ -1,11 +1,29 @@
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
  export async function clearDatabase() {
5
+ // Delete in order to respect foreign key constraints
6
+ // Delete notifications first (they reference users)
7
+ await prisma.notification.deleteMany();
8
+ // Delete other records that reference users
9
+ await prisma.submission.deleteMany();
10
+ await prisma.assignment.deleteMany();
11
+ await prisma.announcement.deleteMany();
12
+ await prisma.event.deleteMany();
13
+ await prisma.attendance.deleteMany();
14
+ await prisma.file.deleteMany();
15
+ // Delete class-related records
16
+ await prisma.section.deleteMany();
17
+ await prisma.markScheme.deleteMany();
18
+ await prisma.gradingBoundary.deleteMany();
19
+ await prisma.folder.deleteMany();
5
20
  await prisma.class.deleteMany();
6
- await prisma.userProfile.deleteMany();
21
+ // Delete user-related records
7
22
  await prisma.session.deleteMany();
23
+ await prisma.userProfile.deleteMany();
24
+ // Finally delete users and schools
8
25
  await prisma.user.deleteMany();
26
+ await prisma.school.deleteMany();
9
27
  }
10
28
  export async function createUser(email, password, username) {
11
29
  logger.debug("Creating user", { email, username, password });
@@ -1,4 +1,4 @@
1
- import { logger } from '../utils/logger';
1
+ import { logger } from '../utils/logger.js';
2
2
  export const setupSocketHandlers = (io) => {
3
3
  io.on('connection', (socket) => {
4
4
  logger.info('Client connected', { socketId: socket.id });
package/dist/trpc.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { TRPCError } from '@trpc/server';
2
2
  import { Request, Response } from 'express';
3
3
  import { z } from 'zod';
4
- import { PrismaErrorInfo } from './utils/prismaErrorHandler';
4
+ import { PrismaErrorInfo } from './utils/prismaErrorHandler.js';
5
5
  interface CreateContextOptions {
6
6
  req: Request;
7
7
  res: Response;
@@ -1 +1 @@
1
- {"version":3,"file":"trpc.d.ts","sourceRoot":"","sources":["../src/trpc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,SAAS,EAAE,MAAM,cAAc,CAAC;AAMnD,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAqB,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAEhF,UAAU,oBAAoB;IAC5B,GAAG,EAAE,OAAO,CAAC;IACb,GAAG,EAAE,QAAQ,CAAC;CACf;AAED,MAAM,MAAM,OAAO,GAAG;IACpB,GAAG,EAAE,OAAO,CAAC;IACb,GAAG,EAAE,QAAQ,CAAC;IACd,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC5B,IAAI,CAAC,EAAE;QACL,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,CAAC;CACH,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAU,MAAM,oBAAoB,KAAG,OAAO,CAAC,OAAO,CAwBnF,CAAC;AAEF,eAAO,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8BZ,CAAC;AAOH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;EAAW,CAAC;AACzC,eAAO,MAAM,eAAe,yOAAqC,CAAC;AAGlE,eAAO,MAAM,kBAAkB,yOAAgC,CAAC;AAChE,eAAO,MAAM,6BAA6B;;;;uHAEnB,CAAC;AACxB,eAAO,MAAM,yBAAyB;;;;uHAEd,CAAC;AAIzB,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;EAAwB,CAAC"}
1
+ {"version":3,"file":"trpc.d.ts","sourceRoot":"","sources":["../src/trpc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,SAAS,EAAE,MAAM,cAAc,CAAC;AAMnD,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAqB,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAEnF,UAAU,oBAAoB;IAC5B,GAAG,EAAE,OAAO,CAAC;IACb,GAAG,EAAE,QAAQ,CAAC;CACf;AAED,MAAM,MAAM,OAAO,GAAG;IACpB,GAAG,EAAE,OAAO,CAAC;IACb,GAAG,EAAE,QAAQ,CAAC;IACd,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC5B,IAAI,CAAC,EAAE;QACL,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,CAAC;CACH,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAU,MAAM,oBAAoB,KAAG,OAAO,CAAC,OAAO,CAwBnF,CAAC;AAEF,eAAO,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8BZ,CAAC;AAOH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;EAAW,CAAC;AACzC,eAAO,MAAM,eAAe,yOAAqC,CAAC;AAGlE,eAAO,MAAM,kBAAkB,yOAAgC,CAAC;AAChE,eAAO,MAAM,6BAA6B;;;;uHAEnB,CAAC;AACxB,eAAO,MAAM,yBAAyB;;;;uHAEd,CAAC;AAIzB,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;EAAwB,CAAC"}
package/dist/trpc.js CHANGED
@@ -1,11 +1,11 @@
1
1
  import { initTRPC } 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 { z } from 'zod';
8
- import { handlePrismaError } from './utils/prismaErrorHandler';
8
+ import { handlePrismaError } from './utils/prismaErrorHandler.js';
9
9
  export const createTRPCContext = async (opts) => {
10
10
  const { req, res } = opts;
11
11
  // Get user from session/token
@@ -1,5 +1,5 @@
1
1
  import { inferAsyncReturnType } from '@trpc/server';
2
- import { createTRPCContext } from '../trpc';
2
+ import { createTRPCContext } from '../trpc.js';
3
3
  export type Context = inferAsyncReturnType<typeof createTRPCContext> & {
4
4
  isTeacher?: boolean;
5
5
  teacherClassIds?: string[];
@@ -1 +1 @@
1
- {"version":3,"file":"trpc.d.ts","sourceRoot":"","sources":["../../src/types/trpc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAE5C,MAAM,MAAM,OAAO,GAAG,oBAAoB,CAAC,OAAO,iBAAiB,CAAC,GAAG;IACrE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B,CAAC;AAEF,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,OAAO,CAAC;IACb,IAAI,EAAE,CAAC,IAAI,CAAC,EAAE;QAAE,GAAG,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;KAAE,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;IACzD,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf"}
1
+ {"version":3,"file":"trpc.d.ts","sourceRoot":"","sources":["../../src/types/trpc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE/C,MAAM,MAAM,OAAO,GAAG,oBAAoB,CAAC,OAAO,iBAAiB,CAAC,GAAG;IACrE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B,CAAC;AAEF,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,OAAO,CAAC;IACb,IAAI,EAAE,CAAC,IAAI,CAAC,EAAE;QAAE,GAAG,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;KAAE,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;IACzD,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf"}
@@ -1,5 +1,5 @@
1
1
  import { TRPCError } from '@trpc/server';
2
- import { handlePrismaError } from './prismaErrorHandler';
2
+ import { handlePrismaError } from './prismaErrorHandler.js';
3
3
  export async function withPrismaErrorHandling(operation, context = 'database operation') {
4
4
  try {
5
5
  return await operation();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@studious-lms/server",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "description": "Backend server for Studious application",
5
5
  "main": "dist/exportType.js",
6
6
  "types": "dist/exportType.d.ts",
@@ -12,13 +12,13 @@
12
12
  }
13
13
  },
14
14
  "scripts": {
15
- "dev": "ts-node-dev --respawn --transpile-only --loader ts-node/esm src/index.ts",
15
+ "dev": "tsx watch src/index.ts",
16
16
  "build": "tsc",
17
17
  "start": "node dist/index.js",
18
18
  "generate": "npx prisma generate",
19
19
  "prepublishOnly": "npm run generate && npm run build",
20
20
  "test": "vitest",
21
- "seed": "ts-node src/seedDatabase.ts"
21
+ "seed": "node dist/seedDatabase.js"
22
22
  },
23
23
  "dependencies": {
24
24
  "@google-cloud/storage": "^7.16.0",
@@ -48,6 +48,7 @@
48
48
  "ts-node": "^10.9.2",
49
49
  "ts-node-dev": "^2.0.0",
50
50
  "tsconfig-paths": "^4.2.0",
51
+ "tsx": "^4.20.5",
51
52
  "typescript": "^5.3.3",
52
53
  "vitest": "^3.2.4"
53
54
  }
@@ -81,7 +81,7 @@ model User {
81
81
  model UserProfile {
82
82
  id String @id @default(uuid())
83
83
  userId String @unique
84
- user User? @relation(fields: [userId], references: [id])
84
+ user User? @relation(fields: [userId], references: [id], onDelete: Cascade)
85
85
 
86
86
  }
87
87
 
@@ -291,5 +291,5 @@ model Notification {
291
291
  receiverId String
292
292
  read Boolean @default(false)
293
293
  sender User? @relation("SentNotifications", fields: [senderId], references: [id])
294
- receiver User @relation("ReceivedNotifications", fields: [receiverId], references: [id])
294
+ receiver User @relation("ReceivedNotifications", fields: [receiverId], references: [id], onDelete: Cascade)
295
295
  }
package/src/exportType.ts CHANGED
@@ -4,6 +4,6 @@
4
4
  * to the client via npmjs
5
5
  */
6
6
 
7
- export type { AppRouter } from "./routers/_app";
8
- export type { RouterInputs } from "./routers/_app";
9
- export type { RouterOutputs } from "./routers/_app";
7
+ export type { AppRouter } from "./routers/_app.js";
8
+ export type { RouterInputs } from "./routers/_app.js";
9
+ export type { RouterOutputs } from "./routers/_app.js";
package/src/index.ts CHANGED
@@ -5,10 +5,10 @@ import { Server } from 'socket.io';
5
5
  import cors from 'cors';
6
6
  import dotenv from 'dotenv';
7
7
  import { createExpressMiddleware } from '@trpc/server/adapters/express';
8
- import { appRouter } from './routers/_app';
9
- import { createTRPCContext, createCallerFactory } from './trpc';
10
- import { logger } from './utils/logger';
11
- import { setupSocketHandlers } from './socket/handlers';
8
+ import { appRouter } from './routers/_app.js';
9
+ import { createTRPCContext, createCallerFactory } from './trpc.js';
10
+ import { logger } from './utils/logger.js';
11
+ import { setupSocketHandlers } from './socket/handlers.js';
12
12
 
13
13
  dotenv.config();
14
14
 
@@ -1,8 +1,8 @@
1
1
  import { TRPCError } from "@trpc/server";
2
2
  import { v4 as uuidv4 } from "uuid";
3
- import { uploadFile as uploadToGCS, getSignedUrl } from "./googleCloudStorage";
4
- import { generateThumbnail, storeThumbnail, generateMediaThumbnail } from "./thumbnailGenerator";
5
- import { prisma } from "./prisma";
3
+ import { uploadFile as uploadToGCS, getSignedUrl } from "./googleCloudStorage.js";
4
+ import { generateThumbnail, storeThumbnail, generateMediaThumbnail } from "./thumbnailGenerator.js";
5
+ import { prisma } from "./prisma.js";
6
6
 
7
7
  export interface FileData {
8
8
  name: string;
@@ -1,6 +1,6 @@
1
1
  import sharp from 'sharp';
2
- import { prisma } from './prisma';
3
- import { uploadFile, deleteFile, getSignedUrl } from './googleCloudStorage';
2
+ import { prisma } from './prisma.js';
3
+ import { uploadFile, deleteFile, getSignedUrl } from './googleCloudStorage.js';
4
4
 
5
5
  // Thumbnail size configuration
6
6
  const THUMBNAIL_WIDTH = 200;
@@ -1,6 +1,6 @@
1
1
  import { TRPCError } from '@trpc/server';
2
- import { prisma } from '../lib/prisma';
3
- import type { MiddlewareContext } from '../types/trpc';
2
+ import { prisma } from '../lib/prisma.js';
3
+ import type { MiddlewareContext } from '../types/trpc.js';
4
4
 
5
5
  export const createAuthMiddleware = (t: any) => {
6
6
 
@@ -1,5 +1,5 @@
1
- import type { MiddlewareContext } from '../types/trpc';
2
- import { logger } from '../utils/logger';
1
+ import type { MiddlewareContext } from '../types/trpc.js';
2
+ import { logger } from '../utils/logger.js';
3
3
 
4
4
  export const createLoggingMiddleware = (t: any) => {
5
5
  return t.middleware(async ({ path, type, next, ctx }: MiddlewareContext) => {
@@ -1,18 +1,18 @@
1
- import { createTRPCRouter } from "../trpc";
2
- import { classRouter } from "./class";
3
- import { announcementRouter } from "./announcement";
4
- import { assignmentRouter } from "./assignment";
5
- import { userRouter } from "./user";
6
- import { createCallerFactory } from "../trpc";
1
+ import { createTRPCRouter } from "../trpc.js";
2
+ import { classRouter } from "./class.js";
3
+ import { announcementRouter } from "./announcement.js";
4
+ import { assignmentRouter } from "./assignment.js";
5
+ import { userRouter } from "./user.js";
6
+ import { createCallerFactory } from "../trpc.js";
7
7
  import type { inferRouterInputs, inferRouterOutputs } from "@trpc/server";
8
- import { sectionRouter } from "./section";
9
- import { attendanceRouter } from "./attendance";
10
- import { eventRouter } from "./event";
11
- import { authRouter } from "./auth";
12
- import { agendaRouter } from "./agenda";
13
- import { fileRouter } from "./file";
14
- import { folderRouter } from "./folder";
15
- import { notificationRouter } from "./notifications";
8
+ import { sectionRouter } from "./section.js";
9
+ import { attendanceRouter } from "./attendance.js";
10
+ import { eventRouter } from "./event.js";
11
+ import { authRouter } from "./auth.js";
12
+ import { agendaRouter } from "./agenda.js";
13
+ import { fileRouter } from "./file.js";
14
+ import { folderRouter } from "./folder.js";
15
+ import { notificationRouter } from "./notifications.js";
16
16
 
17
17
  export const appRouter = createTRPCRouter({
18
18
  class: classRouter,
@@ -1,6 +1,6 @@
1
1
  import { z } from "zod";
2
- import { createTRPCRouter, protectedProcedure } from "../trpc";
3
- import { prisma } from "../lib/prisma";
2
+ import { createTRPCRouter, protectedProcedure } from "../trpc.js";
3
+ import { prisma } from "../lib/prisma.js";
4
4
  import { TRPCError } from "@trpc/server";
5
5
  import { addDays, startOfDay, endOfDay } from "date-fns";
6
6
 
@@ -1,6 +1,6 @@
1
1
  import { z } from "zod";
2
- import { createTRPCRouter, protectedClassMemberProcedure, protectedTeacherProcedure, protectedProcedure } from "../trpc";
3
- import { prisma } from "../lib/prisma";
2
+ import { createTRPCRouter, protectedClassMemberProcedure, protectedTeacherProcedure, protectedProcedure } from "../trpc.js";
3
+ import { prisma } from "../lib/prisma.js";
4
4
  import { TRPCError } from "@trpc/server";
5
5
 
6
6
  const AnnouncementSelect = {
@@ -1,9 +1,9 @@
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";
6
- import { deleteFile } from "../lib/googleCloudStorage";
4
+ import { prisma } from "../lib/prisma.js";
5
+ import { uploadFiles, type UploadedFile } from "../lib/fileUpload.js";
6
+ import { deleteFile } from "../lib/googleCloudStorage.js";
7
7
 
8
8
  const fileSchema = z.object({
9
9
  name: z.string(),
@@ -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 attendanceSchema = z.object({
7
7
  eventId: z.string().optional(),
@@ -1,11 +1,11 @@
1
1
  import { z } from "zod";
2
- import { createTRPCRouter, protectedProcedure, publicProcedure } from "../trpc";
2
+ import { createTRPCRouter, protectedProcedure, publicProcedure } 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 { v4 as uuidv4 } from 'uuid';
6
6
  import { compare, hash } from "bcryptjs";
7
- import { transport } from "../utils/email";
8
- import { prismaWrapper } from "../utils/prismaWrapper";
7
+ import { transport } from "../utils/email.js";
8
+ import { prismaWrapper } from "../utils/prismaWrapper.js";
9
9
 
10
10
  const loginSchema = z.object({
11
11
  username: z.string(),
@@ -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
@@ -482,6 +482,12 @@ export const classRouter = createTRPCRouter({
482
482
  .mutation(async ({ ctx, input }) => {
483
483
  const { classId } = input;
484
484
 
485
+ await prisma.session.deleteMany({
486
+ where: {
487
+ classId,
488
+ },
489
+ });
490
+
485
491
  // Create a new session for the invite code
486
492
  const session = await prisma.session.create({
487
493
  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(),