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