Skip to content

Commit c575f05

Browse files
committed
feat: add company, position, skill data support.
1 parent 28c6ef0 commit c575f05

File tree

6 files changed

+250
-38
lines changed

6 files changed

+250
-38
lines changed

__tests__/auth.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ describe("Authentication Configuration", () => {
4545
expect(authOptions.pages).toEqual({
4646
signIn: "/login",
4747
signOut: "/logout",
48+
verifyRequest: "/login/verify",
4849
});
4950
});
5051
});

package-lock.json

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

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
"@mui/material-nextjs": "^6.1.8",
3434
"@next-auth/prisma-adapter": "^1.0.7",
3535
"@next/third-parties": "^15.0.3",
36-
"@prisma/client": "^6.0.0",
36+
"@prisma/client": "^6.0.1",
3737
"classnames": "^2.5.1",
3838
"next": "15.0.3",
3939
"next-auth": "^4.24.10",
@@ -59,7 +59,7 @@
5959
"jest": "^29.7.0",
6060
"jest-environment-jsdom": "^29.7.0",
6161
"prettier": "^3.3.3",
62-
"prisma": "^6.0.0",
62+
"prisma": "^6.0.1",
6363
"ts-jest": "^29.2.5",
6464
"ts-node": "^10.9.2",
6565
"typescript": "^5"
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
/*
2+
Warnings:
3+
4+
- You are about to drop the column `image` on the `User` table. All the data in the column will be lost.
5+
6+
*/
7+
-- AlterTable
8+
ALTER TABLE "User" DROP COLUMN "image",
9+
ADD COLUMN "displayEmail" TEXT,
10+
ADD COLUMN "location" TEXT,
11+
ADD COLUMN "siteImage" TEXT,
12+
ADD COLUMN "siteTitle" TEXT,
13+
ADD COLUMN "title" TEXT;
14+
15+
-- CreateTable
16+
CREATE TABLE "Skill" (
17+
"id" TEXT NOT NULL,
18+
"name" TEXT NOT NULL,
19+
"icon" TEXT,
20+
21+
CONSTRAINT "Skill_pkey" PRIMARY KEY ("id")
22+
);
23+
24+
-- CreateTable
25+
CREATE TABLE "SkillForUser" (
26+
"id" TEXT NOT NULL,
27+
"skillId" TEXT NOT NULL,
28+
"userId" TEXT NOT NULL,
29+
"description" TEXT,
30+
"icon" TEXT,
31+
"yearStarted" INTEGER,
32+
"totalYears" INTEGER,
33+
34+
CONSTRAINT "SkillForUser_pkey" PRIMARY KEY ("id")
35+
);
36+
37+
-- CreateTable
38+
CREATE TABLE "SkillForProject" (
39+
"id" TEXT NOT NULL,
40+
"skillForUserId" TEXT NOT NULL,
41+
"description" TEXT,
42+
"projectId" TEXT NOT NULL,
43+
44+
CONSTRAINT "SkillForProject_pkey" PRIMARY KEY ("id")
45+
);
46+
47+
-- CreateTable
48+
CREATE TABLE "Project" (
49+
"id" TEXT NOT NULL,
50+
"name" TEXT NOT NULL,
51+
"description" TEXT,
52+
"positionId" TEXT,
53+
54+
CONSTRAINT "Project_pkey" PRIMARY KEY ("id")
55+
);
56+
57+
-- CreateTable
58+
CREATE TABLE "Position" (
59+
"id" TEXT NOT NULL,
60+
"title" TEXT NOT NULL,
61+
"startDate" TIMESTAMP(3) NOT NULL,
62+
"endDate" TIMESTAMP(3),
63+
"companyId" TEXT,
64+
65+
CONSTRAINT "Position_pkey" PRIMARY KEY ("id")
66+
);
67+
68+
-- CreateTable
69+
CREATE TABLE "Company" (
70+
"id" TEXT NOT NULL,
71+
"name" TEXT NOT NULL,
72+
"location" TEXT NOT NULL,
73+
"startDate" TIMESTAMP(3) NOT NULL,
74+
"endDate" TIMESTAMP(3),
75+
"userId" TEXT NOT NULL,
76+
77+
CONSTRAINT "Company_pkey" PRIMARY KEY ("id")
78+
);
79+
80+
-- CreateTable
81+
CREATE TABLE "Education" (
82+
"id" TEXT NOT NULL,
83+
"school" TEXT NOT NULL,
84+
"degree" TEXT NOT NULL,
85+
"dateAwarded" TIMESTAMP(3),
86+
"userId" TEXT NOT NULL,
87+
88+
CONSTRAINT "Education_pkey" PRIMARY KEY ("id")
89+
);
90+
91+
-- AddForeignKey
92+
ALTER TABLE "SkillForUser" ADD CONSTRAINT "SkillForUser_skillId_fkey" FOREIGN KEY ("skillId") REFERENCES "Skill"("id") ON DELETE CASCADE ON UPDATE CASCADE;
93+
94+
-- AddForeignKey
95+
ALTER TABLE "SkillForUser" ADD CONSTRAINT "SkillForUser_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
96+
97+
-- AddForeignKey
98+
ALTER TABLE "SkillForProject" ADD CONSTRAINT "SkillForProject_skillForUserId_fkey" FOREIGN KEY ("skillForUserId") REFERENCES "SkillForUser"("id") ON DELETE CASCADE ON UPDATE CASCADE;
99+
100+
-- AddForeignKey
101+
ALTER TABLE "SkillForProject" ADD CONSTRAINT "SkillForProject_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
102+
103+
-- AddForeignKey
104+
ALTER TABLE "Project" ADD CONSTRAINT "Project_positionId_fkey" FOREIGN KEY ("positionId") REFERENCES "Position"("id") ON DELETE SET NULL ON UPDATE CASCADE;
105+
106+
-- AddForeignKey
107+
ALTER TABLE "Position" ADD CONSTRAINT "Position_companyId_fkey" FOREIGN KEY ("companyId") REFERENCES "Company"("id") ON DELETE SET NULL ON UPDATE CASCADE;
108+
109+
-- AddForeignKey
110+
ALTER TABLE "Company" ADD CONSTRAINT "Company_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
111+
112+
-- AddForeignKey
113+
ALTER TABLE "Education" ADD CONSTRAINT "Education_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;

prisma/schema.prisma

Lines changed: 100 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,23 @@ model Session {
4141
}
4242

4343
model User {
44-
id String @id @default(cuid())
44+
id String @id @default(cuid())
4545
name String?
46-
email String? @unique
46+
email String? @unique
4747
emailVerified DateTime?
48-
image String?
49-
createdAt DateTime @default(now())
50-
updatedAt DateTime @default(now()) @updatedAt
51-
slug String? @unique
52-
accounts Account[]
53-
sessions Session[]
48+
createdAt DateTime @default(now())
49+
updatedAt DateTime @default(now()) @updatedAt
50+
siteTitle String? // Used for SEO and open graph tags.
51+
siteImage String? // Used for open graph tags. Should be a URL.
52+
slug String? @unique // Used for profile URL.
53+
title String? // Used for profile title, e.g. "Senior Software Engineer"
54+
displayEmail String? // Used for contact email, displayed on profile.
55+
location String? // Used for location, displayed on profile. Should be a general value, e.g. City, State.
56+
accounts Account[] // Linked authentication providers.
57+
sessions Session[] // Active sessions.
58+
SkillForUser SkillForUser[] // One-to-many relationship with SkillForUser, customized skills per user.
59+
Company Company[] // One-to-many relationship with Company, work experience. Can be multiple companies.
60+
Education Education[] // One-to-many relationship with Education, education history. Can be multiple schools.
5461
}
5562

5663
model VerificationToken {
@@ -60,3 +67,88 @@ model VerificationToken {
6067
6168
@@unique([identifier, token])
6269
}
70+
71+
// Skill is a general skill that can be used by multiple users, e.g. "HTML", "CSS", "JavaScript"
72+
// Not limited to technical skills. Can be used for any skill, e.g. "Public Speaking", "Leadership"
73+
model Skill {
74+
id String @id @default(cuid())
75+
name String
76+
icon String? // Optional icon, e.g., from Iconify.
77+
SkillForUser SkillForUser[] // One-to-many relationship with SkillForUser
78+
}
79+
80+
// SkillForUser is a specific skill that a user has, e.g. "HTML", "CSS", "JavaScript", with additional
81+
// customized information, e.g. description, icon, yearStarted, totalYears. The custom data is specific
82+
// to the user's resume. The skill itself is a general skill that can be used by multiple users.
83+
model SkillForUser {
84+
id String @id @default(cuid())
85+
skill Skill @relation(fields: [skillId], references: [id], onDelete: Cascade)
86+
skillId String
87+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
88+
userId String
89+
description String? // Optional meta about the skill for this user
90+
icon String? // Optional icon, e.g., from Iconify, overrides the icon in Skill if found.
91+
yearStarted Int? // Optional start year of using the skill
92+
totalYears Int? // Optional total years using the skill
93+
SkillForProject SkillForProject[]
94+
}
95+
96+
// SkillForProject is a specific skill that a user has for a specific project, e.g. "HTML", "CSS", "JavaScript",
97+
// with additional customized information, e.g. description. The custom data is specific to the user's resume, within
98+
// the context of the project. The skill itself is a general skill that can be used by multiple users.
99+
model SkillForProject {
100+
id String @id @default(cuid())
101+
skillForUser SkillForUser @relation(fields: [skillForUserId], references: [id], onDelete: Cascade)
102+
skillForUserId String
103+
description String? // Optional meta about the skill for this project. Overrides the description in SkillForUser if found.
104+
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
105+
projectId String
106+
}
107+
108+
// Project is a project that a user has worked on, e.g. "Personal Portfolio", "Company Website", and is specific
109+
// to the context within the Company. The project can have multiple skills associated with it, e.g. "HTML", "CSS", "JavaScript".
110+
model Project {
111+
id String @id @default(cuid())
112+
name String
113+
description String?
114+
skillsForProject SkillForProject[]
115+
Position Position? @relation(fields: [positionId], references: [id])
116+
positionId String?
117+
}
118+
119+
// Position is a position that a user has worked in, e.g. "Software Engineer", "Product Manager", and is specific
120+
// to the context within the Company. The position can have multiple projects associated with it, e.g. "Personal Portfolio",
121+
// "Company Website".
122+
model Position {
123+
id String @id @default(cuid())
124+
title String
125+
startDate DateTime
126+
endDate DateTime?
127+
projects Project[]
128+
Company Company? @relation(fields: [companyId], references: [id])
129+
companyId String?
130+
}
131+
132+
// Company is a company that a user has worked at, e.g. "Google", "Facebook", and is specific to the context within
133+
// the user's resume. The company can have multiple positions associated with it, e.g. "Software Engineer", "Product Manager".
134+
model Company {
135+
id String @id @default(cuid())
136+
name String
137+
location String
138+
startDate DateTime
139+
endDate DateTime?
140+
positions Position[]
141+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
142+
userId String
143+
}
144+
145+
// Education is a school that a user has attended, e.g. "Harvard University", "Stanford University", and is specific
146+
// to the context within the user's resume. For multiple degrees from the same school, the user can add multiple education entries.
147+
model Education {
148+
id String @id @default(cuid())
149+
school String
150+
degree String
151+
dateAwarded DateTime?
152+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
153+
userId String
154+
}

src/lib/auth.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,10 +126,16 @@ export const authOptions: NextAuthOptions = {
126126
}: {
127127
session: NextAuthSession & { user: { id: string } };
128128
token: JWT;
129-
user: AdapterUser;
129+
user: AdapterUser & { slug?: string };
130130
}) {
131131
// Add the user ID to the session for easier database operations.
132132
session.user = { ...session.user, id: user.id, email: user.email };
133+
134+
// Add the user slug to the session if it exists.
135+
if (user.slug) {
136+
session.user.slug = user.slug;
137+
}
138+
133139
return session;
134140
},
135141
},

0 commit comments

Comments
 (0)