[offers][feat] Create Offer Analysis API

pull/379/head
BryannYeap 3 years ago
parent 7b51ee7e88
commit b7e0d8ff90

@ -1,105 +1,105 @@
// Refer to the Prisma schema docs: https://pris.ly/d/prisma-schema
generator client {
provider = "prisma-client-js"
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
provider = "postgresql"
url = env("DATABASE_URL")
}
// Necessary for NextAuth.
model Account {
id String @id @default(cuid())
userId String
type String
provider String
providerAccountId String
refresh_token String? @db.Text
access_token String? @db.Text
expires_at Int?
token_type String?
scope String?
id_token String? @db.Text
session_state String?
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([provider, providerAccountId])
id String @id @default(cuid())
userId String
type String
provider String
providerAccountId String
refresh_token String? @db.Text
access_token String? @db.Text
expires_at Int?
token_type String?
scope String?
id_token String? @db.Text
session_state String?
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([provider, providerAccountId])
}
model Session {
id String @id @default(cuid())
sessionToken String @unique
userId String
expires DateTime
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
id String @id @default(cuid())
sessionToken String @unique
userId String
expires DateTime
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
}
model User {
id String @id @default(cuid())
name String?
email String? @unique
emailVerified DateTime?
image String?
accounts Account[]
sessions Session[]
todos Todo[]
resumesResumes ResumesResume[]
resumesStars ResumesStar[]
resumesComments ResumesComment[]
resumesCommentVotes ResumesCommentVote[]
questionsQuestions QuestionsQuestion[]
questionsQuestionEncounters QuestionsQuestionEncounter[]
questionsQuestionVotes QuestionsQuestionVote[]
questionsQuestionComments QuestionsQuestionComment[]
questionsQuestionCommentVotes QuestionsQuestionCommentVote[]
questionsAnswers QuestionsAnswer[]
questionsAnswerVotes QuestionsAnswerVote[]
questionsAnswerComments QuestionsAnswerComment[]
questionsAnswerCommentVotes QuestionsAnswerCommentVote[]
OffersProfile OffersProfile[]
offersDiscussion OffersReply[]
id String @id @default(cuid())
name String?
email String? @unique
emailVerified DateTime?
image String?
accounts Account[]
sessions Session[]
todos Todo[]
resumesResumes ResumesResume[]
resumesStars ResumesStar[]
resumesComments ResumesComment[]
resumesCommentVotes ResumesCommentVote[]
questionsQuestions QuestionsQuestion[]
questionsQuestionEncounters QuestionsQuestionEncounter[]
questionsQuestionVotes QuestionsQuestionVote[]
questionsQuestionComments QuestionsQuestionComment[]
questionsQuestionCommentVotes QuestionsQuestionCommentVote[]
questionsAnswers QuestionsAnswer[]
questionsAnswerVotes QuestionsAnswerVote[]
questionsAnswerComments QuestionsAnswerComment[]
questionsAnswerCommentVotes QuestionsAnswerCommentVote[]
OffersProfile OffersProfile[]
offersDiscussion OffersReply[]
}
enum Vote {
UPVOTE
DOWNVOTE
UPVOTE
DOWNVOTE
}
model VerificationToken {
identifier String
token String @unique
expires DateTime
identifier String
token String @unique
expires DateTime
@@unique([identifier, token])
@@unique([identifier, token])
}
model Todo {
id String @id @default(cuid())
userId String
text String @db.Text
status TodoStatus @default(INCOMPLETE)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
id String @id @default(cuid())
userId String
text String @db.Text
status TodoStatus @default(INCOMPLETE)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
}
enum TodoStatus {
INCOMPLETE
COMPLETE
INCOMPLETE
COMPLETE
}
model Company {
id String @id @default(cuid())
name String @db.Text
slug String @unique
description String? @db.Text
logoUrl String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
OffersExperience OffersExperience[]
OffersOffer OffersOffer[]
id String @id @default(cuid())
name String @db.Text
slug String @unique
description String? @db.Text
logoUrl String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
OffersExperience OffersExperience[]
OffersOffer OffersOffer[]
}
// Start of Resumes project models.
@ -107,65 +107,65 @@ model Company {
// use camelCase for field names, and try to name them consistently
// across all models in this file.
model ResumesResume {
id String @id @default(cuid())
userId String
title String @db.Text
// TODO: Update role, experience, location to use Enums
role String @db.Text
experience String @db.Text
location String @db.Text
url String
additionalInfo String? @db.Text
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
stars ResumesStar[]
comments ResumesComment[]
id String @id @default(cuid())
userId String
title String @db.Text
// TODO: Update role, experience, location to use Enums
role String @db.Text
experience String @db.Text
location String @db.Text
url String
additionalInfo String? @db.Text
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
stars ResumesStar[]
comments ResumesComment[]
}
model ResumesStar {
id String @id @default(cuid())
userId String
resumeId String
createdAt DateTime @default(now())
resume ResumesResume @relation(fields: [resumeId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
id String @id @default(cuid())
userId String
resumeId String
createdAt DateTime @default(now())
resume ResumesResume @relation(fields: [resumeId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([userId, resumeId])
@@unique([userId, resumeId])
}
model ResumesComment {
id String @id @default(cuid())
userId String
resumeId String
description String @db.Text
section ResumesSection
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
resume ResumesResume @relation(fields: [resumeId], references: [id], onDelete: Cascade)
votes ResumesCommentVote[]
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
id String @id @default(cuid())
userId String
resumeId String
description String @db.Text
section ResumesSection
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
resume ResumesResume @relation(fields: [resumeId], references: [id], onDelete: Cascade)
votes ResumesCommentVote[]
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
}
enum ResumesSection {
GENERAL
EDUCATION
EXPERIENCE
PROJECTS
SKILLS
GENERAL
EDUCATION
EXPERIENCE
PROJECTS
SKILLS
}
model ResumesCommentVote {
id String @id @default(cuid())
userId String
commentId String
value Vote
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
comment ResumesComment @relation(fields: [commentId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
id String @id @default(cuid())
userId String
commentId String
value Vote
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
comment ResumesComment @relation(fields: [commentId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([userId, commentId])
@@unique([userId, commentId])
}
// End of Resumes project models.
@ -176,176 +176,176 @@ model ResumesCommentVote {
// across all models in this file.
model OffersProfile {
id String @id @default(cuid())
profileName String @unique
createdAt DateTime @default(now())
id String @id @default(cuid())
profileName String @unique
createdAt DateTime @default(now())
background OffersBackground?
background OffersBackground?
editToken String
editToken String
discussion OffersReply[]
discussion OffersReply[]
offers OffersOffer[]
offers OffersOffer[]
user User? @relation(fields: [userId], references: [id])
userId String?
user User? @relation(fields: [userId], references: [id])
userId String?
}
model OffersBackground {
id String @id @default(cuid())
id String @id @default(cuid())
totalYoe Int?
specificYoes OffersSpecificYoe[]
totalYoe Int?
specificYoes OffersSpecificYoe[]
experiences OffersExperience[] // For extensibility in the future
experiences OffersExperience[] // For extensibility in the future
educations OffersEducation[] // For extensibility in the future
educations OffersEducation[] // For extensibility in the future
profile OffersProfile @relation(fields: [offersProfileId], references: [id], onDelete: Cascade)
offersProfileId String @unique
profile OffersProfile @relation(fields: [offersProfileId], references: [id], onDelete: Cascade)
offersProfileId String @unique
}
model OffersSpecificYoe {
id String @id @default(cuid())
id String @id @default(cuid())
yoe Int
domain String
yoe Int
domain String
background OffersBackground @relation(fields: [backgroundId], references: [id], onDelete: Cascade)
backgroundId String
background OffersBackground @relation(fields: [backgroundId], references: [id], onDelete: Cascade)
backgroundId String
}
model OffersExperience {
id String @id @default(cuid())
id String @id @default(cuid())
company Company? @relation(fields: [companyId], references: [id])
companyId String?
company Company? @relation(fields: [companyId], references: [id])
companyId String?
jobType JobType?
title String?
jobType JobType?
title String?
// Add more fields
durationInMonths Int?
specialization String?
// Add more fields
durationInMonths Int?
specialization String?
// FULLTIME fields
level String?
totalCompensation OffersCurrency? @relation("ExperienceTotalCompensation", fields: [totalCompensationId], references: [id])
totalCompensationId String? @unique
// FULLTIME fields
level String?
totalCompensation OffersCurrency? @relation("ExperienceTotalCompensation", fields: [totalCompensationId], references: [id])
totalCompensationId String? @unique
// INTERN fields
monthlySalary OffersCurrency? @relation("ExperienceMonthlySalary", fields: [monthlySalaryId], references: [id])
monthlySalaryId String? @unique
// INTERN fields
monthlySalary OffersCurrency? @relation("ExperienceMonthlySalary", fields: [monthlySalaryId], references: [id])
monthlySalaryId String? @unique
background OffersBackground @relation(fields: [backgroundId], references: [id], onDelete: Cascade)
backgroundId String
background OffersBackground @relation(fields: [backgroundId], references: [id], onDelete: Cascade)
backgroundId String
}
model OffersCurrency {
id String @id @default(cuid())
value Int
currency String
id String @id @default(cuid())
value Int
currency String
// Experience
OffersExperienceTotalCompensation OffersExperience? @relation("ExperienceTotalCompensation")
OffersExperienceMonthlySalary OffersExperience? @relation("ExperienceMonthlySalary")
// Experience
OffersExperienceTotalCompensation OffersExperience? @relation("ExperienceTotalCompensation")
OffersExperienceMonthlySalary OffersExperience? @relation("ExperienceMonthlySalary")
// Full Time
OffersTotalCompensation OffersFullTime? @relation("OfferTotalCompensation")
OffersBaseSalary OffersFullTime? @relation("OfferBaseSalary")
OffersBonus OffersFullTime? @relation("OfferBonus")
OffersStocks OffersFullTime? @relation("OfferStocks")
// Full Time
OffersTotalCompensation OffersFullTime? @relation("OfferTotalCompensation")
OffersBaseSalary OffersFullTime? @relation("OfferBaseSalary")
OffersBonus OffersFullTime? @relation("OfferBonus")
OffersStocks OffersFullTime? @relation("OfferStocks")
// Intern
OffersMonthlySalary OffersIntern?
// Intern
OffersMonthlySalary OffersIntern?
}
enum JobType {
INTERN
FULLTIME
INTERN
FULLTIME
}
model OffersEducation {
id String @id @default(cuid())
type String?
field String?
id String @id @default(cuid())
type String?
field String?
school String?
startDate DateTime?
endDate DateTime?
school String?
startDate DateTime?
endDate DateTime?
background OffersBackground @relation(fields: [backgroundId], references: [id], onDelete: Cascade)
backgroundId String
background OffersBackground @relation(fields: [backgroundId], references: [id], onDelete: Cascade)
backgroundId String
}
model OffersReply {
id String @id @default(cuid())
createdAt DateTime @default(now())
message String
id String @id @default(cuid())
createdAt DateTime @default(now())
message String
replyingToId String?
replyingTo OffersReply? @relation("ReplyThread", fields: [replyingToId], references: [id])
replies OffersReply[] @relation("ReplyThread")
replyingToId String?
replyingTo OffersReply? @relation("ReplyThread", fields: [replyingToId], references: [id])
replies OffersReply[] @relation("ReplyThread")
profile OffersProfile @relation(fields: [profileId], references: [id], onDelete: Cascade)
profileId String
profile OffersProfile @relation(fields: [profileId], references: [id], onDelete: Cascade)
profileId String
user User? @relation(fields: [userId], references: [id])
userId String?
user User? @relation(fields: [userId], references: [id])
userId String?
}
model OffersOffer {
id String @id @default(cuid())
id String @id @default(cuid())
profile OffersProfile @relation(fields: [profileId], references: [id], onDelete: Cascade)
profileId String
profile OffersProfile @relation(fields: [profileId], references: [id], onDelete: Cascade)
profileId String
company Company @relation(fields: [companyId], references: [id])
companyId String
company Company @relation(fields: [companyId], references: [id])
companyId String
monthYearReceived DateTime
location String
negotiationStrategy String?
comments String?
monthYearReceived DateTime
location String
negotiationStrategy String?
comments String?
jobType JobType
jobType JobType
OffersIntern OffersIntern? @relation(fields: [offersInternId], references: [id], onDelete: Cascade)
offersInternId String? @unique
OffersIntern OffersIntern? @relation(fields: [offersInternId], references: [id], onDelete: Cascade)
offersInternId String? @unique
OffersFullTime OffersFullTime? @relation(fields: [offersFullTimeId], references: [id], onDelete: Cascade)
offersFullTimeId String? @unique
OffersFullTime OffersFullTime? @relation(fields: [offersFullTimeId], references: [id], onDelete: Cascade)
offersFullTimeId String? @unique
}
model OffersIntern {
id String @id @default(cuid())
id String @id @default(cuid())
title String
specialization String
internshipCycle String
startYear Int
monthlySalary OffersCurrency @relation(fields: [monthlySalaryId], references: [id], onDelete: Cascade)
monthlySalaryId String @unique
title String
specialization String
internshipCycle String
startYear Int
monthlySalary OffersCurrency @relation(fields: [monthlySalaryId], references: [id], onDelete: Cascade)
monthlySalaryId String @unique
OffersOffer OffersOffer?
OffersOffer OffersOffer?
}
model OffersFullTime {
id String @id @default(cuid())
title String
specialization String
level String
totalCompensation OffersCurrency @relation("OfferTotalCompensation", fields: [totalCompensationId], references: [id], onDelete: Cascade)
totalCompensationId String @unique
baseSalary OffersCurrency @relation("OfferBaseSalary", fields: [baseSalaryId], references: [id], onDelete: Cascade)
baseSalaryId String @unique
bonus OffersCurrency @relation("OfferBonus", fields: [bonusId], references: [id], onDelete: Cascade)
bonusId String @unique
stocks OffersCurrency @relation("OfferStocks", fields: [stocksId], references: [id], onDelete: Cascade)
stocksId String @unique
OffersOffer OffersOffer?
id String @id @default(cuid())
title String
specialization String
level String
totalCompensation OffersCurrency @relation("OfferTotalCompensation", fields: [totalCompensationId], references: [id], onDelete: Cascade)
totalCompensationId String @unique
baseSalary OffersCurrency @relation("OfferBaseSalary", fields: [baseSalaryId], references: [id], onDelete: Cascade)
baseSalaryId String @unique
bonus OffersCurrency @relation("OfferBonus", fields: [bonusId], references: [id], onDelete: Cascade)
bonusId String @unique
stocks OffersCurrency @relation("OfferStocks", fields: [stocksId], references: [id], onDelete: Cascade)
stocksId String @unique
OffersOffer OffersOffer?
}
// End of Offers project models.
@ -356,136 +356,136 @@ model OffersFullTime {
// across all models in this file.
enum QuestionsQuestionType {
CODING
SYSTEM_DESIGN
BEHAVIORAL
CODING
SYSTEM_DESIGN
BEHAVIORAL
}
model QuestionsQuestion {
id String @id @default(cuid())
userId String?
content String @db.Text
questionType QuestionsQuestionType
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
id String @id @default(cuid())
userId String?
content String @db.Text
questionType QuestionsQuestionType
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
encounters QuestionsQuestionEncounter[]
votes QuestionsQuestionVote[]
comments QuestionsQuestionComment[]
answers QuestionsAnswer[]
user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
encounters QuestionsQuestionEncounter[]
votes QuestionsQuestionVote[]
comments QuestionsQuestionComment[]
answers QuestionsAnswer[]
}
model QuestionsQuestionEncounter {
id String @id @default(cuid())
questionId String
userId String?
// TODO: sync with models
company String @db.Text
location String @db.Text
role String @db.Text
seenAt DateTime
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
id String @id @default(cuid())
questionId String
userId String?
// TODO: sync with models
company String @db.Text
location String @db.Text
role String @db.Text
seenAt DateTime
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User? @relation(fields: [userId], 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 {
id String @id @default(cuid())
questionId String
userId String?
vote Vote
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
id String @id @default(cuid())
questionId String
userId String?
vote Vote
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User? @relation(fields: [userId], 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)
@@unique([questionId, userId])
@@unique([questionId, userId])
}
model QuestionsQuestionComment {
id String @id @default(cuid())
questionId String
userId String?
content String @db.Text
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
id String @id @default(cuid())
questionId String
userId String?
content String @db.Text
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
question QuestionsQuestion @relation(fields: [questionId], references: [id], onDelete: Cascade)
votes QuestionsQuestionCommentVote[]
user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
question QuestionsQuestion @relation(fields: [questionId], references: [id], onDelete: Cascade)
votes QuestionsQuestionCommentVote[]
}
model QuestionsQuestionCommentVote {
id String @id @default(cuid())
questionCommentId String
userId String?
vote Vote
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
id String @id @default(cuid())
questionCommentId String
userId String?
vote Vote
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
comment QuestionsQuestionComment @relation(fields: [questionCommentId], references: [id], onDelete: Cascade)
user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
comment QuestionsQuestionComment @relation(fields: [questionCommentId], references: [id], onDelete: Cascade)
@@unique([questionCommentId, userId])
@@unique([questionCommentId, userId])
}
model QuestionsAnswer {
id String @id @default(cuid())
questionId String
userId String?
content String @db.Text
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
id String @id @default(cuid())
questionId String
userId String?
content String @db.Text
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
question QuestionsQuestion @relation(fields: [questionId], references: [id], onDelete: Cascade)
votes QuestionsAnswerVote[]
comments QuestionsAnswerComment[]
user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
question QuestionsQuestion @relation(fields: [questionId], references: [id], onDelete: Cascade)
votes QuestionsAnswerVote[]
comments QuestionsAnswerComment[]
}
model QuestionsAnswerVote {
id String @id @default(cuid())
answerId String
userId String?
vote Vote
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
id String @id @default(cuid())
answerId String
userId String?
vote Vote
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
answer QuestionsAnswer @relation(fields: [answerId], references: [id], onDelete: Cascade)
user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
answer QuestionsAnswer @relation(fields: [answerId], references: [id], onDelete: Cascade)
@@unique([answerId, userId])
@@unique([answerId, userId])
}
model QuestionsAnswerComment {
id String @id @default(cuid())
answerId String
userId String?
content String @db.Text
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
id String @id @default(cuid())
answerId String
userId String?
content String @db.Text
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
answer QuestionsAnswer @relation(fields: [answerId], references: [id], onDelete: Cascade)
votes QuestionsAnswerCommentVote[]
user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
answer QuestionsAnswer @relation(fields: [answerId], references: [id], onDelete: Cascade)
votes QuestionsAnswerCommentVote[]
}
model QuestionsAnswerCommentVote {
id String @id @default(cuid())
answerCommentId String
userId String?
vote Vote
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
id String @id @default(cuid())
answerCommentId String
userId String?
vote Vote
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
comment QuestionsAnswerComment @relation(fields: [answerCommentId], references: [id], onDelete: Cascade)
user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
comment QuestionsAnswerComment @relation(fields: [answerCommentId], references: [id], onDelete: Cascade)
@@unique([answerCommentId, userId])
@@unique([answerCommentId, userId])
}
// End of Questions project models.

@ -4,7 +4,7 @@ import { trpc } from '~/utils/trpc';
function Test() {
const [createdData, setCreatedData] = useState('');
const [error, setError] = useState("");
const [error, setError] = useState('');
const createMutation = trpc.useMutation(['offers.profile.create'], {
onError(err: any) {
@ -15,14 +15,17 @@ function Test() {
},
});
const addToUserProfileMutation = trpc.useMutation(['offers.profile.addToUserProfile'], {
onError(err: any) {
alert(err);
},
onSuccess(data) {
setCreatedData(JSON.stringify(data));
const addToUserProfileMutation = trpc.useMutation(
['offers.profile.addToUserProfile'],
{
onError(err: any) {
alert(err);
},
onSuccess(data) {
setCreatedData(JSON.stringify(data));
},
},
})
);
const deleteCommentMutation = trpc.useMutation(['offers.comments.delete'], {
onError(err: any) {
@ -38,9 +41,9 @@ function Test() {
id: 'cl97fprun001j7iyg6ev9x983',
profileId: 'cl96stky5002ew32gx2kale2x',
token: 'afca11e436d21bde24543718fa957c6c625335439dc504f24ee35eae7b5ef1',
userId: 'cl97dl51k001e7iygd5v5gt58'
})
}
userId: 'cl97dl51k001e7iygd5v5gt58',
});
};
const updateCommentMutation = trpc.useMutation(['offers.comments.update'], {
onError(err: any) {
@ -56,9 +59,9 @@ function Test() {
id: 'cl97fxb0y001l7iyg14sdobt2',
message: 'hello hello',
profileId: 'cl96stky5002ew32gx2kale2x',
token: 'afca11e436d21bde24543718fa957c6c625335439dc504f24ee35eae7b5ef1ba'
})
}
token: 'afca11e436d21bde24543718fa957c6c625335439dc504f24ee35eae7b5ef1ba',
});
};
const createCommentMutation = trpc.useMutation(['offers.comments.create'], {
onError(err: any) {
@ -74,16 +77,16 @@ function Test() {
message: 'hello',
profileId: 'cl96stky5002ew32gx2kale2x',
// UserId: 'cl97dl51k001e7iygd5v5gt58'
})
}
});
};
const handleLink = () => {
addToUserProfileMutation.mutate({
profileId: 'cl96stky5002ew32gx2kale2x',
token: 'afca11e436d21bde24543718fa957c6c625335439dc504f24ee35eae7b5ef1ba',
userId: 'cl97dl51k001e7iygd5v5gt58'
})
}
userId: 'cl97dl51k001e7iygd5v5gt58',
});
};
const handleClick = () => {
createMutation.mutate({
@ -126,7 +129,6 @@ function Test() {
},
offers: [
{
OffersFullTime: {
baseSalary: {
currency: 'SGD',
@ -189,23 +191,30 @@ function Test() {
};
const profileId = 'cl96stky5002ew32gx2kale2x'; // Remember to change this filed after testing deleting
const data = trpc.useQuery([
`offers.profile.listOne`,
const data = trpc.useQuery(
[
`offers.profile.listOne`,
{
profileId,
token:
'afca11e436d21bde24543718fa957c6c625335439dc504f24ee35eae7b5ef1ba',
},
],
{
profileId,
token: 'afca11e436d21bde24543718fa957c6c625335439dc504f24ee35eae7b5ef1ba',
onError(err) {
setError(err.shape?.message || '');
},
},
], {
onError(err) {
setError(err.shape?.message || "")
}
});
);
const replies = trpc.useQuery(['offers.comments.getComments', {profileId: 'cl96stky5002ew32gx2kale2x'}], {
onError(err) {
setError(err.shape?.message || "")
const replies = trpc.useQuery(
['offers.comments.getComments', { profileId: 'cl96stky5002ew32gx2kale2x' }],
{
onError(err) {
setError(err.shape?.message || '');
},
},
});
);
const deleteMutation = trpc.useMutation(['offers.profile.delete']);
@ -230,357 +239,363 @@ function Test() {
background: {
educations: [
{
backgroundId: "cl96stky6002fw32g6vj4meyr",
endDate: new Date("2018-09-30T07:58:54.000Z"),
field: "Computer Science",
id: "cl96stky6002gw32gey2ffawd",
school: "National University of Singapore",
startDate: new Date("2014-09-30T07:58:54.000Z"),
type: "Bachelors"
}
backgroundId: 'cl96stky6002fw32g6vj4meyr',
endDate: new Date('2018-09-30T07:58:54.000Z'),
field: 'Computer Science',
id: 'cl96stky6002gw32gey2ffawd',
school: 'National University of Singapore',
startDate: new Date('2014-09-30T07:58:54.000Z'),
type: 'Bachelors',
},
],
experiences: [
{
backgroundId: "cl96stky6002fw32g6vj4meyr",
backgroundId: 'cl96stky6002fw32g6vj4meyr',
company: {
createdAt: new Date("2022-10-12T16:19:05.196Z"),
description: "Meta Platforms, Inc., doing business as Meta and formerly named Facebook, Inc., and TheFacebook, Inc., is an American multinational technology conglomerate based in Menlo Park, California. The company owns Facebook, Instagram, and WhatsApp, among other products and services.",
id: "cl95u79f000007im531ysjg79",
logoUrl: "https://logo.clearbit.com/meta.com",
name: "Meta",
slug: "meta",
updatedAt: new Date("2022-10-12T16:19:05.196Z")
createdAt: new Date('2022-10-12T16:19:05.196Z'),
description:
'Meta Platforms, Inc., doing business as Meta and formerly named Facebook, Inc., and TheFacebook, Inc., is an American multinational technology conglomerate based in Menlo Park, California. The company owns Facebook, Instagram, and WhatsApp, among other products and services.',
id: 'cl95u79f000007im531ysjg79',
logoUrl: 'https://logo.clearbit.com/meta.com',
name: 'Meta',
slug: 'meta',
updatedAt: new Date('2022-10-12T16:19:05.196Z'),
},
companyId: "cl95u79f000007im531ysjg79",
companyId: 'cl95u79f000007im531ysjg79',
durationInMonths: 24,
id: "cl96stky6002iw32gpt6t87s2",
jobType: "FULLTIME",
level: "Junior",
id: 'cl96stky6002iw32gpt6t87s2',
jobType: 'FULLTIME',
level: 'Junior',
monthlySalary: null,
monthlySalaryId: null,
specialization: "Front End",
title: "Software Engineer",
specialization: 'Front End',
title: 'Software Engineer',
totalCompensation: {
currency: "SGD",
id: "cl96stky6002jw32g73svfacr",
value: 104100
currency: 'SGD',
id: 'cl96stky6002jw32g73svfacr',
value: 104100,
},
totalCompensationId: "cl96stky6002jw32g73svfacr"
}
totalCompensationId: 'cl96stky6002jw32g73svfacr',
},
],
id: "cl96stky6002fw32g6vj4meyr",
offersProfileId: "cl96stky5002ew32gx2kale2x",
id: 'cl96stky6002fw32g6vj4meyr',
offersProfileId: 'cl96stky5002ew32gx2kale2x',
specificYoes: [
{
backgroundId: "cl96stky6002fw32g6vj4meyr",
domain: "Backend",
id: "cl96t7890004tw32g5in3px5j",
yoe: 2
backgroundId: 'cl96stky6002fw32g6vj4meyr',
domain: 'Backend',
id: 'cl96t7890004tw32g5in3px5j',
yoe: 2,
},
{
backgroundId: "cl96stky6002fw32g6vj4meyr",
domain: "Backend",
id: "cl96tb87x004xw32gnu17jbzv",
yoe: 2
backgroundId: 'cl96stky6002fw32g6vj4meyr',
domain: 'Backend',
id: 'cl96tb87x004xw32gnu17jbzv',
yoe: 2,
},
{
backgroundId: "cl96stky6002fw32g6vj4meyr",
domain: "Backend",
id: "cl976t39z00007iygt3np3cgo",
yoe: 2
backgroundId: 'cl96stky6002fw32g6vj4meyr',
domain: 'Backend',
id: 'cl976t39z00007iygt3np3cgo',
yoe: 2,
},
{
backgroundId: "cl96stky6002fw32g6vj4meyr",
domain: "Front End",
id: "cl96stky7002mw32gn4jc7uml",
yoe: 2
backgroundId: 'cl96stky6002fw32g6vj4meyr',
domain: 'Front End',
id: 'cl96stky7002mw32gn4jc7uml',
yoe: 2,
},
{
backgroundId: "cl96stky6002fw32g6vj4meyr",
domain: "Full Stack",
id: "cl96stky7002nw32gpprghtxr",
yoe: 2
backgroundId: 'cl96stky6002fw32g6vj4meyr',
domain: 'Full Stack',
id: 'cl96stky7002nw32gpprghtxr',
yoe: 2,
},
{
backgroundId: "cl96stky6002fw32g6vj4meyr",
domain: "Backend",
id: "cl976we5h000p7iygiomdo9fh",
yoe: 2
}
backgroundId: 'cl96stky6002fw32g6vj4meyr',
domain: 'Backend',
id: 'cl976we5h000p7iygiomdo9fh',
yoe: 2,
},
],
totalYoe: 6
totalYoe: 6,
},
createdAt: "2022-10-13T08:28:13.518Z",
createdAt: '2022-10-13T08:28:13.518Z',
discussion: [],
id: "cl96stky5002ew32gx2kale2x",
id: 'cl96stky5002ew32gx2kale2x',
isEditable: true,
offers: [
{
OffersFullTime: {
baseSalary: {
currency: "SGD",
id: "cl976t4de00067iyg3pjir7k9",
value: 1999999999
currency: 'SGD',
id: 'cl976t4de00067iyg3pjir7k9',
value: 1999999999,
},
baseSalaryId: "cl976t4de00067iyg3pjir7k9",
baseSalaryId: 'cl976t4de00067iyg3pjir7k9',
bonus: {
currency: "SGD",
id: "cl976t4de00087iygcnlmh8aw",
value: 1410065407
currency: 'SGD',
id: 'cl976t4de00087iygcnlmh8aw',
value: 1410065407,
},
bonusId: "cl976t4de00087iygcnlmh8aw",
id: "cl976t4de00057iygq3ktce3v",
level: "EXPERT",
specialization: "FRONTEND",
bonusId: 'cl976t4de00087iygcnlmh8aw',
id: 'cl976t4de00057iygq3ktce3v',
level: 'EXPERT',
specialization: 'FRONTEND',
stocks: {
currency: "SGD",
id: "cl976t4df000a7iygkrsgr1xh",
value: -558038585
currency: 'SGD',
id: 'cl976t4df000a7iygkrsgr1xh',
value: -558038585,
},
stocksId: "cl976t4df000a7iygkrsgr1xh",
title: "Software Engineer",
stocksId: 'cl976t4df000a7iygkrsgr1xh',
title: 'Software Engineer',
totalCompensation: {
currency: "SGD",
id: "cl976t4df000c7iyg73ryf5uw",
value: 55555555
currency: 'SGD',
id: 'cl976t4df000c7iyg73ryf5uw',
value: 55555555,
},
totalCompensationId: "cl976t4df000c7iyg73ryf5uw"
totalCompensationId: 'cl976t4df000c7iyg73ryf5uw',
},
OffersIntern: null,
comments: "this IS SO IEUHDAEUIGDI",
comments: 'this IS SO IEUHDAEUIGDI',
company: {
createdAt: new Date("2022-10-12T16:19:05.196Z"),
description: "Meta Platforms, Inc., doing business as Meta and formerly named Facebook, Inc., and TheFacebook, Inc., is an American multinational technology conglomerate based in Menlo Park, California. The company owns Facebook, Instagram, and WhatsApp, among other products and services.",
id: "cl95u79f000007im531ysjg79",
logoUrl: "https://logo.clearbit.com/meta.com",
name: "Meta",
slug: "meta",
updatedAt: new Date("2022-10-12T16:19:05.196Z")
createdAt: new Date('2022-10-12T16:19:05.196Z'),
description:
'Meta Platforms, Inc., doing business as Meta and formerly named Facebook, Inc., and TheFacebook, Inc., is an American multinational technology conglomerate based in Menlo Park, California. The company owns Facebook, Instagram, and WhatsApp, among other products and services.',
id: 'cl95u79f000007im531ysjg79',
logoUrl: 'https://logo.clearbit.com/meta.com',
name: 'Meta',
slug: 'meta',
updatedAt: new Date('2022-10-12T16:19:05.196Z'),
},
companyId: "cl95u79f000007im531ysjg79",
id: "cl976t4de00047iygl0zbce11",
jobType: "FULLTIME",
location: "Singapore, Singapore",
monthYearReceived: new Date("2022-09-30T07:58:54.000Z"),
negotiationStrategy: "Charmed the guy with my face",
offersFullTimeId: "cl976t4de00057iygq3ktce3v",
companyId: 'cl95u79f000007im531ysjg79',
id: 'cl976t4de00047iygl0zbce11',
jobType: 'FULLTIME',
location: 'Singapore, Singapore',
monthYearReceived: new Date('2022-09-30T07:58:54.000Z'),
negotiationStrategy: 'Charmed the guy with my face',
offersFullTimeId: 'cl976t4de00057iygq3ktce3v',
offersInternId: null,
profileId: "cl96stky5002ew32gx2kale2x"
profileId: 'cl96stky5002ew32gx2kale2x',
},
{
OffersFullTime: {
baseSalary: {
currency: "SGD",
id: "cl96stky80033w32gxw5goc4z",
value: 84000
currency: 'SGD',
id: 'cl96stky80033w32gxw5goc4z',
value: 84000,
},
baseSalaryId: "cl96stky80033w32gxw5goc4z",
baseSalaryId: 'cl96stky80033w32gxw5goc4z',
bonus: {
currency: "SGD",
id: "cl96stky80035w32gajjwdo1p",
value: 123456789
currency: 'SGD',
id: 'cl96stky80035w32gajjwdo1p',
value: 123456789,
},
bonusId: "cl96stky80035w32gajjwdo1p",
id: "cl96stky80032w32gep9ovgj3",
level: "Junior",
specialization: "Front End",
bonusId: 'cl96stky80035w32gajjwdo1p',
id: 'cl96stky80032w32gep9ovgj3',
level: 'Junior',
specialization: 'Front End',
stocks: {
currency: "SGD",
id: "cl96stky90037w32gu04t6ybh",
value: 100
currency: 'SGD',
id: 'cl96stky90037w32gu04t6ybh',
value: 100,
},
stocksId: "cl96stky90037w32gu04t6ybh",
title: "Software Engineer",
stocksId: 'cl96stky90037w32gu04t6ybh',
title: 'Software Engineer',
totalCompensation: {
currency: "SGD",
id: "cl96stky90039w32glbpktd0o",
value: 104100
currency: 'SGD',
id: 'cl96stky90039w32glbpktd0o',
value: 104100,
},
totalCompensationId: "cl96stky90039w32glbpktd0o"
totalCompensationId: 'cl96stky90039w32glbpktd0o',
},
OffersIntern: null,
comments: null,
company: {
createdAt: new Date("2022-10-12T16:19:05.196Z"),
description: "Meta Platforms, Inc., doing business as Meta and formerly named Facebook, Inc., and TheFacebook, Inc., is an American multinational technology conglomerate based in Menlo Park, California. The company owns Facebook, Instagram, and WhatsApp, among other products and services.",
id: "cl95u79f000007im531ysjg79",
logoUrl: "https://logo.clearbit.com/meta.com",
name: "Meta",
slug: "meta",
updatedAt: new Date("2022-10-12T16:19:05.196Z")
createdAt: new Date('2022-10-12T16:19:05.196Z'),
description:
'Meta Platforms, Inc., doing business as Meta and formerly named Facebook, Inc., and TheFacebook, Inc., is an American multinational technology conglomerate based in Menlo Park, California. The company owns Facebook, Instagram, and WhatsApp, among other products and services.',
id: 'cl95u79f000007im531ysjg79',
logoUrl: 'https://logo.clearbit.com/meta.com',
name: 'Meta',
slug: 'meta',
updatedAt: new Date('2022-10-12T16:19:05.196Z'),
},
companyId: "cl95u79f000007im531ysjg79",
id: "cl96stky80031w32gau9mu1gs",
jobType: "FULLTIME",
location: "Singapore, Singapore",
monthYearReceived: new Date("2022-09-30T07:58:54.000Z"),
negotiationStrategy: "Leveraged having million offers",
offersFullTimeId: "cl96stky80032w32gep9ovgj3",
companyId: 'cl95u79f000007im531ysjg79',
id: 'cl96stky80031w32gau9mu1gs',
jobType: 'FULLTIME',
location: 'Singapore, Singapore',
monthYearReceived: new Date('2022-09-30T07:58:54.000Z'),
negotiationStrategy: 'Leveraged having million offers',
offersFullTimeId: 'cl96stky80032w32gep9ovgj3',
offersInternId: null,
profileId: "cl96stky5002ew32gx2kale2x"
profileId: 'cl96stky5002ew32gx2kale2x',
},
{
OffersFullTime: {
baseSalary: {
currency: "SGD",
id: "cl96stky9003dw32gcvqbijlo",
value: 1
currency: 'SGD',
id: 'cl96stky9003dw32gcvqbijlo',
value: 1,
},
baseSalaryId: "cl96stky9003dw32gcvqbijlo",
baseSalaryId: 'cl96stky9003dw32gcvqbijlo',
bonus: {
currency: "SGD",
id: "cl96stky9003fw32goc3zqxwr",
value: 0
currency: 'SGD',
id: 'cl96stky9003fw32goc3zqxwr',
value: 0,
},
bonusId: "cl96stky9003fw32goc3zqxwr",
id: "cl96stky9003cw32g5v10izfu",
level: "Senior",
specialization: "Front End",
bonusId: 'cl96stky9003fw32goc3zqxwr',
id: 'cl96stky9003cw32g5v10izfu',
level: 'Senior',
specialization: 'Front End',
stocks: {
currency: "SGD",
id: "cl96stky9003hw32g1lbbkqqr",
value: 999999
currency: 'SGD',
id: 'cl96stky9003hw32g1lbbkqqr',
value: 999999,
},
stocksId: "cl96stky9003hw32g1lbbkqqr",
title: "Software Engineer DOG",
stocksId: 'cl96stky9003hw32g1lbbkqqr',
title: 'Software Engineer DOG',
totalCompensation: {
currency: "SGD",
id: "cl96stky9003jw32gzumcoi7v",
value: 999999
currency: 'SGD',
id: 'cl96stky9003jw32gzumcoi7v',
value: 999999,
},
totalCompensationId: "cl96stky9003jw32gzumcoi7v"
totalCompensationId: 'cl96stky9003jw32gzumcoi7v',
},
OffersIntern: null,
comments: null,
company: {
createdAt: new Date("2022-10-12T16:19:05.196Z"),
description: "Meta Platforms, Inc., doing business as Meta and formerly named Facebook, Inc., and TheFacebook, Inc., is an American multinational technology conglomerate based in Menlo Park, California. The company owns Facebook, Instagram, and WhatsApp, among other products and services.",
id: "cl95u79f000007im531ysjg79",
logoUrl: "https://logo.clearbit.com/meta.com",
name: "Meta",
slug: "meta",
updatedAt: new Date("2022-10-12T16:19:05.196Z")
createdAt: new Date('2022-10-12T16:19:05.196Z'),
description:
'Meta Platforms, Inc., doing business as Meta and formerly named Facebook, Inc., and TheFacebook, Inc., is an American multinational technology conglomerate based in Menlo Park, California. The company owns Facebook, Instagram, and WhatsApp, among other products and services.',
id: 'cl95u79f000007im531ysjg79',
logoUrl: 'https://logo.clearbit.com/meta.com',
name: 'Meta',
slug: 'meta',
updatedAt: new Date('2022-10-12T16:19:05.196Z'),
},
companyId: "cl95u79f000007im531ysjg79",
id: "cl96stky9003bw32gc3l955vr",
jobType: "FULLTIME",
location: "Singapore, Singapore",
monthYearReceived: new Date("2022-09-30T07:58:54.000Z"),
negotiationStrategy: "LOst out having multiple offers",
offersFullTimeId: "cl96stky9003cw32g5v10izfu",
companyId: 'cl95u79f000007im531ysjg79',
id: 'cl96stky9003bw32gc3l955vr',
jobType: 'FULLTIME',
location: 'Singapore, Singapore',
monthYearReceived: new Date('2022-09-30T07:58:54.000Z'),
negotiationStrategy: 'LOst out having multiple offers',
offersFullTimeId: 'cl96stky9003cw32g5v10izfu',
offersInternId: null,
profileId: "cl96stky5002ew32gx2kale2x"
profileId: 'cl96stky5002ew32gx2kale2x',
},
{
OffersFullTime: {
baseSalary: {
currency: "SGD",
id: "cl976wf28000v7iygmk1b7qaq",
value: 1999999999
currency: 'SGD',
id: 'cl976wf28000v7iygmk1b7qaq',
value: 1999999999,
},
baseSalaryId: "cl976wf28000v7iygmk1b7qaq",
baseSalaryId: 'cl976wf28000v7iygmk1b7qaq',
bonus: {
currency: "SGD",
id: "cl976wf28000x7iyg63w7kcli",
value: 1410065407
currency: 'SGD',
id: 'cl976wf28000x7iyg63w7kcli',
value: 1410065407,
},
bonusId: "cl976wf28000x7iyg63w7kcli",
id: "cl976wf28000u7iyg6euei8e9",
level: "EXPERT",
specialization: "FRONTEND",
bonusId: 'cl976wf28000x7iyg63w7kcli',
id: 'cl976wf28000u7iyg6euei8e9',
level: 'EXPERT',
specialization: 'FRONTEND',
stocks: {
currency: "SGD",
id: "cl976wf28000z7iyg9ivun6ap",
value: 111222333
currency: 'SGD',
id: 'cl976wf28000z7iyg9ivun6ap',
value: 111222333,
},
stocksId: "cl976wf28000z7iyg9ivun6ap",
title: "Software Engineer",
stocksId: 'cl976wf28000z7iyg9ivun6ap',
title: 'Software Engineer',
totalCompensation: {
currency: "SGD",
id: "cl976wf2800117iygmzsc0xit",
value: 55555555
currency: 'SGD',
id: 'cl976wf2800117iygmzsc0xit',
value: 55555555,
},
totalCompensationId: "cl976wf2800117iygmzsc0xit"
totalCompensationId: 'cl976wf2800117iygmzsc0xit',
},
OffersIntern: null,
comments: "this IS SO COOL",
comments: 'this IS SO COOL',
company: {
createdAt: new Date("2022-10-12T16:19:05.196Z"),
description: "Meta Platforms, Inc., doing business as Meta and formerly named Facebook, Inc., and TheFacebook, Inc., is an American multinational technology conglomerate based in Menlo Park, California. The company owns Facebook, Instagram, and WhatsApp, among other products and services.",
id: "cl95u79f000007im531ysjg79",
logoUrl: "https://logo.clearbit.com/meta.com",
name: "Meta",
slug: "meta",
updatedAt: new Date("2022-10-12T16:19:05.196Z")
createdAt: new Date('2022-10-12T16:19:05.196Z'),
description:
'Meta Platforms, Inc., doing business as Meta and formerly named Facebook, Inc., and TheFacebook, Inc., is an American multinational technology conglomerate based in Menlo Park, California. The company owns Facebook, Instagram, and WhatsApp, among other products and services.',
id: 'cl95u79f000007im531ysjg79',
logoUrl: 'https://logo.clearbit.com/meta.com',
name: 'Meta',
slug: 'meta',
updatedAt: new Date('2022-10-12T16:19:05.196Z'),
},
companyId: "cl95u79f000007im531ysjg79",
id: "cl976wf28000t7iyga4noyz7s",
jobType: "FULLTIME",
location: "Singapore, Singapore",
monthYearReceived: new Date("2022-09-30T07:58:54.000Z"),
negotiationStrategy: "Charmed the guy with my face",
offersFullTimeId: "cl976wf28000u7iyg6euei8e9",
companyId: 'cl95u79f000007im531ysjg79',
id: 'cl976wf28000t7iyga4noyz7s',
jobType: 'FULLTIME',
location: 'Singapore, Singapore',
monthYearReceived: new Date('2022-09-30T07:58:54.000Z'),
negotiationStrategy: 'Charmed the guy with my face',
offersFullTimeId: 'cl976wf28000u7iyg6euei8e9',
offersInternId: null,
profileId: "cl96stky5002ew32gx2kale2x"
profileId: 'cl96stky5002ew32gx2kale2x',
},
{
OffersFullTime: {
baseSalary: {
currency: "SGD",
id: "cl96tbb3o0053w32gz11paaxu",
value: 1999999999
currency: 'SGD',
id: 'cl96tbb3o0053w32gz11paaxu',
value: 1999999999,
},
baseSalaryId: "cl96tbb3o0053w32gz11paaxu",
baseSalaryId: 'cl96tbb3o0053w32gz11paaxu',
bonus: {
currency: "SGD",
id: "cl96tbb3o0055w32gpyqgz5hx",
value: 1410065407
currency: 'SGD',
id: 'cl96tbb3o0055w32gpyqgz5hx',
value: 1410065407,
},
bonusId: "cl96tbb3o0055w32gpyqgz5hx",
id: "cl96tbb3o0052w32guguajzin",
level: "EXPERT",
specialization: "FRONTEND",
bonusId: 'cl96tbb3o0055w32gpyqgz5hx',
id: 'cl96tbb3o0052w32guguajzin',
level: 'EXPERT',
specialization: 'FRONTEND',
stocks: {
currency: "SGD",
id: "cl96tbb3o0057w32gu4nyxguf",
value: 500
currency: 'SGD',
id: 'cl96tbb3o0057w32gu4nyxguf',
value: 500,
},
stocksId: "cl96tbb3o0057w32gu4nyxguf",
title: "Software Engineer",
stocksId: 'cl96tbb3o0057w32gu4nyxguf',
title: 'Software Engineer',
totalCompensation: {
currency: "SGD",
id: "cl96tbb3o0059w32gm3iy1zk4",
value: 55555555
currency: 'SGD',
id: 'cl96tbb3o0059w32gm3iy1zk4',
value: 55555555,
},
totalCompensationId: "cl96tbb3o0059w32gm3iy1zk4"
totalCompensationId: 'cl96tbb3o0059w32gm3iy1zk4',
},
OffersIntern: null,
comments: "this rocks",
comments: 'this rocks',
company: {
createdAt: new Date("2022-10-12T16:19:05.196Z"),
description: "Meta Platforms, Inc., doing business as Meta and formerly named Facebook, Inc., and TheFacebook, Inc., is an American multinational technology conglomerate based in Menlo Park, California. The company owns Facebook, Instagram, and WhatsApp, among other products and services.",
id: "cl95u79f000007im531ysjg79",
logoUrl: "https://logo.clearbit.com/meta.com",
name: "Meta",
slug: "meta",
updatedAt: new Date("2022-10-12T16:19:05.196Z")
createdAt: new Date('2022-10-12T16:19:05.196Z'),
description:
'Meta Platforms, Inc., doing business as Meta and formerly named Facebook, Inc., and TheFacebook, Inc., is an American multinational technology conglomerate based in Menlo Park, California. The company owns Facebook, Instagram, and WhatsApp, among other products and services.',
id: 'cl95u79f000007im531ysjg79',
logoUrl: 'https://logo.clearbit.com/meta.com',
name: 'Meta',
slug: 'meta',
updatedAt: new Date('2022-10-12T16:19:05.196Z'),
},
companyId: "cl95u79f000007im531ysjg79",
id: "cl96tbb3o0051w32gjrpaiiit",
jobType: "FULLTIME",
location: "Singapore, Singapore",
monthYearReceived: new Date("2022-09-30T07:58:54.000Z"),
negotiationStrategy: "Charmed the guy with my face",
offersFullTimeId: "cl96tbb3o0052w32guguajzin",
companyId: 'cl95u79f000007im531ysjg79',
id: 'cl96tbb3o0051w32gjrpaiiit',
jobType: 'FULLTIME',
location: 'Singapore, Singapore',
monthYearReceived: new Date('2022-09-30T07:58:54.000Z'),
negotiationStrategy: 'Charmed the guy with my face',
offersFullTimeId: 'cl96tbb3o0052w32guguajzin',
offersInternId: null,
profileId: "cl96stky5002ew32gx2kale2x"
}
profileId: 'cl96stky5002ew32gx2kale2x',
},
],
profileName: "ailing bryann stuart ziqing",
token: "afca11e436d21bde24543718fa957c6c625335439dc504f24ee35eae7b5ef1ba",
userId: null
profileName: 'ailing bryann stuart ziqing',
token: 'afca11e436d21bde24543718fa957c6c625335439dc504f24ee35eae7b5ef1ba',
userId: null,
});
}
};
return (
<>

@ -6,12 +6,11 @@ function Test() {
const data = trpc.useQuery([
'offers.list',
{
companyId: 'cl95u79f000007im531ysjg79',
limit: 20,
limit: 100,
location: 'Singapore, Singapore',
offset: 0,
sortBy: '-monthYearReceived',
yoeCategory: 1,
sortBy: '-totalYoe',
yoeCategory: 2,
},
]);

@ -0,0 +1,14 @@
import React from 'react';
import { trpc } from '~/utils/trpc';
function profileAnalysis() {
const analysis = trpc.useQuery([
'offers.analysis.generate',
{ profileId: 'cl96stky5002ew32gx2kale2x' },
]);
return <div>{JSON.stringify(analysis.data)}</div>;
}
export default profileAnalysis;

@ -3,6 +3,7 @@ import superjson from 'superjson';
import { companiesRouter } from './companies-router';
import { createRouter } from './context';
import { offersRouter } from './offers/offers';
import { offersAnalysisRouter } from './offers/offers-analysis-router';
import { offersCommentsRouter } from './offers/offers-comments-router';
import { offersProfileRouter } from './offers/offers-profile-router';
import { protectedExampleRouter } from './protected-example-router';
@ -38,6 +39,7 @@ export const appRouter = createRouter()
.merge('questions.questions.', questionsQuestionRouter)
.merge('offers.', offersRouter)
.merge('offers.profile.', offersProfileRouter)
.merge('offers.analysis.', offersAnalysisRouter)
.merge('offers.comments.', offersCommentsRouter);
// Export type definition of API

@ -0,0 +1,264 @@
import { z } from 'zod';
import type {
Company,
OffersBackground,
OffersCurrency,
OffersFullTime,
OffersIntern,
OffersOffer,
OffersProfile,
} from '@prisma/client';
import { TRPCError } from '@trpc/server';
import { createRouter } from '../context';
const binarySearchOfferPercentile = (
offer: OffersOffer & {
OffersFullTime:
| (OffersFullTime & {
baseSalary: OffersCurrency;
bonus: OffersCurrency;
stocks: OffersCurrency;
totalCompensation: OffersCurrency;
})
| null;
OffersIntern: (OffersIntern & { monthlySalary: OffersCurrency }) | null;
company: Company;
profile: OffersProfile & { background: OffersBackground | null };
},
similarOffers: Array<any> | string,
) => {
let start = 0;
let end = similarOffers.length - 1;
while (start <= end) {
const mid = Math.floor((start + end) / 2);
if (similarOffers[mid].id === offer.id) {
return mid;
}
if (offer.id < similarOffers[mid].id) {
end = mid - 1;
} else {
start = mid + 1;
}
}
return -1;
};
export const offersAnalysisRouter = createRouter().query('generate', {
input: z.object({
profileId: z.string(),
}),
async resolve({ ctx, input }) {
const offers = await ctx.prisma.offersOffer.findMany({
include: {
OffersFullTime: {
include: {
baseSalary: true,
bonus: true,
stocks: true,
totalCompensation: true,
},
},
OffersIntern: {
include: {
monthlySalary: true,
},
},
company: true,
profile: {
include: {
background: true,
},
},
},
orderBy: [
{
OffersFullTime: {
totalCompensation: {
value: 'desc',
},
},
},
{
OffersIntern: {
monthlySalary: {
value: 'desc',
},
},
},
],
where: {
profileId: input.profileId,
},
});
if (!offers || offers.length === 0) {
throw new TRPCError({
code: 'NOT_FOUND',
message: 'No offers found on this profile',
});
}
const overallHighestOffer = offers[0];
// TODO: Shift yoe to background to make it mandatory
if (
!overallHighestOffer.profile.background ||
!overallHighestOffer.profile.background.totalYoe
) {
throw new TRPCError({
code: 'BAD_REQUEST',
message: 'Cannot analyse without YOE',
});
}
const yoe = overallHighestOffer.profile.background.totalYoe as number;
let similarOffers = await ctx.prisma.offersOffer.findMany({
include: {
OffersFullTime: {
include: {
totalCompensation: true,
},
},
OffersIntern: {
include: {
monthlySalary: true,
},
},
company: true,
profile: {
include: {
background: {
include: {
experiences: {
include: {
company: true,
},
},
},
},
},
},
},
orderBy: [
{
OffersFullTime: {
totalCompensation: {
value: 'desc',
},
},
},
{
OffersIntern: {
monthlySalary: {
value: 'desc',
},
},
},
],
where: {
AND: [
{
location: overallHighestOffer.location,
},
{
OR: [
{
OffersFullTime: {
level: overallHighestOffer.OffersFullTime?.level,
specialization:
overallHighestOffer.OffersFullTime?.specialization,
},
OffersIntern: {
specialization:
overallHighestOffer.OffersIntern?.specialization,
},
},
],
},
{
profile: {
background: {
AND: [
{
totalYoe: {
gte: Math.max(yoe - 1, 0),
lte: yoe + 1,
},
},
],
},
},
},
],
},
});
let similarCompanyOffers = similarOffers.filter(
(offer) => offer.companyId === overallHighestOffer.companyId,
);
// CALCULATE PERCENTILES
const highestOfferAgainstOverallIndex = binarySearchOfferPercentile(
overallHighestOffer,
similarOffers,
);
const highestOfferAgainstOverallPercentile =
highestOfferAgainstOverallIndex / similarOffers.length;
const highestOfferAgainstCompanyIndex = binarySearchOfferPercentile(
overallHighestOffer,
similarCompanyOffers,
);
const highestOfferAgainstCompanyPercentile =
highestOfferAgainstCompanyIndex / similarCompanyOffers.length;
// FIND TOP >=90 PERCENTILE OFFERS
similarOffers = similarOffers.filter(
(offer) => offer.id !== overallHighestOffer.id,
);
similarCompanyOffers = similarCompanyOffers.filter(
(offer) => offer.id !== overallHighestOffer.id,
);
const similarOffersCount = similarOffers.length;
const similarOffers90PercentileIndex =
Math.floor(similarOffersCount * 0.9) - 1;
const topPercentileOffers =
similarOffersCount > 1
? similarOffers.slice(
similarOffers90PercentileIndex,
similarOffers90PercentileIndex + 2,
)
: similarOffers;
const similarCompanyOffersCount = similarCompanyOffers.length;
const similarCompanyOffers90PercentileIndex =
Math.floor(similarCompanyOffersCount * 0.9) - 1;
const topPercentileCompanyOffers =
similarCompanyOffersCount > 1
? similarCompanyOffers.slice(
similarCompanyOffers90PercentileIndex,
similarCompanyOffers90PercentileIndex + 2,
)
: similarCompanyOffers;
return {
company: {
highestOfferAgainstCompanyPercentile,
similarCompanyOffersCount,
topPercentileCompanyOffers,
},
overall: {
highestOfferAgainstOverallPercentile,
similarOffersCount,
topPercentileOffers,
},
overallHighestOffer,
};
},
});

@ -16,8 +16,8 @@ const getYoeRange = (yoeCategory: number) => {
: yoeCategoryMap[yoeCategory] === 'Mid'
? { maxYoe: 7, minYoe: 4 }
: yoeCategoryMap[yoeCategory] === 'Senior'
? { maxYoe: null, minYoe: 8 }
: null;
? { maxYoe: 100, minYoe: 8 }
: null; // Internship
};
const ascOrder = '+';
@ -35,7 +35,7 @@ export const offersRouter = createRouter().query('list', {
companyId: z.string().nullish(),
dateEnd: z.date().nullish(),
dateStart: z.date().nullish(),
limit: z.number().nonnegative(),
limit: z.number().positive(),
location: z.string(),
offset: z.number().nonnegative(),
salaryMax: z.number().nullish(),
@ -43,9 +43,13 @@ export const offersRouter = createRouter().query('list', {
sortBy: z.string().regex(createSortByValidationRegex()).nullish(),
title: z.string().nullish(),
yoeCategory: z.number().min(0).max(3),
yoeMax: z.number().max(100).nullish(),
yoeMin: z.number().min(0).nullish(),
}),
async resolve({ ctx, input }) {
const yoeRange = getYoeRange(input.yoeCategory);
const yoeMin = input.yoeMin ? input.yoeMin : yoeRange?.minYoe;
const yoeMax = input.yoeMax ? input.yoeMax : yoeRange?.maxYoe;
let data = !yoeRange
? await ctx.prisma.offersOffer.findMany({
@ -89,68 +93,8 @@ export const offersRouter = createRouter().query('list', {
],
},
})
: yoeRange.maxYoe
? await ctx.prisma.offersOffer.findMany({
// Junior, Mid
include: {
OffersFullTime: {
include: {
baseSalary: true,
bonus: true,
stocks: true,
totalCompensation: true,
},
},
OffersIntern: {
include: {
monthlySalary: true,
},
},
company: true,
profile: {
include: {
background: true,
},
},
},
where: {
AND: [
{
location: input.location,
},
{
OffersIntern: {
is: null,
},
},
{
OffersFullTime: {
isNot: null,
},
},
{
profile: {
background: {
totalYoe: {
gte: yoeRange.minYoe,
},
},
},
},
{
profile: {
background: {
totalYoe: {
gte: yoeRange.maxYoe,
},
},
},
},
],
},
})
: await ctx.prisma.offersOffer.findMany({
// Senior
// Junior, Mid, Senior
include: {
OffersFullTime: {
include: {
@ -191,7 +135,8 @@ export const offersRouter = createRouter().query('list', {
profile: {
background: {
totalYoe: {
gte: yoeRange.minYoe,
gte: yoeMin,
lte: yoeMax,
},
},
},

Loading…
Cancel
Save