Skip to content

Commit eaa95db

Browse files
authored
Merge pull request #5 from call-0f-code/prisma-data-model-changes
Prisma data model changes
2 parents 65058fc + 0815c8f commit eaa95db

6 files changed

Lines changed: 182 additions & 64 deletions

File tree

.env.example

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,13 @@ DATABASE_URL=
44

55
# Direct connection to the database. Used for migrations
66
DIRECT_URL=
7+
8+
# Supabase URL
9+
SUPABASE_URL=
10+
11+
# Supabase service role key
12+
SUPABASE_SERVICE_ROLE_KEY=
13+
14+
# Environment variables for the application
15+
NODE_ENV=development
16+

bun.lock

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,15 @@
88
},
99
"scripts": {
1010
"test": "jest",
11-
"apidoc": "apidoc -c apidoc.json"
11+
"apidoc": "apidoc -c apidoc.json",
12+
"start" : "bun run src/server.ts",
13+
"lint": "eslint src/",
14+
"format": "prettier --write src/",
15+
"lint:fix": "eslint src/ --fix",
16+
"precommit": "lint-staged",
17+
"migrate:first":"bunx prisma migrate dev --name init",
18+
"migrate": "bunx prisma migrate dev",
19+
"generate": "bunx prisma generate"
1220
},
1321
"repository": {
1422
"type": "git",
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
Warnings:
3+
4+
- Added the required column `description` to the `Achievement` table without a default value. This is not possible if the table is not empty.
5+
- Added the required column `updatedAt` to the `Achievement` table without a default value. This is not possible if the table is not empty.
6+
- Made the column `imageUrl` on table `Achievement` required. This step will fail if there are existing NULL values in that column.
7+
- Added the required column `updatedAt` to the `Project` table without a default value. This is not possible if the table is not empty.
8+
- Added the required column `updatedAt` to the `Question` table without a default value. This is not possible if the table is not empty.
9+
10+
*/
11+
-- AlterTable
12+
ALTER TABLE "Achievement" ADD COLUMN "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
13+
ADD COLUMN "createdById" TEXT,
14+
ADD COLUMN "description" TEXT NOT NULL,
15+
ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL,
16+
ADD COLUMN "updatedById" TEXT,
17+
ALTER COLUMN "imageUrl" SET NOT NULL;
18+
19+
-- AlterTable
20+
ALTER TABLE "Member" ADD COLUMN "approvedById" TEXT;
21+
22+
-- AlterTable
23+
ALTER TABLE "Project" ADD COLUMN "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
24+
ADD COLUMN "createdById" TEXT,
25+
ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL,
26+
ADD COLUMN "updatedById" TEXT;
27+
28+
-- AlterTable
29+
ALTER TABLE "Question" ADD COLUMN "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
30+
ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL,
31+
ADD COLUMN "updatedById" TEXT;
32+
33+
-- AlterTable
34+
ALTER TABLE "Topic" ADD COLUMN "updatedById" TEXT;
35+
36+
-- AddForeignKey
37+
ALTER TABLE "Member" ADD CONSTRAINT "Member_approvedById_fkey" FOREIGN KEY ("approvedById") REFERENCES "Member"("id") ON DELETE SET NULL ON UPDATE CASCADE;
38+
39+
-- AddForeignKey
40+
ALTER TABLE "Achievement" ADD CONSTRAINT "Achievement_createdById_fkey" FOREIGN KEY ("createdById") REFERENCES "Member"("id") ON DELETE SET NULL ON UPDATE CASCADE;
41+
42+
-- AddForeignKey
43+
ALTER TABLE "Achievement" ADD CONSTRAINT "Achievement_updatedById_fkey" FOREIGN KEY ("updatedById") REFERENCES "Member"("id") ON DELETE SET NULL ON UPDATE CASCADE;
44+
45+
-- AddForeignKey
46+
ALTER TABLE "Project" ADD CONSTRAINT "Project_createdById_fkey" FOREIGN KEY ("createdById") REFERENCES "Member"("id") ON DELETE SET NULL ON UPDATE CASCADE;
47+
48+
-- AddForeignKey
49+
ALTER TABLE "Project" ADD CONSTRAINT "Project_updatedById_fkey" FOREIGN KEY ("updatedById") REFERENCES "Member"("id") ON DELETE SET NULL ON UPDATE CASCADE;
50+
51+
-- AddForeignKey
52+
ALTER TABLE "Topic" ADD CONSTRAINT "Topic_updatedById_fkey" FOREIGN KEY ("updatedById") REFERENCES "Member"("id") ON DELETE SET NULL ON UPDATE CASCADE;
53+
54+
-- AddForeignKey
55+
ALTER TABLE "Question" ADD CONSTRAINT "Question_updatedById_fkey" FOREIGN KEY ("updatedById") REFERENCES "Member"("id") ON DELETE SET NULL ON UPDATE CASCADE;

prisma/schema.prisma

Lines changed: 103 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
// This is your Prisma schema file,
22
// learn more about it in the docs: https://pris.ly/d/prisma-schema
33

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-
74
generator client {
85
provider = "prisma-client-js"
96
output = "../src/generated/prisma"
@@ -16,12 +13,12 @@ datasource db {
1613
}
1714

1815
model Member {
19-
id String @id @default(uuid())
16+
id String @id @default(uuid())
2017
name String
21-
email String @unique
22-
phone String? // Single phone number
18+
email String @unique
19+
phone String? // Single phone number
2320
bio String?
24-
profilePhoto String? // URL to profile photo
21+
profilePhoto String? // URL to profile photo
2522
github String?
2623
linkedin String?
2724
twitter String?
@@ -30,44 +27,67 @@ model Member {
3027
codechef String?
3128
codeforces String?
3229
passoutYear DateTime
33-
isApproved Boolean @default(false)
34-
isManager Boolean @default(false)
35-
createdAt DateTime @default(now())
36-
updatedAt DateTime @updatedAt
37-
38-
// Relations
39-
accounts Account[]
40-
achievements MemberAchievement[]
41-
projects MemberProject[]
42-
topicsCreated Topic[] @relation("MemberTopics")
43-
questionsCreated Question[] @relation("MemberQuestionsCreated")
44-
interviews InterviewExperience[]
45-
completedQs CompletedQuestion[]
30+
isApproved Boolean @default(false)
31+
isManager Boolean @default(false)
32+
createdAt DateTime @default(now())
33+
updatedAt DateTime @updatedAt
34+
35+
// Approval audit (self-reference)
36+
approvedBy Member? @relation("MemberApprovals", fields: [approvedById], references: [id])
37+
approvedById String?
38+
approvedMembers Member[] @relation("MemberApprovals")
39+
40+
// Authentication & Relations
41+
accounts Account[]
42+
achievements MemberAchievement[]
43+
projects MemberProject[]
44+
interviews InterviewExperience[]
45+
completedQs CompletedQuestion[]
46+
47+
// Back-relations for audit fields
48+
createdTopics Topic[] @relation("TopicCreatedBy")
49+
updatedTopics Topic[] @relation("TopicUpdatedBy")
50+
createdQuestions Question[] @relation("QuestionCreatedBy")
51+
updatedQuestions Question[] @relation("QuestionUpdatedBy")
52+
createdAchievements Achievement[] @relation("AchievementCreatedBy")
53+
updatedAchievements Achievement[] @relation("AchievementUpdatedBy")
54+
createdProjects Project[] @relation("ProjectCreatedBy")
55+
updatedProjects Project[] @relation("ProjectUpdatedBy")
4656
}
4757

4858
model Account {
49-
id String @id @default(uuid())
59+
id String @id @default(uuid())
5060
provider String
5161
providerAccountId String
52-
password String? // for email/password auth
62+
password String? // for email/password auth
5363
accessToken String?
5464
refreshToken String?
5565
expiresAt DateTime?
56-
createdAt DateTime @default(now())
57-
updatedAt DateTime @updatedAt
66+
createdAt DateTime @default(now())
67+
updatedAt DateTime @updatedAt
5868
59-
member Member @relation(fields: [memberId], references: [id], onDelete: Cascade)
69+
member Member @relation(fields: [memberId], references: [id], onDelete: Cascade)
6070
memberId String
6171
6272
@@unique([provider, providerAccountId])
6373
}
6474

6575
model Achievement {
66-
id Int @id @default(autoincrement())
67-
title String
68-
achievedAt DateTime
69-
imageUrl String?
70-
members MemberAchievement[]
76+
id Int @id @default(autoincrement())
77+
title String
78+
description String
79+
achievedAt DateTime
80+
imageUrl String
81+
82+
// Audit fields
83+
createdBy Member? @relation("AchievementCreatedBy", fields: [createdById], references: [id], onDelete: SetNull)
84+
createdById String?
85+
createdAt DateTime @default(now())
86+
updatedBy Member? @relation("AchievementUpdatedBy", fields: [updatedById], references: [id], onDelete: SetNull)
87+
updatedById String?
88+
updatedAt DateTime @updatedAt
89+
90+
members MemberAchievement[]
7191
}
7292

7393
model MemberAchievement {
@@ -80,46 +100,66 @@ model MemberAchievement {
80100
}
81101

82102
model Project {
83-
id Int @id @default(autoincrement())
84-
name String
85-
imageUrl String?
86-
githubUrl String?
87-
deployUrl String?
88-
members MemberProject[]
103+
id Int @id @default(autoincrement())
104+
name String
105+
imageUrl String?
106+
githubUrl String?
107+
deployUrl String?
108+
109+
// Audit fields
110+
createdBy Member? @relation("ProjectCreatedBy", fields: [createdById], references: [id], onDelete: SetNull)
111+
createdById String?
112+
createdAt DateTime @default(now())
113+
updatedBy Member? @relation("ProjectUpdatedBy", fields: [updatedById], references: [id], onDelete: SetNull)
114+
updatedById String?
115+
updatedAt DateTime @updatedAt
116+
117+
members MemberProject[]
89118
}
90119

91120
model MemberProject {
92-
member Member @relation(fields: [memberId], references: [id], onDelete: Cascade)
121+
member Member @relation(fields: [memberId], references: [id], onDelete: Cascade)
93122
memberId String
94-
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
123+
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
95124
projectId Int
96125
97126
@@id([memberId, projectId])
98127
}
99128

100129
model Topic {
101-
id Int @id @default(autoincrement())
130+
id Int @id @default(autoincrement())
102131
title String
103132
description String
104-
/// Who created this topic; optional to allow system-generated topics or imports
105-
createdBy Member? @relation("MemberTopics", fields: [createdById], references: [id], onDelete: SetNull)
133+
134+
// Audit fields
135+
createdBy Member? @relation("TopicCreatedBy", fields: [createdById], references: [id], onDelete: SetNull)
106136
createdById String?
107-
createdAt DateTime @default(now())
108-
updatedAt DateTime @updatedAt
109-
questions Question[]
137+
createdAt DateTime @default(now())
138+
updatedBy Member? @relation("TopicUpdatedBy", fields: [updatedById], references: [id], onDelete: SetNull)
139+
updatedById String?
140+
updatedAt DateTime @updatedAt
141+
142+
questions Question[]
110143
}
111144

112145
model Question {
113146
id Int @id @default(autoincrement())
114147
questionName String
115148
difficulty Difficulty
116149
link String
117-
topic Topic @relation(fields: [topicId], references: [id], onDelete: Cascade)
118-
topicId Int
119-
// Who added this question; optional in case the member is deleted
120-
createdBy Member? @relation("MemberQuestionsCreated", fields: [createdById], references: [id], onDelete: SetNull)
121-
createdById String?
122-
completedBy CompletedQuestion[]
150+
151+
topic Topic @relation(fields: [topicId], references: [id], onDelete: Cascade)
152+
topicId Int
153+
154+
// Audit fields
155+
createdBy Member? @relation("QuestionCreatedBy", fields: [createdById], references: [id], onDelete: SetNull)
156+
createdById String?
157+
createdAt DateTime @default(now())
158+
updatedBy Member? @relation("QuestionUpdatedBy", fields: [updatedById], references: [id], onDelete: SetNull)
159+
updatedById String?
160+
updatedAt DateTime @updatedAt
161+
162+
completedBy CompletedQuestion[]
123163
}
124164

125165
enum Difficulty {
@@ -129,26 +169,27 @@ enum Difficulty {
129169
}
130170

131171
model InterviewExperience {
132-
id Int @id @default(autoincrement())
133-
company String
134-
role String
135-
verdict Verdict
136-
content String
172+
id Int @id @default(autoincrement())
173+
company String
174+
role String
175+
verdict Verdict
176+
content String
137177
isAnonymous Boolean
138-
member Member @relation(fields: [memberId], references: [id], onDelete: Cascade)
139-
memberId String
178+
member Member @relation(fields: [memberId], references: [id], onDelete: Cascade)
179+
memberId String
140180
}
181+
141182
enum Verdict {
142183
Selected
143184
Rejected
144185
Pending
145186
}
146187

147188
model CompletedQuestion {
148-
member Member @relation(fields: [memberId], references: [id], onDelete: Cascade)
149-
memberId String
150-
question Question @relation(fields: [questionId], references: [id], onDelete: Cascade)
151-
questionId Int
189+
member Member @relation(fields: [memberId], references: [id], onDelete: Cascade)
190+
memberId String
191+
question Question @relation(fields: [questionId], references: [id], onDelete: Cascade)
192+
questionId Int
152193
153194
@@id([memberId, questionId])
154-
}
195+
}

tests/Sample.test.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ describe('createProject', () => {
1919
imageUrl: 'https://example.com/image.png',
2020
githubUrl: 'https://github.com/example/eventhub',
2121
deployUrl: 'https://eventhub.example.com',
22+
createdById: null,
23+
createdAt: new Date(),
24+
updatedById: null,
25+
updatedAt: new Date(),
26+
2227
};
2328
//this stops the call from doing to database and returns the value as resolved promise
2429
prismaMock.project.create.mockResolvedValue(mockCreatedProject);

0 commit comments

Comments
 (0)