Skip to content

Commit 55d3efc

Browse files
committed
feat(db): add mockInterviews and resumeViews schema
1 parent 220e149 commit 55d3efc

1 file changed

Lines changed: 102 additions & 37 deletions

File tree

src/db/schema.ts

Lines changed: 102 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export const accounts = pgTable(
4545
primaryKey({
4646
columns: [account.provider, account.providerAccountId],
4747
}),
48-
]
48+
],
4949
);
5050

5151
export const sessions = pgTable("sessions", {
@@ -67,7 +67,7 @@ export const verificationTokens = pgTable(
6767
primaryKey({
6868
columns: [verificationToken.identifier, verificationToken.token],
6969
}),
70-
]
70+
],
7171
);
7272

7373
// ============================================================
@@ -181,7 +181,10 @@ export const jobs = pgTable("jobs", {
181181
location: text("location"),
182182
sourceUrl: text("source_url"),
183183
jdText: text("jd_text").notNull(),
184-
extractedKeywords: jsonb("extracted_keywords").$type<string[]>().notNull().default([]),
184+
extractedKeywords: jsonb("extracted_keywords")
185+
.$type<string[]>()
186+
.notNull()
187+
.default([]),
185188
createdAt: timestamp("created_at", { mode: "date" }).defaultNow().notNull(),
186189
updatedAt: timestamp("updated_at", { mode: "date" }).defaultNow().notNull(),
187190
});
@@ -211,10 +214,13 @@ export const applications = pgTable("applications", {
211214
jobId: uuid("job_id")
212215
.notNull()
213216
.references(() => jobs.id, { onDelete: "cascade" }),
214-
resumeId: uuid("resume_id")
215-
.references(() => resumes.id, { onDelete: "set null" }),
216-
resumeVersionId: uuid("resume_version_id")
217-
.references(() => resumeVersions.id, { onDelete: "set null" }),
217+
resumeId: uuid("resume_id").references(() => resumes.id, {
218+
onDelete: "set null",
219+
}),
220+
resumeVersionId: uuid("resume_version_id").references(
221+
() => resumeVersions.id,
222+
{ onDelete: "set null" },
223+
),
218224
status: text("status").notNull().default("wishlist"),
219225
appliedAt: timestamp("applied_at", { mode: "date" }),
220226
nextStepAt: timestamp("next_step_at", { mode: "date" }),
@@ -243,10 +249,54 @@ export const usageEvents = pgTable("usage_events", {
243249
.notNull()
244250
.references(() => users.id, { onDelete: "cascade" }),
245251
eventName: text("event_name").notNull(),
246-
metadata: jsonb("metadata").$type<Record<string, unknown>>().notNull().default({}),
252+
metadata: jsonb("metadata")
253+
.$type<Record<string, unknown>>()
254+
.notNull()
255+
.default({}),
247256
createdAt: timestamp("created_at", { mode: "date" }).defaultNow().notNull(),
248257
});
249258

259+
export const mockInterviews = pgTable("mock_interviews", {
260+
id: uuid("id").defaultRandom().primaryKey(),
261+
userId: uuid("user_id")
262+
.notNull()
263+
.references(() => users.id, { onDelete: "cascade" }),
264+
applicationId: uuid("application_id")
265+
.notNull()
266+
.references(() => applications.id, { onDelete: "cascade" }),
267+
questions: jsonb("questions")
268+
.$type<Array<{ question: string; expectedContext: string }>>()
269+
.notNull()
270+
.default([]),
271+
answers: jsonb("answers")
272+
.$type<
273+
Array<{
274+
questionId: number;
275+
answer: string;
276+
feedback: string;
277+
score: number;
278+
}>
279+
>()
280+
.notNull()
281+
.default([]),
282+
status: text("status").notNull().default("pending"), // pending, in_progress, completed
283+
createdAt: timestamp("created_at", { mode: "date" }).defaultNow().notNull(),
284+
updatedAt: timestamp("updated_at", { mode: "date" }).defaultNow().notNull(),
285+
});
286+
287+
export const resumeViews = pgTable("resume_views", {
288+
id: uuid("id").defaultRandom().primaryKey(),
289+
resumeId: uuid("resume_id")
290+
.notNull()
291+
.references(() => resumes.id, { onDelete: "cascade" }),
292+
viewerIpId: text("viewer_ip_id").notNull(), // hashed ip or session identifier
293+
location: text("location"), // e.g. "San Francisco, CA"
294+
durationSeconds: integer("duration_seconds").notNull().default(0),
295+
clickedLinks: jsonb("clicked_links").$type<string[]>().notNull().default([]),
296+
createdAt: timestamp("created_at", { mode: "date" }).defaultNow().notNull(),
297+
updatedAt: timestamp("updated_at", { mode: "date" }).defaultNow().notNull(),
298+
});
299+
250300
// ============================================================
251301
// RELATIONS
252302
// ============================================================
@@ -260,54 +310,69 @@ export const usersRelations = relations(users, ({ many }) => ({
260310
usageEvents: many(usageEvents),
261311
accounts: many(accounts),
262312
sessions: many(sessions),
313+
mockInterviews: many(mockInterviews),
263314
}));
264315

265-
export const resumesRelations = relations(resumes, ({ one }) => ({
316+
export const resumesRelations = relations(resumes, ({ one, many }) => ({
266317
user: one(users, {
267318
fields: [resumes.userId],
268319
references: [users.id],
269320
}),
321+
views: many(resumeViews),
270322
}));
271323

272-
export const jobsRelations = relations(jobs, ({ one, many }) => ({
273-
user: one(users, {
274-
fields: [jobs.userId],
275-
references: [users.id],
324+
export const resumeViewsRelations = relations(resumeViews, ({ one }) => ({
325+
resume: one(resumes, {
326+
fields: [resumeViews.resumeId],
327+
references: [resumes.id],
276328
}),
277-
applications: many(applications),
278329
}));
279330

280-
export const resumeVersionsRelations = relations(resumeVersions, ({ one, many }) => ({
331+
export const jobsRelations = relations(jobs, ({ one, many }) => ({
281332
user: one(users, {
282-
fields: [resumeVersions.userId],
333+
fields: [jobs.userId],
283334
references: [users.id],
284335
}),
285-
resume: one(resumes, {
286-
fields: [resumeVersions.resumeId],
287-
references: [resumes.id],
288-
}),
289336
applications: many(applications),
290337
}));
291338

292-
export const applicationsRelations = relations(applications, ({ one, many }) => ({
293-
user: one(users, {
294-
fields: [applications.userId],
295-
references: [users.id],
296-
}),
297-
job: one(jobs, {
298-
fields: [applications.jobId],
299-
references: [jobs.id],
300-
}),
301-
resume: one(resumes, {
302-
fields: [applications.resumeId],
303-
references: [resumes.id],
339+
export const resumeVersionsRelations = relations(
340+
resumeVersions,
341+
({ one, many }) => ({
342+
user: one(users, {
343+
fields: [resumeVersions.userId],
344+
references: [users.id],
345+
}),
346+
resume: one(resumes, {
347+
fields: [resumeVersions.resumeId],
348+
references: [resumes.id],
349+
}),
350+
applications: many(applications),
304351
}),
305-
resumeVersion: one(resumeVersions, {
306-
fields: [applications.resumeVersionId],
307-
references: [resumeVersions.id],
352+
);
353+
354+
export const applicationsRelations = relations(
355+
applications,
356+
({ one, many }) => ({
357+
user: one(users, {
358+
fields: [applications.userId],
359+
references: [users.id],
360+
}),
361+
job: one(jobs, {
362+
fields: [applications.jobId],
363+
references: [jobs.id],
364+
}),
365+
resume: one(resumes, {
366+
fields: [applications.resumeId],
367+
references: [resumes.id],
368+
}),
369+
resumeVersion: one(resumeVersions, {
370+
fields: [applications.resumeVersionId],
371+
references: [resumeVersions.id],
372+
}),
373+
coverLetters: many(coverLetters),
308374
}),
309-
coverLetters: many(coverLetters),
310-
}));
375+
);
311376

312377
export const coverLettersRelations = relations(coverLetters, ({ one }) => ({
313378
user: one(users, {

0 commit comments

Comments
 (0)