Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add unique constraint to Hacker and update relations #66

Merged
merged 9 commits into from
Oct 15, 2024
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
Warnings:

- A unique constraint covering the columns `[userId,hackathonId]` on the table `Hacker` will be added. If there are existing duplicate values, this will fail.

*/
-- DropIndex
DROP INDEX "Hacker_userId_key";

-- CreateIndex
CREATE UNIQUE INDEX "Hacker_userId_hackathonId_key" ON "Hacker"("userId", "hackathonId");
2 changes: 2 additions & 0 deletions prisma/migrations/20241015132032_remove_unique/migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- DropIndex
DROP INDEX "Hacker_userId_hackathonId_key";
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
Warnings:

- A unique constraint covering the columns `[userId,hackathonId]` on the table `Hacker` will be added. If there are existing duplicate values, this will fail.

*/
-- CreateIndex
CREATE UNIQUE INDEX "Hacker_userId_hackathonId_key" ON "Hacker"("userId", "hackathonId");
5 changes: 3 additions & 2 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ model User {
forgotPasswordLastRequest DateTime?
image String?
accounts Account[]
hacker Hacker?
hacker Hacker[]
organizer Organizer?
sponsor Sponsor?
}
Expand Down Expand Up @@ -70,7 +70,7 @@ model Hackathon {
model Hacker {
id Int @id @default(autoincrement())
user User @relation(fields: [userId], references: [id])
userId Int @unique
userId Int
team Team? @relation(fields: [teamId], references: [id])
ownedTeam Team? @relation(name: "TeamOwner")
teamId Int?
Expand All @@ -80,6 +80,7 @@ model Hacker {
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
travelReimbursementRequest TravelReimbursementRequest?
@@unique([userId, hackathonId], name: "hackerApplication")
}

model Team {
Expand Down
10 changes: 9 additions & 1 deletion src/app/application/form/step/[stepId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import ApplicationFormStep from "@/scenes/ApplicationFormStep/ApplicationFormSte
import getApplicationFormStep from "@/server/getters/application/applicationFormStep";
import { Metadata } from "next";
import requireNonOrganizer from "@/services/helpers/requireNonOrganizer";
import getActiveHackathonId from "@/server/getters/getActiveHackathonId";
import { prisma } from "@/services/prisma";

export const metadata: Metadata = {
title: "Application Form",
Expand All @@ -14,8 +16,14 @@ const ApplicationFormStepPage = async ({
params: { stepId: string };
}) => {
await requireNonOrganizer();
const hackathonId = await getActiveHackathonId(prisma);
if (!hackathonId) {
return null;
}

const applicationFormStepData = await getApplicationFormStep(
Number(params.stepId)
Number(params.stepId),
hackathonId
);
return (
<ApplicationFormStep
Expand Down
7 changes: 5 additions & 2 deletions src/server/getters/application/application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ const getApplicationData = async ({
},
},
},
hackathonId: true,
},
},
},
Expand Down Expand Up @@ -185,7 +186,8 @@ const getApplicationData = async ({
steps.every((step) => step.isCompleted) && session.emailVerified;

// Get list of all free tables if user doesn't have table assigned
const tableCode = user.hacker?.team?.table?.code;
const hacker = user.hacker.find((h) => h.hackathonId === hackathonId);
const tableCode = hacker?.team?.table?.code;
let freeTables = [] as string[];
if (!tableCode) {
const tables = await prisma.table.findMany({
Expand Down Expand Up @@ -217,7 +219,8 @@ const getApplicationData = async ({
steps,
canSubmit,
hackathonName: hackathon.name,
tableCode: user.hacker?.team?.table?.code,
tableCode: user.hacker.find((h) => h.hackathonId === hackathonId)?.team
?.table?.code,
freeTables,
},
};
Expand Down
6 changes: 4 additions & 2 deletions src/server/getters/application/applicationFormStep.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ export type ApplicationFormStepData = {
};

const getApplicationFormStep = async (
stepId: number
stepId: number,
hackathonId: number
): Promise<ApplicationFormStepData> => {
const session = await getServerSession(authOptions);

Expand All @@ -38,9 +39,10 @@ const getApplicationFormStep = async (
};
}

const hacker = await prisma.hacker.findUnique({
const hacker = await prisma.hacker.findFirst({
where: {
userId: session.id,
hackathonId: hackathonId,
},
});

Expand Down
29 changes: 29 additions & 0 deletions src/server/services/helpers/applications/isApplicationComplete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,36 @@ const isApplicationComplete = async (
},
});

const application = await prisma.application.findUnique({
where: {
id: applicationId,
},
select: {
id: true,
hacker: {
select: {
hackathonId: true,
},
},
formValues: {
select: {
fieldId: true,
value: true,
},
},
},
});

if (!application || !application.hacker) {
throw new Error("Application or hacker not found");
}

const { hackathonId } = application.hacker;

const stepsDb = await prisma.applicationFormStep.findMany({
where: {
hackathonId,
},
select: {
formFields: {
select: {
Expand Down
6 changes: 5 additions & 1 deletion src/server/services/helpers/auth/requireHackerSession.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import "server-only";
import { getServerSession } from "next-auth/next";
import { authOptions } from "@/app/api/auth/[...nextauth]/route";
import { prisma } from "@/services/prisma";
import getActiveHackathonId from "@/server/getters/getActiveHackathonId";

type RequireHackerSessionOptions = {
verified?: boolean;
Expand All @@ -20,10 +21,13 @@ const requireHackerSession = async ({
throw new Error("User email not verified");
}

const hacker = await prisma.hacker.findUnique({
const hacker = await prisma.hacker.findFirst({
where: {
userId: session.id,
},
orderBy: {
createdAt: "desc",
},
});

if (!hacker) {
Expand Down
Loading