mirror of
https://github.com/yangshun/tech-interview-handbook.git
synced 2025-07-30 05:34:33 +08:00
[offers][feat] Add delete OfferProfile API
This commit is contained in:
@ -201,7 +201,7 @@ model OffersBackground {
|
||||
|
||||
educations OffersEducation[] // For extensibility in the future
|
||||
|
||||
profile OffersProfile @relation(fields: [offersProfileId], references: [id])
|
||||
profile OffersProfile @relation(fields: [offersProfileId], references: [id], onDelete: Cascade)
|
||||
offersProfileId String @unique
|
||||
}
|
||||
|
||||
@ -211,7 +211,7 @@ model OffersSpecificYoe {
|
||||
yoe Int
|
||||
domain String
|
||||
|
||||
background OffersBackground @relation(fields: [backgroundId], references: [id])
|
||||
background OffersBackground @relation(fields: [backgroundId], references: [id], onDelete: Cascade)
|
||||
backgroundId String
|
||||
}
|
||||
|
||||
@ -237,7 +237,7 @@ model OffersExperience {
|
||||
monthlySalary OffersCurrency? @relation("ExperienceMonthlySalary", fields: [monthlySalaryId], references: [id])
|
||||
monthlySalaryId String? @unique
|
||||
|
||||
background OffersBackground @relation(fields: [backgroundId], references: [id])
|
||||
background OffersBackground @relation(fields: [backgroundId], references: [id], onDelete: Cascade)
|
||||
backgroundId String
|
||||
}
|
||||
|
||||
@ -270,12 +270,11 @@ model OffersEducation {
|
||||
type String?
|
||||
field String?
|
||||
|
||||
// Add more fields
|
||||
school String?
|
||||
startDate DateTime?
|
||||
endDate DateTime?
|
||||
|
||||
background OffersBackground @relation(fields: [backgroundId], references: [id])
|
||||
background OffersBackground @relation(fields: [backgroundId], references: [id], onDelete: Cascade)
|
||||
backgroundId String
|
||||
}
|
||||
|
||||
@ -289,14 +288,14 @@ model OffersReply {
|
||||
replyingTo OffersReply? @relation("ReplyThread", fields: [replyingToId], references: [id])
|
||||
replies OffersReply[] @relation("ReplyThread")
|
||||
|
||||
profile OffersProfile @relation(fields: [profileId], references: [id])
|
||||
profile OffersProfile @relation(fields: [profileId], references: [id], onDelete: Cascade)
|
||||
profileId String
|
||||
}
|
||||
|
||||
model OffersOffer {
|
||||
id String @id @default(cuid())
|
||||
|
||||
profile OffersProfile @relation(fields: [profileId], references: [id])
|
||||
profile OffersProfile @relation(fields: [profileId], references: [id], onDelete: Cascade)
|
||||
profileId String
|
||||
|
||||
company Company @relation(fields: [companyId], references: [id])
|
||||
@ -309,10 +308,10 @@ model OffersOffer {
|
||||
|
||||
jobType JobType
|
||||
|
||||
OffersIntern OffersIntern? @relation(fields: [offersInternId], references: [id])
|
||||
OffersIntern OffersIntern? @relation(fields: [offersInternId], references: [id], onDelete: Cascade)
|
||||
offersInternId String? @unique
|
||||
|
||||
OffersFullTime OffersFullTime? @relation(fields: [offersFullTimeId], references: [id])
|
||||
OffersFullTime OffersFullTime? @relation(fields: [offersFullTimeId], references: [id], onDelete: Cascade)
|
||||
offersFullTimeId String? @unique
|
||||
}
|
||||
|
||||
@ -323,7 +322,7 @@ model OffersIntern {
|
||||
specialization String
|
||||
internshipCycle String
|
||||
startYear Int
|
||||
monthlySalary OffersCurrency @relation(fields: [monthlySalaryId], references: [id])
|
||||
monthlySalary OffersCurrency @relation(fields: [monthlySalaryId], references: [id], onDelete: Cascade)
|
||||
monthlySalaryId String @unique
|
||||
|
||||
OffersOffer OffersOffer?
|
||||
@ -334,13 +333,13 @@ model OffersFullTime {
|
||||
title String
|
||||
specialization String
|
||||
level String
|
||||
totalCompensation OffersCurrency @relation("OfferTotalCompensation", fields: [totalCompensationId], references: [id])
|
||||
totalCompensation OffersCurrency @relation("OfferTotalCompensation", fields: [totalCompensationId], references: [id], onDelete: Cascade)
|
||||
totalCompensationId String @unique
|
||||
baseSalary OffersCurrency @relation("OfferBaseSalary", fields: [baseSalaryId], references: [id])
|
||||
baseSalary OffersCurrency @relation("OfferBaseSalary", fields: [baseSalaryId], references: [id], onDelete: Cascade)
|
||||
baseSalaryId String @unique
|
||||
bonus OffersCurrency @relation("OfferBonus", fields: [bonusId], references: [id])
|
||||
bonus OffersCurrency @relation("OfferBonus", fields: [bonusId], references: [id], onDelete: Cascade)
|
||||
bonusId String @unique
|
||||
stocks OffersCurrency @relation("OfferStocks", fields: [stocksId], references: [id])
|
||||
stocks OffersCurrency @relation("OfferStocks", fields: [stocksId], references: [id], onDelete: Cascade)
|
||||
stocksId String @unique
|
||||
|
||||
OffersOffer OffersOffer?
|
||||
|
@ -14,7 +14,39 @@ function Test() {
|
||||
},
|
||||
]);
|
||||
|
||||
return <>{JSON.stringify(data.data)}</>;
|
||||
const deleteMutation = trpc.useMutation(['offers.profile.delete']);
|
||||
|
||||
const handleDelete = (id: string) => {
|
||||
deleteMutation.mutate({ id });
|
||||
};
|
||||
|
||||
return (
|
||||
<ul>
|
||||
<li>
|
||||
<b>{JSON.stringify(data.data?.paging)}</b>
|
||||
</li>
|
||||
<li>
|
||||
<ul>
|
||||
{data.data?.data.map((offer) => {
|
||||
return (
|
||||
<li key={offer.id}>
|
||||
<button
|
||||
className="text-danger-600"
|
||||
type="button"
|
||||
onClick={() => {
|
||||
handleDelete(offer.profileId);
|
||||
}}>
|
||||
DELETE THIS PROFILE AND ALL ITS OFFERS
|
||||
</button>
|
||||
<div>{JSON.stringify(offer)}</div>
|
||||
<br />
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
|
||||
export default Test;
|
||||
|
@ -3,136 +3,142 @@ import React, { useState } from 'react';
|
||||
import { trpc } from '~/utils/trpc';
|
||||
|
||||
function Test() {
|
||||
// F const data = trpc.useQuery([
|
||||
// 'offers.profile.',
|
||||
// {
|
||||
// limit: 3,
|
||||
// location: 'Singapore, Singapore',
|
||||
// offset: 0,
|
||||
// yoeCategory: 0,
|
||||
// },
|
||||
// ]);
|
||||
// F const data = trpc.useQuery([
|
||||
// 'offers.profile.',
|
||||
// {
|
||||
// limit: 3,
|
||||
// location: 'Singapore, Singapore',
|
||||
// offset: 0,
|
||||
// yoeCategory: 0,
|
||||
// },
|
||||
// ]);
|
||||
|
||||
const [createdData, setCreatedData] = useState("")
|
||||
const [createdData, setCreatedData] = useState('');
|
||||
|
||||
const createMutation = trpc.useMutation(['offers.profile.create'], {
|
||||
onError(error: any) {
|
||||
alert(error)
|
||||
},
|
||||
onSuccess(data) {
|
||||
setCreatedData(JSON.stringify(data))
|
||||
},
|
||||
});
|
||||
|
||||
const handleClick = () => {
|
||||
createMutation.mutate({
|
||||
"background": {
|
||||
"educations": [
|
||||
{
|
||||
"endDate": new Date("2018-09-30T07:58:54.000Z"),
|
||||
"field": "Computer Science",
|
||||
"school": "National University of Singapore",
|
||||
"startDate": new Date("2014-09-30T07:58:54.000Z"),
|
||||
"type": "Bachelors"
|
||||
}
|
||||
],
|
||||
"experiences": [
|
||||
{
|
||||
"companyId": "cl92szctf0008i9nfxk54bhxn",
|
||||
"durationInMonths": 24,
|
||||
"jobType": "FULLTIME",
|
||||
"level": "Junior",
|
||||
// "monthlySalary": undefined,
|
||||
"specialization": "Front End",
|
||||
"title": "Software Engineer",
|
||||
"totalCompensation": {
|
||||
"currency": "SGD",
|
||||
"value": 104100
|
||||
}
|
||||
}
|
||||
],
|
||||
"specificYoes": [
|
||||
{
|
||||
"domain": "Front End",
|
||||
"yoe": 2
|
||||
},
|
||||
{
|
||||
"domain": "Full Stack",
|
||||
"yoe": 2
|
||||
}
|
||||
],
|
||||
"totalYoe": 4
|
||||
},
|
||||
"offers": [
|
||||
{
|
||||
"comments": "",
|
||||
"companyId": "cl92szctf0008i9nfxk54bhxn",
|
||||
"job": {
|
||||
"base": {
|
||||
"currency": "SGD",
|
||||
"value": 84000
|
||||
},
|
||||
"bonus": {
|
||||
"currency": "SGD",
|
||||
"value": 20000
|
||||
},
|
||||
"level": "Junior",
|
||||
"specialization": "Front End",
|
||||
"stocks": {
|
||||
"currency": "SGD",
|
||||
"value": 100
|
||||
},
|
||||
"title": "Software Engineer",
|
||||
"totalCompensation": {
|
||||
"currency": "SGD",
|
||||
"value": 104100
|
||||
}
|
||||
},
|
||||
"jobType": "FULLTIME",
|
||||
"location": "Singapore, Singapore",
|
||||
"monthYearReceived": new Date("2022-09-30T07:58:54.000Z"),
|
||||
"negotiationStrategy": "Leveraged having multiple offers"
|
||||
const createMutation = trpc.useMutation(['offers.profile.create'], {
|
||||
onError(error: any) {
|
||||
alert(error);
|
||||
},
|
||||
{
|
||||
"comments": "",
|
||||
"companyId": "cl92szctf0008i9nfxk54bhxn",
|
||||
"job": {
|
||||
"base": {
|
||||
"currency": "SGD",
|
||||
"value": 84000
|
||||
},
|
||||
"bonus": {
|
||||
"currency": "SGD",
|
||||
"value": 20000
|
||||
},
|
||||
"level": "Junior",
|
||||
"specialization": "Front End",
|
||||
"stocks": {
|
||||
"currency": "SGD",
|
||||
"value": 100
|
||||
},
|
||||
"title": "Software Engineer",
|
||||
"totalCompensation": {
|
||||
"currency": "SGD",
|
||||
"value": 104100
|
||||
}
|
||||
onSuccess(data) {
|
||||
setCreatedData(JSON.stringify(data));
|
||||
},
|
||||
});
|
||||
|
||||
const handleClick = () => {
|
||||
createMutation.mutate({
|
||||
background: {
|
||||
educations: [
|
||||
{
|
||||
endDate: new Date('2018-09-30T07:58:54.000Z'),
|
||||
field: 'Computer Science',
|
||||
school: 'National University of Singapore',
|
||||
startDate: new Date('2014-09-30T07:58:54.000Z'),
|
||||
type: 'Bachelors',
|
||||
},
|
||||
],
|
||||
experiences: [
|
||||
{
|
||||
companyId: 'cl93m87pl0000tx1ofbafqz6f',
|
||||
durationInMonths: 24,
|
||||
jobType: 'FULLTIME',
|
||||
level: 'Junior',
|
||||
// "monthlySalary": undefined,
|
||||
specialization: 'Front End',
|
||||
title: 'Software Engineer',
|
||||
totalCompensation: {
|
||||
currency: 'SGD',
|
||||
value: 104100,
|
||||
},
|
||||
},
|
||||
],
|
||||
specificYoes: [
|
||||
{
|
||||
domain: 'Front End',
|
||||
yoe: 2,
|
||||
},
|
||||
{
|
||||
domain: 'Full Stack',
|
||||
yoe: 2,
|
||||
},
|
||||
],
|
||||
totalYoe: 4,
|
||||
},
|
||||
"jobType": "FULLTIME",
|
||||
"location": "Singapore, Singapore",
|
||||
"monthYearReceived": new Date("2022-09-30T07:58:54.000Z"),
|
||||
"negotiationStrategy": "Leveraged having multiple offers"
|
||||
}
|
||||
]
|
||||
});
|
||||
};
|
||||
offers: [
|
||||
{
|
||||
comments: '',
|
||||
companyId: 'cl93m87pl0000tx1ofbafqz6f',
|
||||
job: {
|
||||
base: {
|
||||
currency: 'SGD',
|
||||
value: 84000,
|
||||
},
|
||||
bonus: {
|
||||
currency: 'SGD',
|
||||
value: 20000,
|
||||
},
|
||||
level: 'Junior',
|
||||
specialization: 'Front End',
|
||||
stocks: {
|
||||
currency: 'SGD',
|
||||
value: 100,
|
||||
},
|
||||
title: 'Software Engineer',
|
||||
totalCompensation: {
|
||||
currency: 'SGD',
|
||||
value: 104100,
|
||||
},
|
||||
},
|
||||
jobType: 'FULLTIME',
|
||||
location: 'Singapore, Singapore',
|
||||
monthYearReceived: new Date('2022-09-30T07:58:54.000Z'),
|
||||
negotiationStrategy: 'Leveraged having multiple offers',
|
||||
},
|
||||
{
|
||||
comments: '',
|
||||
companyId: 'cl93m87pl0000tx1ofbafqz6f',
|
||||
job: {
|
||||
base: {
|
||||
currency: 'SGD',
|
||||
value: 84000,
|
||||
},
|
||||
bonus: {
|
||||
currency: 'SGD',
|
||||
value: 20000,
|
||||
},
|
||||
level: 'Junior',
|
||||
specialization: 'Front End',
|
||||
stocks: {
|
||||
currency: 'SGD',
|
||||
value: 100,
|
||||
},
|
||||
title: 'Software Engineer',
|
||||
totalCompensation: {
|
||||
currency: 'SGD',
|
||||
value: 104100,
|
||||
},
|
||||
},
|
||||
jobType: 'FULLTIME',
|
||||
location: 'Singapore, Singapore',
|
||||
monthYearReceived: new Date('2022-09-30T07:58:54.000Z'),
|
||||
negotiationStrategy: 'Leveraged having multiple offers',
|
||||
},
|
||||
],
|
||||
});
|
||||
};
|
||||
|
||||
const data = trpc.useQuery([
|
||||
`offers.profile.listOne`,
|
||||
{
|
||||
profileId: "cl92wc64a004gw3hgq4pfln2m"
|
||||
}
|
||||
])
|
||||
const profileId = 'cl92wiw30006vw3hg7dxa14fo'; // Remember to change this filed after testing deleting
|
||||
const data = trpc.useQuery([
|
||||
`offers.profile.listOne`,
|
||||
{
|
||||
profileId,
|
||||
},
|
||||
]);
|
||||
|
||||
const deleteMutation = trpc.useMutation(['offers.profile.delete']);
|
||||
|
||||
const handleDelete = (id: string) => {
|
||||
deleteMutation.mutate({ id });
|
||||
};
|
||||
|
||||
return (
|
||||
// <ul>
|
||||
@ -140,14 +146,22 @@ function Test() {
|
||||
// return <li key={x.id}>{JSON.stringify(x)}</li>;
|
||||
// })}
|
||||
// </ul>
|
||||
<>
|
||||
<div>
|
||||
{createdData}
|
||||
</div>
|
||||
<button type="button" onClick={handleClick}>Click Me!</button>
|
||||
<>
|
||||
<div>{createdData}</div>
|
||||
<button type="button" onClick={handleClick}>
|
||||
Click Me!
|
||||
</button>
|
||||
<button
|
||||
className="text-danger-600"
|
||||
type="button"
|
||||
onClick={() => {
|
||||
handleDelete(profileId);
|
||||
}}>
|
||||
DELETE THIS PROFILE
|
||||
</button>
|
||||
<div>{JSON.stringify(data.data)}</div>
|
||||
|
||||
{/* <button type="button" onClick}>Get One</button> */}
|
||||
{/* <button type="button" onClick}>Get One</button> */}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -1,323 +1,353 @@
|
||||
import crypto, { randomUUID } from "crypto";
|
||||
import { z } from "zod";
|
||||
import { Prisma } from "@prisma/client";
|
||||
import crypto, { randomUUID } from 'crypto';
|
||||
import { z } from 'zod';
|
||||
import { Prisma } from '@prisma/client';
|
||||
|
||||
import { createRouter } from "./context";
|
||||
import { createRouter } from './context';
|
||||
|
||||
const valuation = z.object({
|
||||
currency: z.string(),
|
||||
value: z.number(),
|
||||
})
|
||||
currency: z.string(),
|
||||
value: z.number(),
|
||||
});
|
||||
|
||||
// TODO: handle both full time and intern
|
||||
const offer = z.object({
|
||||
comments: z.string(),
|
||||
companyId: z.string(),
|
||||
job: z.object({
|
||||
base: valuation.optional(), // Full time
|
||||
bonus: valuation.optional(), // Full time
|
||||
internshipCycle: z.string().optional(), // Intern
|
||||
level: z.string().optional(), // Full time
|
||||
monthlySalary: valuation.optional(), // Intern
|
||||
specialization: z.string(),
|
||||
startYear: z.number().optional(), // Intern
|
||||
stocks: valuation.optional(), // Full time
|
||||
title: z.string(),
|
||||
totalCompensation: valuation.optional(), // Full time
|
||||
}),
|
||||
jobType: z.string(),
|
||||
location: z.string(),
|
||||
monthYearReceived: z.date(),
|
||||
negotiationStrategy: z.string(),
|
||||
})
|
||||
comments: z.string(),
|
||||
companyId: z.string(),
|
||||
job: z.object({
|
||||
base: valuation.optional(), // Full time
|
||||
bonus: valuation.optional(), // Full time
|
||||
internshipCycle: z.string().optional(), // Intern
|
||||
level: z.string().optional(), // Full time
|
||||
monthlySalary: valuation.optional(), // Intern
|
||||
specialization: z.string(),
|
||||
startYear: z.number().optional(), // Intern
|
||||
stocks: valuation.optional(), // Full time
|
||||
title: z.string(),
|
||||
totalCompensation: valuation.optional(), // Full time
|
||||
}),
|
||||
jobType: z.string(),
|
||||
location: z.string(),
|
||||
monthYearReceived: z.date(),
|
||||
negotiationStrategy: z.string(),
|
||||
});
|
||||
|
||||
const experience = z.object({
|
||||
companyId: z.string().optional(),
|
||||
durationInMonths: z.number().optional(),
|
||||
jobType: z.string().optional(),
|
||||
level: z.string().optional(),
|
||||
monthlySalary: valuation.optional(),
|
||||
specialization: z.string().optional(),
|
||||
title: z.string().optional(),
|
||||
totalCompensation: valuation.optional(),
|
||||
})
|
||||
companyId: z.string().optional(),
|
||||
durationInMonths: z.number().optional(),
|
||||
jobType: z.string().optional(),
|
||||
level: z.string().optional(),
|
||||
monthlySalary: valuation.optional(),
|
||||
specialization: z.string().optional(),
|
||||
title: z.string().optional(),
|
||||
totalCompensation: valuation.optional(),
|
||||
});
|
||||
|
||||
const education = z.object({
|
||||
endDate: z.date().optional(),
|
||||
field: z.string().optional(),
|
||||
school: z.string().optional(),
|
||||
startDate: z.date().optional(),
|
||||
type: z.string().optional(),
|
||||
})
|
||||
endDate: z.date().optional(),
|
||||
field: z.string().optional(),
|
||||
school: z.string().optional(),
|
||||
startDate: z.date().optional(),
|
||||
type: z.string().optional(),
|
||||
});
|
||||
|
||||
export const offersProfileRouter = createRouter()
|
||||
.query('listOne', {
|
||||
input: z.object({
|
||||
profileId: z.string(),
|
||||
}),
|
||||
async resolve({ ctx, input }) {
|
||||
return await ctx.prisma.offersProfile.findFirst({
|
||||
.query('listOne', {
|
||||
input: z.object({
|
||||
profileId: z.string(),
|
||||
}),
|
||||
async resolve({ ctx, input }) {
|
||||
return await ctx.prisma.offersProfile.findFirst({
|
||||
include: {
|
||||
background: {
|
||||
include: {
|
||||
educations: true,
|
||||
experiences: {
|
||||
include: {
|
||||
background: {
|
||||
include: {
|
||||
educations: true,
|
||||
experiences: {
|
||||
include: {
|
||||
company: true,
|
||||
monthlySalary: true,
|
||||
totalCompensation: true
|
||||
}
|
||||
},
|
||||
specificYoes: true
|
||||
}
|
||||
},
|
||||
discussion: {
|
||||
include: {
|
||||
replies: true,
|
||||
replyingTo: true
|
||||
}
|
||||
},
|
||||
offers: {
|
||||
include: {
|
||||
OffersFullTime: {
|
||||
include: {
|
||||
baseSalary: true,
|
||||
bonus: true,
|
||||
stocks: true,
|
||||
totalCompensation: true
|
||||
}
|
||||
},
|
||||
OffersIntern: {
|
||||
include: {
|
||||
monthlySalary: true
|
||||
}
|
||||
},
|
||||
company: true
|
||||
}
|
||||
}
|
||||
},
|
||||
where: {
|
||||
id: input.profileId
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
.mutation(
|
||||
'create',
|
||||
{
|
||||
input: z.object({
|
||||
background: z.object({
|
||||
educations: z.array(education),
|
||||
experiences: z.array(experience),
|
||||
specificYoes: z.array(z.object({
|
||||
domain: z.string(),
|
||||
yoe: z.number(),
|
||||
})),
|
||||
totalYoe: z.number().optional(),
|
||||
}),
|
||||
offers: z.array(offer)
|
||||
}),
|
||||
async resolve({ ctx, input }) {
|
||||
|
||||
// TODO: add more
|
||||
const token = crypto
|
||||
.createHash("sha256")
|
||||
.update(Date.now().toString())
|
||||
.digest("hex");
|
||||
|
||||
const profile = await ctx.prisma.offersProfile.create({
|
||||
data: {
|
||||
background: {
|
||||
create: {
|
||||
educations: {
|
||||
create:
|
||||
input.background.educations.map((x) => ({
|
||||
endDate: x.endDate,
|
||||
field: x.field,
|
||||
school: x.school,
|
||||
startDate: x.startDate,
|
||||
type: x.type
|
||||
}))
|
||||
},
|
||||
experiences: {
|
||||
create:
|
||||
input.background.experiences.map((x) => {
|
||||
if (x.jobType === "FULLTIME" && x.totalCompensation?.currency !== undefined && x.totalCompensation.value !== undefined) {
|
||||
return {
|
||||
company: {
|
||||
connect: {
|
||||
id: x.companyId
|
||||
}
|
||||
},
|
||||
durationInMonths: x.durationInMonths,
|
||||
jobType: x.jobType,
|
||||
level: x.level,
|
||||
specialization: x.specialization,
|
||||
title: x.title,
|
||||
totalCompensation: {
|
||||
create: {
|
||||
currency: x.totalCompensation?.currency,
|
||||
value: x.totalCompensation?.value,
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
if (x.jobType === "INTERN" && x.monthlySalary?.currency !== undefined && x.monthlySalary.value !== undefined) {
|
||||
return {
|
||||
company: {
|
||||
connect: {
|
||||
id: x.companyId
|
||||
}
|
||||
},
|
||||
durationInMonths: x.durationInMonths,
|
||||
jobType: x.jobType,
|
||||
monthlySalary: {
|
||||
create: {
|
||||
currency: x.monthlySalary?.currency,
|
||||
value: x.monthlySalary?.value
|
||||
}
|
||||
},
|
||||
specialization: x.specialization,
|
||||
title: x.title,
|
||||
}
|
||||
}
|
||||
|
||||
throw Prisma.PrismaClientKnownRequestError
|
||||
|
||||
})
|
||||
},
|
||||
specificYoes: {
|
||||
create:
|
||||
input.background.specificYoes.map((x) => {
|
||||
return {
|
||||
domain: x.domain,
|
||||
yoe: x.yoe
|
||||
}
|
||||
})
|
||||
},
|
||||
totalYoe: input.background.totalYoe,
|
||||
}
|
||||
},
|
||||
editToken: token,
|
||||
offers: {
|
||||
create:
|
||||
input.offers.map((x) => {
|
||||
if (x.jobType === "INTERN" && x.job.internshipCycle !== undefined && x.job.monthlySalary?.currency !== undefined && x.job.monthlySalary.value !== undefined && x.job.startYear !== undefined) {
|
||||
return {
|
||||
OffersIntern: {
|
||||
create: {
|
||||
internshipCycle: x.job.internshipCycle,
|
||||
monthlySalary: {
|
||||
create: {
|
||||
currency: x.job.monthlySalary?.currency,
|
||||
value: x.job.monthlySalary?.value
|
||||
}
|
||||
},
|
||||
specialization: x.job.specialization,
|
||||
startYear: x.job.startYear,
|
||||
title: x.job.title,
|
||||
}
|
||||
},
|
||||
comments: x.comments,
|
||||
company: {
|
||||
connect: {
|
||||
id: x.companyId
|
||||
}
|
||||
},
|
||||
jobType: x.jobType,
|
||||
location: x.location,
|
||||
monthYearReceived: x.monthYearReceived,
|
||||
negotiationStrategy: x.negotiationStrategy
|
||||
}
|
||||
}
|
||||
if (x.jobType === "FULLTIME" && x.job.base?.currency !== undefined && x.job.base?.value !== undefined && x.job.bonus?.currency !== undefined && x.job.bonus?.value !== undefined && x.job.stocks?.currency !== undefined && x.job.stocks?.value !== undefined && x.job.totalCompensation?.currency !== undefined && x.job.totalCompensation?.value !== undefined && x.job.level !== undefined) {
|
||||
return {
|
||||
OffersFullTime: {
|
||||
create: {
|
||||
baseSalary: {
|
||||
create: {
|
||||
currency: x.job.base?.currency,
|
||||
value: x.job.base?.value
|
||||
}
|
||||
},
|
||||
bonus: {
|
||||
create: {
|
||||
currency: x.job.bonus?.currency,
|
||||
value: x.job.bonus?.value
|
||||
}
|
||||
},
|
||||
level: x.job.level,
|
||||
specialization: x.job.specialization,
|
||||
stocks: {
|
||||
create: {
|
||||
currency: x.job.stocks?.currency,
|
||||
value: x.job.stocks?.value,
|
||||
}
|
||||
},
|
||||
title: x.job.title,
|
||||
totalCompensation: {
|
||||
create: {
|
||||
currency: x.job.totalCompensation?.currency,
|
||||
value: x.job.totalCompensation?.value,
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
comments: x.comments,
|
||||
company: {
|
||||
connect: {
|
||||
id: x.companyId
|
||||
}
|
||||
},
|
||||
jobType: x.jobType,
|
||||
location: x.location,
|
||||
monthYearReceived: x.monthYearReceived,
|
||||
negotiationStrategy: x.negotiationStrategy
|
||||
}
|
||||
}
|
||||
|
||||
// Throw error
|
||||
throw Prisma.PrismaClientKnownRequestError
|
||||
})
|
||||
},
|
||||
profileName: randomUUID().substring(0,10),
|
||||
company: true,
|
||||
monthlySalary: true,
|
||||
totalCompensation: true,
|
||||
},
|
||||
},
|
||||
specificYoes: true,
|
||||
},
|
||||
},
|
||||
discussion: {
|
||||
include: {
|
||||
replies: true,
|
||||
replyingTo: true,
|
||||
},
|
||||
},
|
||||
offers: {
|
||||
include: {
|
||||
OffersFullTime: {
|
||||
include: {
|
||||
background: {
|
||||
include: {
|
||||
educations: true,
|
||||
experiences: {
|
||||
include: {
|
||||
company: true,
|
||||
monthlySalary: true,
|
||||
totalCompensation: true
|
||||
}
|
||||
},
|
||||
specificYoes: true
|
||||
}
|
||||
},
|
||||
offers: {
|
||||
include: {
|
||||
OffersFullTime: {
|
||||
include: {
|
||||
baseSalary: true,
|
||||
bonus: true,
|
||||
stocks: true,
|
||||
totalCompensation: true
|
||||
}
|
||||
},
|
||||
OffersIntern: {
|
||||
include: {
|
||||
monthlySalary: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
baseSalary: true,
|
||||
bonus: true,
|
||||
stocks: true,
|
||||
totalCompensation: true,
|
||||
},
|
||||
});
|
||||
|
||||
// TODO: add analysis to profile object then return
|
||||
return profile
|
||||
}
|
||||
},
|
||||
OffersIntern: {
|
||||
include: {
|
||||
monthlySalary: true,
|
||||
},
|
||||
},
|
||||
company: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
where: {
|
||||
id: input.profileId,
|
||||
},
|
||||
});
|
||||
},
|
||||
);
|
||||
})
|
||||
.mutation('create', {
|
||||
input: z.object({
|
||||
background: z.object({
|
||||
educations: z.array(education),
|
||||
experiences: z.array(experience),
|
||||
specificYoes: z.array(
|
||||
z.object({
|
||||
domain: z.string(),
|
||||
yoe: z.number(),
|
||||
}),
|
||||
),
|
||||
totalYoe: z.number().optional(),
|
||||
}),
|
||||
offers: z.array(offer),
|
||||
}),
|
||||
async resolve({ ctx, input }) {
|
||||
// TODO: add more
|
||||
const token = crypto
|
||||
.createHash('sha256')
|
||||
.update(Date.now().toString())
|
||||
.digest('hex');
|
||||
|
||||
const profile = await ctx.prisma.offersProfile.create({
|
||||
data: {
|
||||
background: {
|
||||
create: {
|
||||
educations: {
|
||||
create: input.background.educations.map((x) => ({
|
||||
endDate: x.endDate,
|
||||
field: x.field,
|
||||
school: x.school,
|
||||
startDate: x.startDate,
|
||||
type: x.type,
|
||||
})),
|
||||
},
|
||||
experiences: {
|
||||
create: input.background.experiences.map((x) => {
|
||||
if (
|
||||
x.jobType === 'FULLTIME' &&
|
||||
x.totalCompensation?.currency !== undefined &&
|
||||
x.totalCompensation.value !== undefined
|
||||
) {
|
||||
return {
|
||||
company: {
|
||||
connect: {
|
||||
id: x.companyId,
|
||||
},
|
||||
},
|
||||
durationInMonths: x.durationInMonths,
|
||||
jobType: x.jobType,
|
||||
level: x.level,
|
||||
specialization: x.specialization,
|
||||
title: x.title,
|
||||
totalCompensation: {
|
||||
create: {
|
||||
currency: x.totalCompensation?.currency,
|
||||
value: x.totalCompensation?.value,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
if (
|
||||
x.jobType === 'INTERN' &&
|
||||
x.monthlySalary?.currency !== undefined &&
|
||||
x.monthlySalary.value !== undefined
|
||||
) {
|
||||
return {
|
||||
company: {
|
||||
connect: {
|
||||
id: x.companyId,
|
||||
},
|
||||
},
|
||||
durationInMonths: x.durationInMonths,
|
||||
jobType: x.jobType,
|
||||
monthlySalary: {
|
||||
create: {
|
||||
currency: x.monthlySalary?.currency,
|
||||
value: x.monthlySalary?.value,
|
||||
},
|
||||
},
|
||||
specialization: x.specialization,
|
||||
title: x.title,
|
||||
};
|
||||
}
|
||||
|
||||
throw Prisma.PrismaClientKnownRequestError;
|
||||
}),
|
||||
},
|
||||
specificYoes: {
|
||||
create: input.background.specificYoes.map((x) => {
|
||||
return {
|
||||
domain: x.domain,
|
||||
yoe: x.yoe,
|
||||
};
|
||||
}),
|
||||
},
|
||||
totalYoe: input.background.totalYoe,
|
||||
},
|
||||
},
|
||||
editToken: token,
|
||||
offers: {
|
||||
create: input.offers.map((x) => {
|
||||
if (
|
||||
x.jobType === 'INTERN' &&
|
||||
x.job.internshipCycle !== undefined &&
|
||||
x.job.monthlySalary?.currency !== undefined &&
|
||||
x.job.monthlySalary.value !== undefined &&
|
||||
x.job.startYear !== undefined
|
||||
) {
|
||||
return {
|
||||
OffersIntern: {
|
||||
create: {
|
||||
internshipCycle: x.job.internshipCycle,
|
||||
monthlySalary: {
|
||||
create: {
|
||||
currency: x.job.monthlySalary?.currency,
|
||||
value: x.job.monthlySalary?.value,
|
||||
},
|
||||
},
|
||||
specialization: x.job.specialization,
|
||||
startYear: x.job.startYear,
|
||||
title: x.job.title,
|
||||
},
|
||||
},
|
||||
comments: x.comments,
|
||||
company: {
|
||||
connect: {
|
||||
id: x.companyId,
|
||||
},
|
||||
},
|
||||
jobType: x.jobType,
|
||||
location: x.location,
|
||||
monthYearReceived: x.monthYearReceived,
|
||||
negotiationStrategy: x.negotiationStrategy,
|
||||
};
|
||||
}
|
||||
if (
|
||||
x.jobType === 'FULLTIME' &&
|
||||
x.job.base?.currency !== undefined &&
|
||||
x.job.base?.value !== undefined &&
|
||||
x.job.bonus?.currency !== undefined &&
|
||||
x.job.bonus?.value !== undefined &&
|
||||
x.job.stocks?.currency !== undefined &&
|
||||
x.job.stocks?.value !== undefined &&
|
||||
x.job.totalCompensation?.currency !== undefined &&
|
||||
x.job.totalCompensation?.value !== undefined &&
|
||||
x.job.level !== undefined
|
||||
) {
|
||||
return {
|
||||
OffersFullTime: {
|
||||
create: {
|
||||
baseSalary: {
|
||||
create: {
|
||||
currency: x.job.base?.currency,
|
||||
value: x.job.base?.value,
|
||||
},
|
||||
},
|
||||
bonus: {
|
||||
create: {
|
||||
currency: x.job.bonus?.currency,
|
||||
value: x.job.bonus?.value,
|
||||
},
|
||||
},
|
||||
level: x.job.level,
|
||||
specialization: x.job.specialization,
|
||||
stocks: {
|
||||
create: {
|
||||
currency: x.job.stocks?.currency,
|
||||
value: x.job.stocks?.value,
|
||||
},
|
||||
},
|
||||
title: x.job.title,
|
||||
totalCompensation: {
|
||||
create: {
|
||||
currency: x.job.totalCompensation?.currency,
|
||||
value: x.job.totalCompensation?.value,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
comments: x.comments,
|
||||
company: {
|
||||
connect: {
|
||||
id: x.companyId,
|
||||
},
|
||||
},
|
||||
jobType: x.jobType,
|
||||
location: x.location,
|
||||
monthYearReceived: x.monthYearReceived,
|
||||
negotiationStrategy: x.negotiationStrategy,
|
||||
};
|
||||
}
|
||||
|
||||
// Throw error
|
||||
throw Prisma.PrismaClientKnownRequestError;
|
||||
}),
|
||||
},
|
||||
profileName: randomUUID().substring(0, 10),
|
||||
},
|
||||
include: {
|
||||
background: {
|
||||
include: {
|
||||
educations: true,
|
||||
experiences: {
|
||||
include: {
|
||||
company: true,
|
||||
monthlySalary: true,
|
||||
totalCompensation: true,
|
||||
},
|
||||
},
|
||||
specificYoes: true,
|
||||
},
|
||||
},
|
||||
offers: {
|
||||
include: {
|
||||
OffersFullTime: {
|
||||
include: {
|
||||
baseSalary: true,
|
||||
bonus: true,
|
||||
stocks: true,
|
||||
totalCompensation: true,
|
||||
},
|
||||
},
|
||||
OffersIntern: {
|
||||
include: {
|
||||
monthlySalary: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// TODO: add analysis to profile object then return
|
||||
return profile;
|
||||
},
|
||||
})
|
||||
.mutation('delete', {
|
||||
input: z.object({
|
||||
id: z.string(),
|
||||
}),
|
||||
async resolve({ ctx, input }) {
|
||||
return await ctx.prisma.offersProfile.delete({
|
||||
where: {
|
||||
id: input.id,
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
|
@ -200,6 +200,7 @@ export const offersRouter = createRouter().query('list', {
|
||||
},
|
||||
});
|
||||
|
||||
// FILTERING
|
||||
data = data.filter((offer) => {
|
||||
let validRecord = true;
|
||||
|
||||
@ -235,6 +236,7 @@ export const offersRouter = createRouter().query('list', {
|
||||
return validRecord;
|
||||
});
|
||||
|
||||
// SORTING
|
||||
data = data.sort((offer1, offer2) => {
|
||||
const defaultReturn =
|
||||
offer2.monthYearReceived.getTime() - offer1.monthYearReceived.getTime();
|
||||
|
Reference in New Issue
Block a user