@studious-lms/server 1.0.1 → 1.0.3

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 (66) hide show
  1. package/dist/index.js +4 -4
  2. package/dist/middleware/auth.js +1 -1
  3. package/dist/middleware/logging.js +1 -1
  4. package/dist/routers/_app.js +1 -1
  5. package/dist/routers/agenda.js +1 -1
  6. package/dist/routers/announcement.js +1 -1
  7. package/dist/routers/assignment.js +3 -3
  8. package/dist/routers/attendance.js +1 -1
  9. package/dist/routers/auth.js +2 -2
  10. package/dist/routers/class.js +2 -2
  11. package/dist/routers/event.js +1 -1
  12. package/dist/routers/file.js +2 -2
  13. package/dist/routers/section.js +1 -1
  14. package/dist/routers/user.js +2 -2
  15. package/dist/trpc.js +2 -2
  16. package/package.json +1 -6
  17. package/prisma/schema.prisma +228 -0
  18. package/src/exportType.ts +9 -0
  19. package/src/index.ts +94 -0
  20. package/src/lib/fileUpload.ts +163 -0
  21. package/src/lib/googleCloudStorage.ts +94 -0
  22. package/src/lib/prisma.ts +16 -0
  23. package/src/lib/thumbnailGenerator.ts +185 -0
  24. package/src/logger.ts +163 -0
  25. package/src/middleware/auth.ts +191 -0
  26. package/src/middleware/logging.ts +54 -0
  27. package/src/routers/_app.ts +34 -0
  28. package/src/routers/agenda.ts +79 -0
  29. package/src/routers/announcement.ts +134 -0
  30. package/src/routers/assignment.ts +1614 -0
  31. package/src/routers/attendance.ts +284 -0
  32. package/src/routers/auth.ts +286 -0
  33. package/src/routers/class.ts +753 -0
  34. package/src/routers/event.ts +509 -0
  35. package/src/routers/file.ts +96 -0
  36. package/src/routers/section.ts +138 -0
  37. package/src/routers/user.ts +82 -0
  38. package/src/socket/handlers.ts +143 -0
  39. package/src/trpc.ts +90 -0
  40. package/src/types/trpc.ts +15 -0
  41. package/src/utils/email.ts +11 -0
  42. package/src/utils/generateInviteCode.ts +8 -0
  43. package/src/utils/logger.ts +156 -0
  44. package/tsconfig.json +17 -0
  45. package/generated/prisma/client.d.ts +0 -1
  46. package/generated/prisma/client.js +0 -4
  47. package/generated/prisma/default.d.ts +0 -1
  48. package/generated/prisma/default.js +0 -4
  49. package/generated/prisma/edge.d.ts +0 -1
  50. package/generated/prisma/edge.js +0 -389
  51. package/generated/prisma/index-browser.js +0 -375
  52. package/generated/prisma/index.d.ts +0 -34865
  53. package/generated/prisma/index.js +0 -410
  54. package/generated/prisma/libquery_engine-darwin-arm64.dylib.node +0 -0
  55. package/generated/prisma/package.json +0 -140
  56. package/generated/prisma/runtime/edge-esm.js +0 -34
  57. package/generated/prisma/runtime/edge.js +0 -34
  58. package/generated/prisma/runtime/index-browser.d.ts +0 -370
  59. package/generated/prisma/runtime/index-browser.js +0 -16
  60. package/generated/prisma/runtime/library.d.ts +0 -3647
  61. package/generated/prisma/runtime/library.js +0 -146
  62. package/generated/prisma/runtime/react-native.js +0 -83
  63. package/generated/prisma/runtime/wasm.js +0 -35
  64. package/generated/prisma/schema.prisma +0 -304
  65. package/generated/prisma/wasm.d.ts +0 -1
  66. package/generated/prisma/wasm.js +0 -375
package/dist/index.js CHANGED
@@ -9,10 +9,10 @@ const socket_io_1 = require("socket.io");
9
9
  const cors_1 = __importDefault(require("cors"));
10
10
  const dotenv_1 = __importDefault(require("dotenv"));
11
11
  const express_2 = require("@trpc/server/adapters/express");
12
- const _app_1 = require("@routers/_app");
13
- const trpc_1 = require("@/trpc");
14
- const logger_1 = require("@utils/logger");
15
- const handlers_1 = require("@/socket/handlers");
12
+ const _app_1 = require("./routers/_app");
13
+ const trpc_1 = require("./trpc");
14
+ const logger_1 = require("./utils/logger");
15
+ const handlers_1 = require("./socket/handlers");
16
16
  dotenv_1.default.config();
17
17
  const app = (0, express_1.default)();
18
18
  // CORS middleware
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createAuthMiddleware = void 0;
4
4
  const server_1 = require("@trpc/server");
5
- const prisma_1 = require("@lib/prisma");
5
+ const prisma_1 = require("../lib/prisma");
6
6
  const createAuthMiddleware = (t) => {
7
7
  // Auth middleware
8
8
  const isAuthed = t.middleware(async ({ next, ctx }) => {
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createLoggingMiddleware = void 0;
4
- const logger_1 = require("@/logger");
4
+ const logger_1 = require("../utils/logger");
5
5
  const createLoggingMiddleware = (t) => {
6
6
  return t.middleware(async ({ path, type, next, ctx }) => {
7
7
  const start = Date.now();
@@ -6,7 +6,7 @@ const class_1 = require("./class");
6
6
  const announcement_1 = require("./announcement");
7
7
  const assignment_1 = require("./assignment");
8
8
  const user_1 = require("./user");
9
- const trpc_2 = require("@/trpc");
9
+ const trpc_2 = require("../trpc");
10
10
  const section_1 = require("./section");
11
11
  const attendance_1 = require("./attendance");
12
12
  const event_1 = require("./event");
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.agendaRouter = void 0;
4
4
  const zod_1 = require("zod");
5
5
  const trpc_1 = require("../trpc");
6
- const prisma_1 = require("@lib/prisma");
6
+ const prisma_1 = require("../lib/prisma");
7
7
  const server_1 = require("@trpc/server");
8
8
  const date_fns_1 = require("date-fns");
9
9
  exports.agendaRouter = (0, trpc_1.createTRPCRouter)({
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.announcementRouter = void 0;
4
4
  const zod_1 = require("zod");
5
5
  const trpc_1 = require("../trpc");
6
- const prisma_1 = require("@lib/prisma");
6
+ const prisma_1 = require("../lib/prisma");
7
7
  const server_1 = require("@trpc/server");
8
8
  const AnnouncementSelect = {
9
9
  id: true,
@@ -4,9 +4,9 @@ exports.assignmentRouter = void 0;
4
4
  const zod_1 = require("zod");
5
5
  const trpc_1 = require("../trpc");
6
6
  const server_1 = require("@trpc/server");
7
- const prisma_1 = require("@lib/prisma");
8
- const fileUpload_1 = require("@lib/fileUpload");
9
- const googleCloudStorage_1 = require("@lib/googleCloudStorage");
7
+ const prisma_1 = require("../lib/prisma");
8
+ const fileUpload_1 = require("../lib/fileUpload");
9
+ const googleCloudStorage_1 = require("../lib/googleCloudStorage");
10
10
  const fileSchema = zod_1.z.object({
11
11
  name: zod_1.z.string(),
12
12
  type: zod_1.z.string(),
@@ -4,7 +4,7 @@ exports.attendanceRouter = void 0;
4
4
  const zod_1 = require("zod");
5
5
  const trpc_1 = require("../trpc");
6
6
  const server_1 = require("@trpc/server");
7
- const prisma_1 = require("@lib/prisma");
7
+ const prisma_1 = require("../lib/prisma");
8
8
  const attendanceSchema = zod_1.z.object({
9
9
  eventId: zod_1.z.string().optional(),
10
10
  present: zod_1.z.array(zod_1.z.object({ id: zod_1.z.string(), username: zod_1.z.string() })),
@@ -4,10 +4,10 @@ exports.authRouter = void 0;
4
4
  const zod_1 = require("zod");
5
5
  const trpc_1 = require("../trpc");
6
6
  const server_1 = require("@trpc/server");
7
- const prisma_1 = require("@lib/prisma");
7
+ const prisma_1 = require("../lib/prisma");
8
8
  const uuid_1 = require("uuid");
9
9
  const bcryptjs_1 = require("bcryptjs");
10
- const email_1 = require("@/utils/email");
10
+ const email_1 = require("../utils/email");
11
11
  const loginSchema = zod_1.z.object({
12
12
  username: zod_1.z.string(),
13
13
  password: zod_1.z.string(),
@@ -3,9 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.classRouter = void 0;
4
4
  const zod_1 = require("zod");
5
5
  const trpc_1 = require("../trpc");
6
- const prisma_1 = require("@lib/prisma");
6
+ const prisma_1 = require("../lib/prisma");
7
7
  const server_1 = require("@trpc/server");
8
- const generateInviteCode_1 = require("@/utils/generateInviteCode");
8
+ const generateInviteCode_1 = require("../utils/generateInviteCode");
9
9
  exports.classRouter = (0, trpc_1.createTRPCRouter)({
10
10
  getAll: trpc_1.protectedProcedure
11
11
  .query(async ({ ctx }) => {
@@ -4,7 +4,7 @@ exports.eventRouter = void 0;
4
4
  const zod_1 = require("zod");
5
5
  const trpc_1 = require("../trpc");
6
6
  const server_1 = require("@trpc/server");
7
- const prisma_1 = require("@lib/prisma");
7
+ const prisma_1 = require("../lib/prisma");
8
8
  const date_fns_1 = require("date-fns");
9
9
  const eventSchema = zod_1.z.object({
10
10
  name: zod_1.z.string().optional(),
@@ -4,8 +4,8 @@ exports.fileRouter = void 0;
4
4
  const zod_1 = require("zod");
5
5
  const trpc_1 = require("../trpc");
6
6
  const server_1 = require("@trpc/server");
7
- const googleCloudStorage_1 = require("@/lib/googleCloudStorage");
8
- const prisma_1 = require("@lib/prisma");
7
+ const googleCloudStorage_1 = require("../lib/googleCloudStorage");
8
+ const prisma_1 = require("../lib/prisma");
9
9
  exports.fileRouter = (0, trpc_1.createTRPCRouter)({
10
10
  getSignedUrl: trpc_1.protectedProcedure
11
11
  .input(zod_1.z.object({
@@ -4,7 +4,7 @@ exports.sectionRouter = void 0;
4
4
  const zod_1 = require("zod");
5
5
  const trpc_1 = require("../trpc");
6
6
  const server_1 = require("@trpc/server");
7
- const prisma_1 = require("@lib/prisma");
7
+ const prisma_1 = require("../lib/prisma");
8
8
  const createSectionSchema = zod_1.z.object({
9
9
  classId: zod_1.z.string(),
10
10
  name: zod_1.z.string(),
@@ -4,8 +4,8 @@ exports.userRouter = void 0;
4
4
  const zod_1 = require("zod");
5
5
  const trpc_1 = require("../trpc");
6
6
  const server_1 = require("@trpc/server");
7
- const prisma_1 = require("@lib/prisma");
8
- const fileUpload_1 = require("@lib/fileUpload");
7
+ const prisma_1 = require("../lib/prisma");
8
+ const fileUpload_1 = require("../lib/fileUpload");
9
9
  const fileSchema = zod_1.z.object({
10
10
  name: zod_1.z.string(),
11
11
  type: zod_1.z.string(),
package/dist/trpc.js CHANGED
@@ -3,8 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createCallerFactory = exports.protectedTeacherProcedure = exports.protectedClassMemberProcedure = exports.protectedProcedure = exports.publicProcedure = exports.createTRPCRouter = exports.t = exports.createTRPCContext = void 0;
4
4
  const server_1 = require("@trpc/server");
5
5
  const zod_1 = require("zod");
6
- const logger_1 = require("@utils/logger");
7
- const prisma_1 = require("@lib/prisma");
6
+ const logger_1 = require("./utils/logger");
7
+ const prisma_1 = require("./lib/prisma");
8
8
  const logging_1 = require("./middleware/logging");
9
9
  const auth_1 = require("./middleware/auth");
10
10
  const zod_2 = require("zod");
package/package.json CHANGED
@@ -1,14 +1,9 @@
1
1
  {
2
2
  "name": "@studious-lms/server",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "Backend server for Studious application",
5
5
  "main": "dist/exportType.js",
6
6
  "types": "dist/exportType.d.ts",
7
- "files": [
8
- "dist/**/*",
9
- "generated/**/*",
10
- "README.md"
11
- ],
12
7
  "scripts": {
13
8
  "dev": "ts-node-dev -r tsconfig-paths/register --respawn --transpile-only src/index.ts",
14
9
  "build": "tsc",
@@ -0,0 +1,228 @@
1
+ // This is your Prisma schema file,
2
+ // learn more about it in the docs: https://pris.ly/d/prisma-schema
3
+
4
+ // Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?
5
+ // Try Prisma Accelerate: https://pris.ly/cli/accelerate-init
6
+
7
+ generator client {
8
+ provider = "prisma-client-js"
9
+ // output = "../generated/prisma"
10
+ }
11
+
12
+ datasource db {
13
+ provider = "postgresql"
14
+ url = env("DATABASE_URL")
15
+ }
16
+
17
+ enum AssignmentType {
18
+ HOMEWORK
19
+ QUIZ
20
+ TEST
21
+ PROJECT
22
+ ESSAY
23
+ DISCUSSION
24
+ PRESENTATION
25
+ LAB
26
+ OTHER
27
+ }
28
+
29
+
30
+ model User {
31
+ id String @id @default(uuid())
32
+ username String
33
+ email String
34
+ password String
35
+ profile UserProfile?
36
+ verified Boolean @default(false)
37
+
38
+ profileId String? @unique
39
+
40
+ teacherIn Class[] @relation("UserTeacherToClass")
41
+ studentIn Class[] @relation("UserStudentToClass")
42
+
43
+ submissions Submission[]
44
+ sessions Session[]
45
+ files File[]
46
+ assignments Assignment[]
47
+ events Event[]
48
+ announcements Announcement[]
49
+
50
+ presentAttendance Attendance[] @relation("PresentAttendance")
51
+ lateAttendance Attendance[] @relation("LateAttendance")
52
+ absentAttendance Attendance[] @relation("AbsentAttendance")
53
+ }
54
+
55
+ model UserProfile {
56
+ id String @id @default(uuid())
57
+ userId String @unique
58
+ user User? @relation(fields: [userId], references: [id])
59
+
60
+ }
61
+
62
+ model Class {
63
+ id String @id @default(uuid())
64
+ name String
65
+ subject String
66
+ color String? @default("#3B82F6")
67
+ section String
68
+ announcements Announcement[]
69
+ assignments Assignment[]
70
+ attendance Attendance[]
71
+ events Event[]
72
+ sections Section[]
73
+ sessions Session[]
74
+ students User[] @relation("UserStudentToClass")
75
+ teachers User[] @relation("UserTeacherToClass")
76
+ markSchemes MarkScheme[] @relation("ClassToMarkScheme")
77
+ gradingBoundaries GradingBoundary[] @relation("ClassToGradingBoundary")
78
+ }
79
+
80
+ model MarkScheme {
81
+ id String @id @default(uuid())
82
+ classId String
83
+ class Class[] @relation("ClassToMarkScheme")
84
+ structured String
85
+ assignments Assignment[]
86
+ }
87
+
88
+ model GradingBoundary {
89
+ id String @id @default(uuid())
90
+ classId String
91
+ class Class[] @relation("ClassToGradingBoundary")
92
+ structured String
93
+ assignments Assignment[]
94
+ }
95
+
96
+ model File {
97
+ id String @id @default(uuid())
98
+ name String
99
+ path String
100
+ size Int?
101
+ type String
102
+ user User? @relation(fields: [userId], references: [id])
103
+ userId String?
104
+ uploadedAt DateTime? @default(now())
105
+
106
+ // Thumbnail relationship
107
+ thumbnail File? @relation("Thumbnail", fields: [thumbnailId], references: [id])
108
+ thumbnailId String? @unique
109
+ originalFile File? @relation("Thumbnail")
110
+
111
+ assignment Assignment? @relation(fields: [assignmentId], references: [id], onDelete: Cascade)
112
+ assignmentId String?
113
+
114
+ submission Submission? @relation("SubmissionFile", fields: [submissionId], references: [id], onDelete: Cascade)
115
+ submissionId String?
116
+
117
+ annotations Submission? @relation("SubmissionAnnotations", fields: [annotationId], references: [id], onDelete: Cascade)
118
+ annotationId String?
119
+ }
120
+
121
+ model Assignment {
122
+ id String @id @default(uuid())
123
+ title String
124
+ instructions String
125
+ dueDate DateTime
126
+ createdAt DateTime? @default(now())
127
+ modifiedAt DateTime? @updatedAt
128
+ teacher User @relation(fields: [teacherId], references: [id], onDelete: NoAction)
129
+ teacherId String
130
+ class Class @relation(fields: [classId], references: [id], onDelete: Cascade)
131
+ classId String
132
+ attachments File[]
133
+ submissions Submission[]
134
+ section Section? @relation(fields: [sectionId], references: [id], onDelete: Cascade)
135
+ sectionId String?
136
+ graded Boolean @default(false)
137
+ maxGrade Int? @default(0)
138
+ weight Float @default(1)
139
+ type AssignmentType @default(HOMEWORK)
140
+ eventAttached Event? @relation(fields: [eventId], references: [id], onDelete: NoAction)
141
+ eventId String?
142
+ markScheme MarkScheme? @relation(fields: [markSchemeId], references: [id], onDelete: Cascade)
143
+ markSchemeId String?
144
+ gradingBoundary GradingBoundary? @relation(fields: [gradingBoundaryId], references: [id], onDelete: Cascade)
145
+ gradingBoundaryId String?
146
+ }
147
+
148
+ model Announcement {
149
+ id String @id @default(uuid())
150
+ remarks String
151
+ teacher User @relation(fields: [teacherId], references: [id])
152
+ teacherId String
153
+ createdAt DateTime @default(now())
154
+ class Class @relation(fields: [classId], references: [id], onDelete: Cascade)
155
+ classId String
156
+ }
157
+
158
+ model Submission {
159
+ id String @id @default(uuid())
160
+ createdAt DateTime @default(now())
161
+ modifiedAt DateTime @default(now())
162
+
163
+ assignment Assignment @relation(fields: [assignmentId], references: [id], onDelete: Cascade)
164
+ assignmentId String
165
+
166
+ student User @relation(fields: [studentId], references: [id])
167
+ studentId String
168
+
169
+ attachments File[] @relation("SubmissionFile")
170
+ annotations File[] @relation("SubmissionAnnotations")
171
+
172
+ gradeReceived Int?
173
+
174
+ rubricState String?
175
+
176
+ submittedAt DateTime?
177
+ submitted Boolean? @default(false)
178
+ returned Boolean? @default(false)
179
+ }
180
+
181
+ model Section {
182
+ id String @id @default(uuid())
183
+ name String
184
+ classId String
185
+ class Class @relation(fields: [classId], references: [id], onDelete: Cascade)
186
+ assignments Assignment[]
187
+ }
188
+
189
+ model Session {
190
+ id String @id @default(uuid())
191
+ createdAt DateTime? @default(now())
192
+ expiresAt DateTime?
193
+ userId String?
194
+ user User? @relation(fields: [userId], references: [id], onDelete: NoAction)
195
+ classId String?
196
+ class Class? @relation(fields: [classId], references: [id], onDelete: Cascade)
197
+ }
198
+
199
+ model Event {
200
+ id String @id @default(uuid())
201
+ name String?
202
+ startTime DateTime
203
+ endTime DateTime
204
+ location String?
205
+ remarks String?
206
+ userId String?
207
+ user User? @relation(fields: [userId], references: [id], onDelete: Cascade)
208
+ classId String?
209
+ class Class? @relation(fields: [classId], references: [id], onDelete: Cascade)
210
+ color String? @default("#3B82F6")
211
+ assignmentsAttached Assignment[]
212
+ attendance Attendance[]
213
+ }
214
+
215
+ model Attendance {
216
+ id String @id @default(uuid())
217
+ date DateTime @default(now())
218
+
219
+ class Class @relation(fields: [classId], references: [id], onDelete: Cascade)
220
+ classId String
221
+
222
+ event Event? @relation(fields: [eventId], references: [id], onDelete: Cascade)
223
+ eventId String?
224
+
225
+ present User[] @relation("PresentAttendance")
226
+ late User[] @relation("LateAttendance")
227
+ absent User[] @relation("AbsentAttendance")
228
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Export types for the server
3
+ * This is used to export the types for the server
4
+ * to the client via npmjs
5
+ */
6
+
7
+ export type { AppRouter } from "./routers/_app";
8
+ export type { RouterInputs } from "./routers/_app";
9
+ export type { RouterOutputs } from "./routers/_app";
package/src/index.ts ADDED
@@ -0,0 +1,94 @@
1
+ import express from 'express';
2
+ import type { Request, Response } from 'express';
3
+ import { createServer } from 'http';
4
+ import { Server } from 'socket.io';
5
+ import cors from 'cors';
6
+ import dotenv from 'dotenv';
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';
12
+
13
+ dotenv.config();
14
+
15
+ const app = express();
16
+
17
+ // CORS middleware
18
+ app.use(cors({
19
+ origin: process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000',
20
+ credentials: true,
21
+ }));
22
+
23
+ // Response time logging middleware
24
+ app.use((req, res, next) => {
25
+ const start = Date.now();
26
+ res.on('finish', () => {
27
+ const duration = Date.now() - start;
28
+ logger.info('Request completed', {
29
+ method: req.method,
30
+ path: req.path,
31
+ statusCode: res.statusCode,
32
+ duration: `${duration}ms`
33
+ });
34
+ });
35
+ next();
36
+ });
37
+
38
+ // Create HTTP server
39
+ const httpServer = createServer(app);
40
+
41
+ // Setup Socket.IO
42
+ const io = new Server(httpServer, {
43
+ cors: {
44
+ origin: process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000',
45
+ methods: ['GET', 'POST'],
46
+ credentials: true,
47
+ allowedHeaders: ['Access-Control-Allow-Origin']
48
+ },
49
+ transports: ['websocket', 'polling'],
50
+ pingTimeout: 60000,
51
+ pingInterval: 25000,
52
+ connectTimeout: 45000,
53
+ path: '/socket.io/',
54
+ allowEIO3: true
55
+ });
56
+
57
+ // Add server-level logging
58
+ io.engine.on('connection_error', (err) => {
59
+ logger.error('Socket connection error', { error: err.message });
60
+ });
61
+
62
+ // Setup socket handlers
63
+ setupSocketHandlers(io);
64
+
65
+ // Create caller
66
+ const createCaller = createCallerFactory(appRouter);
67
+
68
+ // Setup tRPC middleware
69
+ app.use(
70
+ '/trpc',
71
+ createExpressMiddleware({
72
+ router: appRouter,
73
+ createContext: async ({ req, res }: { req: Request; res: Response }) => {
74
+ return createTRPCContext({ req, res });
75
+ },
76
+ })
77
+ );
78
+
79
+ const PORT = process.env.PORT || 3001;
80
+
81
+ httpServer.listen(PORT, () => {
82
+ logger.info(`Server running on port ${PORT}`, {
83
+ port: PORT,
84
+ services: ['tRPC', 'Socket.IO']
85
+ });
86
+ });
87
+
88
+ // log all env variables
89
+ logger.info('Configurations', {
90
+ NODE_ENV: process.env.NODE_ENV,
91
+ PORT: process.env.PORT,
92
+ NEXT_PUBLIC_APP_URL: process.env.NEXT_PUBLIC_APP_URL,
93
+ LOG_MODE: process.env.LOG_MODE,
94
+ });