mirror of
https://github.com/yangshun/tech-interview-handbook.git
synced 2025-07-28 20:52:00 +08:00
[questions][chore] update to use company table values (#351)
Co-authored-by: Jeff Sieu <jeffsy00@gmail.com>
This commit is contained in:
@ -0,0 +1,13 @@
|
|||||||
|
/*
|
||||||
|
Warnings:
|
||||||
|
|
||||||
|
- You are about to drop the column `company` on the `QuestionsQuestionEncounter` table. All the data in the column will be lost.
|
||||||
|
- Added the required column `companyId` to the `QuestionsQuestionEncounter` table without a default value. This is not possible if the table is not empty.
|
||||||
|
|
||||||
|
*/
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "QuestionsQuestionEncounter" DROP COLUMN "company",
|
||||||
|
ADD COLUMN "companyId" TEXT NOT NULL;
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "QuestionsQuestionEncounter" ADD CONSTRAINT "QuestionsQuestionEncounter_companyId_fkey" FOREIGN KEY ("companyId") REFERENCES "Company"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
@ -91,15 +91,17 @@ enum TodoStatus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
model Company {
|
model Company {
|
||||||
id String @id @default(cuid())
|
id String @id @default(cuid())
|
||||||
name String @db.Text
|
name String @db.Text
|
||||||
slug String @unique
|
slug String @unique
|
||||||
description String? @db.Text
|
description String? @db.Text
|
||||||
logoUrl String?
|
logoUrl String?
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
OffersExperience OffersExperience[]
|
|
||||||
OffersOffer OffersOffer[]
|
questionsQuestionEncounter QuestionsQuestionEncounter[]
|
||||||
|
OffersExperience OffersExperience[]
|
||||||
|
OffersOffer OffersOffer[]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start of Resumes project models.
|
// Start of Resumes project models.
|
||||||
@ -403,19 +405,20 @@ model QuestionsQuestion {
|
|||||||
}
|
}
|
||||||
|
|
||||||
model QuestionsQuestionEncounter {
|
model QuestionsQuestionEncounter {
|
||||||
id String @id @default(cuid())
|
id String @id @default(cuid())
|
||||||
questionId String
|
questionId String
|
||||||
userId String?
|
userId String?
|
||||||
// TODO: sync with models
|
// TODO: sync with models (location, role)
|
||||||
company String @db.Text
|
companyId String
|
||||||
location String @db.Text
|
location String @db.Text
|
||||||
role String @db.Text
|
role String @db.Text
|
||||||
seenAt DateTime
|
seenAt DateTime
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
|
|
||||||
user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
|
company Company? @relation(fields: [companyId], references: [id], onDelete: SetNull)
|
||||||
question QuestionsQuestion @relation(fields: [questionId], references: [id], onDelete: Cascade)
|
user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
|
||||||
|
question QuestionsQuestion @relation(fields: [questionId], references: [id], onDelete: Cascade)
|
||||||
}
|
}
|
||||||
|
|
||||||
model QuestionsQuestionVote {
|
model QuestionsQuestionVote {
|
||||||
|
@ -84,9 +84,8 @@ export default function ContributeQuestionForm({
|
|||||||
name="company"
|
name="company"
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<CompaniesTypeahead
|
<CompaniesTypeahead
|
||||||
onSelect={({ label }) => {
|
onSelect={({ id }) => {
|
||||||
// TODO: To change from using company name to company id (i.e., value)
|
field.onChange(id);
|
||||||
field.onChange(label);
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
@ -65,7 +65,7 @@ export default function QuestionsHomePage() {
|
|||||||
[
|
[
|
||||||
'questions.questions.getQuestionsByFilter',
|
'questions.questions.getQuestionsByFilter',
|
||||||
{
|
{
|
||||||
companies: selectedCompanies,
|
companyNames: selectedCompanies,
|
||||||
endDate: today,
|
endDate: today,
|
||||||
locations: selectedLocations,
|
locations: selectedLocations,
|
||||||
questionTypes: selectedQuestionTypes,
|
questionTypes: selectedQuestionTypes,
|
||||||
@ -252,7 +252,7 @@ export default function QuestionsHomePage() {
|
|||||||
<ContributeQuestionCard
|
<ContributeQuestionCard
|
||||||
onSubmit={(data) => {
|
onSubmit={(data) => {
|
||||||
createQuestion({
|
createQuestion({
|
||||||
company: data.company,
|
companyId: data.company,
|
||||||
content: data.questionContent,
|
content: data.questionContent,
|
||||||
location: data.location,
|
location: data.location,
|
||||||
questionType: data.questionType,
|
questionType: data.questionType,
|
||||||
|
@ -9,7 +9,7 @@ import type { Question } from '~/types/questions';
|
|||||||
export const questionsQuestionRouter = createProtectedRouter()
|
export const questionsQuestionRouter = createProtectedRouter()
|
||||||
.query('getQuestionsByFilter', {
|
.query('getQuestionsByFilter', {
|
||||||
input: z.object({
|
input: z.object({
|
||||||
companies: z.string().array(),
|
companyNames: z.string().array(),
|
||||||
endDate: z.date(),
|
endDate: z.date(),
|
||||||
locations: z.string().array(),
|
locations: z.string().array(),
|
||||||
questionTypes: z.nativeEnum(QuestionsQuestionType).array(),
|
questionTypes: z.nativeEnum(QuestionsQuestionType).array(),
|
||||||
@ -51,68 +51,69 @@ export const questionsQuestionRouter = createProtectedRouter()
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
: {}),
|
: {}),
|
||||||
encounters : {
|
encounters: {
|
||||||
some: {
|
some: {
|
||||||
...(input.companies.length > 0
|
...(input.companyNames.length > 0
|
||||||
? {
|
? {
|
||||||
company : {
|
company: {
|
||||||
in : input.companies
|
name: {
|
||||||
}
|
in: input.companyNames,
|
||||||
}
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
: {}),
|
: {}),
|
||||||
...(input.locations.length > 0
|
...(input.locations.length > 0
|
||||||
? {
|
? {
|
||||||
location: {
|
location: {
|
||||||
in: input.locations
|
in: input.locations,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
: {}),
|
: {}),
|
||||||
...(input.roles.length > 0
|
...(input.roles.length > 0
|
||||||
? {
|
? {
|
||||||
role : {
|
role: {
|
||||||
in: input.roles
|
in: input.roles,
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
: {}),
|
: {}),
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
return questionsData
|
return questionsData.map((data) => {
|
||||||
.map((data) => {
|
const votes: number = data.votes.reduce(
|
||||||
const votes: number = data.votes.reduce(
|
(previousValue: number, currentValue) => {
|
||||||
(previousValue: number, currentValue) => {
|
let result: number = previousValue;
|
||||||
let result: number = previousValue;
|
|
||||||
|
|
||||||
switch (currentValue.vote) {
|
switch (currentValue.vote) {
|
||||||
case Vote.UPVOTE:
|
case Vote.UPVOTE:
|
||||||
result += 1;
|
result += 1;
|
||||||
break;
|
break;
|
||||||
case Vote.DOWNVOTE:
|
case Vote.DOWNVOTE:
|
||||||
result -= 1;
|
result -= 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
|
|
||||||
const question: Question = {
|
const question: Question = {
|
||||||
company: data.encounters[0].company,
|
company: data.encounters[0].company!.name ?? 'Unknown company',
|
||||||
content: data.content,
|
content: data.content,
|
||||||
id: data.id,
|
id: data.id,
|
||||||
location: data.encounters[0].location ?? 'Unknown location',
|
location: data.encounters[0].location ?? 'Unknown location',
|
||||||
numAnswers: data._count.answers,
|
numAnswers: data._count.answers,
|
||||||
numComments: data._count.comments,
|
numComments: data._count.comments,
|
||||||
numVotes: votes,
|
numVotes: votes,
|
||||||
role: data.encounters[0].role ?? 'Unknown role',
|
role: data.encounters[0].role ?? 'Unknown role',
|
||||||
seenAt: data.encounters[0].seenAt,
|
seenAt: data.encounters[0].seenAt,
|
||||||
type: data.questionType,
|
type: data.questionType,
|
||||||
updatedAt: data.updatedAt,
|
updatedAt: data.updatedAt,
|
||||||
user: data.user?.name ?? '',
|
user: data.user?.name ?? '',
|
||||||
};
|
};
|
||||||
return question;
|
return question;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.query('getQuestionById', {
|
.query('getQuestionById', {
|
||||||
@ -171,7 +172,7 @@ export const questionsQuestionRouter = createProtectedRouter()
|
|||||||
);
|
);
|
||||||
|
|
||||||
const question: Question = {
|
const question: Question = {
|
||||||
company: questionData.encounters[0].company,
|
company: questionData.encounters[0].company!.name ?? 'Unknown company',
|
||||||
content: questionData.content,
|
content: questionData.content,
|
||||||
id: questionData.id,
|
id: questionData.id,
|
||||||
location: questionData.encounters[0].location ?? 'Unknown location',
|
location: questionData.encounters[0].location ?? 'Unknown location',
|
||||||
@ -189,7 +190,7 @@ export const questionsQuestionRouter = createProtectedRouter()
|
|||||||
})
|
})
|
||||||
.mutation('create', {
|
.mutation('create', {
|
||||||
input: z.object({
|
input: z.object({
|
||||||
company: z.string(),
|
companyId: z.string(),
|
||||||
content: z.string(),
|
content: z.string(),
|
||||||
location: z.string(),
|
location: z.string(),
|
||||||
questionType: z.nativeEnum(QuestionsQuestionType),
|
questionType: z.nativeEnum(QuestionsQuestionType),
|
||||||
@ -199,17 +200,25 @@ export const questionsQuestionRouter = createProtectedRouter()
|
|||||||
async resolve({ ctx, input }) {
|
async resolve({ ctx, input }) {
|
||||||
const userId = ctx.session?.user?.id;
|
const userId = ctx.session?.user?.id;
|
||||||
|
|
||||||
const question = await ctx.prisma.questionsQuestion.create({
|
return await ctx.prisma.questionsQuestion.create({
|
||||||
data: {
|
data: {
|
||||||
content: input.content,
|
content: input.content,
|
||||||
encounters: {
|
encounters: {
|
||||||
create: [
|
create: [
|
||||||
{
|
{
|
||||||
company: input.company,
|
company: {
|
||||||
|
connect: {
|
||||||
|
id: input.companyId,
|
||||||
|
},
|
||||||
|
},
|
||||||
location: input.location,
|
location: input.location,
|
||||||
role: input.role,
|
role: input.role,
|
||||||
seenAt: input.seenAt,
|
seenAt: input.seenAt,
|
||||||
userId,
|
user: {
|
||||||
|
connect: {
|
||||||
|
id: userId,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -217,20 +226,6 @@ export const questionsQuestionRouter = createProtectedRouter()
|
|||||||
userId,
|
userId,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// Create question encounter
|
|
||||||
await ctx.prisma.questionsQuestionEncounter.create({
|
|
||||||
data: {
|
|
||||||
company: input.company,
|
|
||||||
location: input.location,
|
|
||||||
questionId: question.id,
|
|
||||||
role: input.role,
|
|
||||||
seenAt: input.seenAt,
|
|
||||||
userId,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
return question;
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.mutation('update', {
|
.mutation('update', {
|
||||||
@ -259,7 +254,6 @@ export const questionsQuestionRouter = createProtectedRouter()
|
|||||||
const { content, questionType } = input;
|
const { content, questionType } = input;
|
||||||
|
|
||||||
return await ctx.prisma.questionsQuestion.update({
|
return await ctx.prisma.questionsQuestion.update({
|
||||||
|
|
||||||
data: {
|
data: {
|
||||||
content,
|
content,
|
||||||
questionType,
|
questionType,
|
||||||
|
4
apps/portal/src/types/questions.d.ts
vendored
4
apps/portal/src/types/questions.d.ts
vendored
@ -1,3 +1,5 @@
|
|||||||
|
import type { QuestionsQuestionType } from '@prisma/client';
|
||||||
|
|
||||||
export type Question = {
|
export type Question = {
|
||||||
// TODO: company, location, role maps
|
// TODO: company, location, role maps
|
||||||
company: string;
|
company: string;
|
||||||
@ -9,7 +11,7 @@ export type Question = {
|
|||||||
numVotes: number;
|
numVotes: number;
|
||||||
role: string;
|
role: string;
|
||||||
seenAt: Date;
|
seenAt: Date;
|
||||||
type: stringl;
|
type: QuestionsQuestionType;
|
||||||
updatedAt: Date;
|
updatedAt: Date;
|
||||||
user: string;
|
user: string;
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user