Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ jobs:
test:
if: github.base_ref == 'main'
runs-on: ubuntu-latest
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}

steps:
- name: Checkout repository
Expand Down
203 changes: 190 additions & 13 deletions bun.lock

Large diffs are not rendered by default.

9 changes: 6 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,29 +42,32 @@
"jest-mock-extended": "^4.0.0",
"lint-staged": "^16.1.2",
"prettier": "^3.6.2",
"prisma": "^6.11.1",
"prisma": "^7.2.0",
"ts-node-dev": "^2.0.0",
"typescript": "^5.8.3",
"typescript-eslint": "^8.36.0"
},
"dependencies": {
"@prisma/client": "^6.11.1",
"@prisma/adapter-pg": "^7.2.0",
"@prisma/client": "^7.2.0",
"@supabase/supabase-js": "^2.50.5",
"@types/cors": "^2.8.19",
"@types/express": "^5.0.3",
"@types/morgan": "^1.9.10",
"@types/multer": "^2.0.0",
"@types/node": "^24.0.13",
"@types/pg": "^8.16.0",
"@types/uuid": "^10.0.0",
"apidoc": "^1.2.0",
"body-parser": "^2.2.0",
"cors": "^2.8.5",
"dotenv": "^17.2.0",
"dotenv": "^17.2.3",
"express": "^5.1.0",
"husky": "^9.1.7",
"jest": "^30.0.4",
"morgan": "^1.10.1",
"multer": "^2.0.1",
"pg": "^8.16.3",
"ts-jest": "^29.4.0",
"ts-node": "^10.9.2",
"uuid": "^11.1.0",
Expand Down
17 changes: 17 additions & 0 deletions prisma.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import dotenv from "dotenv";
import path from "node:path";
import { defineConfig,env } from "prisma/config";

dotenv.config({
path: "./.env",
});

export default defineConfig({
schema: path.join("prisma", "schema.prisma"),
migrations: {
path: path.join("prisma", "migrations"),
},
datasource: {
url: env("DATABASE_URL"),
},
});
4 changes: 1 addition & 3 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@
// learn more about it in the docs: https://pris.ly/d/prisma-schema

generator client {
provider = "prisma-client-js"
provider = "prisma-client"
output = "../src/generated/prisma"
}

datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
directUrl = env("DIRECT_URL")
}

model Member {
Expand Down
11 changes: 8 additions & 3 deletions src/db/client.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { PrismaClient } from "../generated/prisma";
import { PrismaPg } from "@prisma/adapter-pg";
import { PrismaClient } from "../generated/prisma/client";
export * from "../generated/prisma/client";

const prisma = new PrismaClient();
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL,
});
Comment on lines +5 to +7
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Add validation for DATABASE_URL environment variable.

The DATABASE_URL environment variable is used without validation. If it's undefined or invalid, the adapter initialization will fail at runtime, potentially with unclear error messages.

🔎 Proposed fix to add validation
+if (!process.env.DATABASE_URL) {
+  throw new Error("DATABASE_URL environment variable is not set");
+}
+
 const adapter = new PrismaPg({
   connectionString: process.env.DATABASE_URL,
 });

Alternatively, use a more defensive approach with a type assertion:

 const adapter = new PrismaPg({
-  connectionString: process.env.DATABASE_URL,
+  connectionString: process.env.DATABASE_URL as string,
 });
+
+if (!process.env.DATABASE_URL) {
+  throw new Error("DATABASE_URL environment variable is not set");
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL,
});
if (!process.env.DATABASE_URL) {
throw new Error("DATABASE_URL environment variable is not set");
}
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL,
});
🤖 Prompt for AI Agents
In @src/db/client.ts around lines 5-7, The code instantiates PrismaPg with
process.env.DATABASE_URL without validating it, so add a guard to check that
DATABASE_URL is present and non-empty before creating the adapter (e.g., throw a
clear error or exit with a descriptive message if missing/invalid). Modify the
initialization surrounding PrismaPg and the adapter constant (the PrismaPg
constructor call and the adapter variable) to read DATABASE_URL into a local
const, validate it (non-empty string and optionally a basic URI check), and only
pass the validated value into new PrismaPg; if validation fails, surface a clear
error referencing DATABASE_URL.


export { prisma };
const prisma = new PrismaClient({ adapter });

export default prisma;
2 changes: 1 addition & 1 deletion src/services/achievement.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { prisma } from "../db/client";
import prisma from "../db/client";

export const getAchievements = async () => {
return await prisma.achievement.findMany({
Expand Down
3 changes: 2 additions & 1 deletion src/services/interview.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { prisma } from "../db/client"
import prisma from "../db/client";


export const getInterviews = async (page: number = 1, limit: number = 10, verdict : string = "All") => {
const skip = (page - 1) * limit;
Expand Down
2 changes: 1 addition & 1 deletion src/services/member.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { prisma } from "../db/client";
import prisma from "../db/client";
import { ApiError } from "../utils/apiError";

export const getUserByEmail = async(email: string) => {
Expand Down
2 changes: 1 addition & 1 deletion src/services/progress.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { prisma } from "../db/client";
import prisma from "../db/client";

export const getCompletedQuestion = async (memeberId: string) => {
return await prisma.completedQuestion.findMany({
Expand Down
2 changes: 1 addition & 1 deletion src/services/project.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { prisma } from "../db/client";
import prisma from "../db/client";

export const getProjects = async () => {
return await prisma.project.findMany({
Expand Down
4 changes: 2 additions & 2 deletions src/services/question.service.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { prisma } from "../db/client";
import { Difficulty } from "../generated/prisma";
import prisma from "../db/client";
import { Difficulty } from "../generated/prisma/enums";

export const getQuestionByTopicId = async (TopicId: number) => {
return await prisma.question.findMany({
Expand Down
2 changes: 1 addition & 1 deletion src/services/topic.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { prisma } from "../db/client";
import prisma from "../db/client";

export const getTopics = async () => {
return await prisma.topic.findMany();
Expand Down
2 changes: 1 addition & 1 deletion tests/Interview.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { getInterviews, getInterviewById, createInterview, updateInterviewById, deleteInterviewById} from '../src/controllers/interview.controller';
import * as interviewService from '../src/services/interview.service';
import { ApiError } from '../src/utils/apiError';
import { Verdict } from '../src/generated/prisma';
import { Verdict } from '../src/generated/prisma/enums';

describe('getInterviews', () => {
it('should return 200 and all interviews', async () => {
Expand Down
2 changes: 1 addition & 1 deletion tests/Progress.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
} from "../src/controllers/progress.controller";
import * as progressServices from "../src/services/progress.service";
import { Request, Response } from "express";
import { CompletedQuestion } from "../src/generated/prisma";
import { CompletedQuestion } from "../src/generated/prisma/client";
import { ApiError } from "../src/utils/apiError";

beforeEach(() => {
Expand Down
2 changes: 1 addition & 1 deletion tests/Question.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
updateQuestion,
deleteQuestion,
} from "../src/controllers/question.controller";
import { Question } from "../src/generated/prisma";
import { Question } from "../src/generated/prisma/client";
import { ApiError } from "../src/utils/apiError";

beforeEach(() => {
Expand Down
2 changes: 1 addition & 1 deletion tests/Topics.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
} from "../src/controllers/topic.controller";
import * as topicServices from "../src/services/topic.service";
import { ApiError } from "../src/utils/apiError";
import { Topic } from "../src/generated/prisma";
import { Topic } from "../src/generated/prisma/browser";

beforeEach(() => {
jest.clearAllMocks();
Expand Down