Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions prisma/migrations/20260412020911_remove_unique_link/migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
Warnings:

- You are about to drop the column `uniqueLink` on the `Assessment` table. All the data in the column will be lost.

*/
-- DropIndex
DROP INDEX "public"."Assessment_uniqueLink_key";

-- AlterTable
ALTER TABLE "public"."Assessment" DROP COLUMN "uniqueLink";
1 change: 0 additions & 1 deletion prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,6 @@ model Assessment {
assessmentTemplateId String
assignedAt DateTime @default(now())
submittedAt DateTime?
uniqueLink String @unique
deadline DateTime?

application Application @relation(fields: [applicationId], references: [id], onDelete: Cascade)
Expand Down
2 changes: 0 additions & 2 deletions prisma/seed-data/assessment.seed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@ export const assessmentsData = [
{
id: 'assessment_carter_001',
assessmentTemplateId: 'assessment_template_general_001',
uniqueLink: 'https://assessment.sarge.dev/take/carter-herman-001',
deadline: new Date('2035-12-20T23:59:59Z'),
},
{
id: 'assessment_laith_001',
assessmentTemplateId: 'assessment_template_general_001',
uniqueLink: 'https://assessment.sarge.dev/take/laith-taher-001',
deadline: new Date('2035-12-20T23:59:59Z'),
},
];
4 changes: 2 additions & 2 deletions prisma/seed-data/organizations.seed.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
export const organizationsData = [
{
id: 'org_nextlab_001',
name: 'Next Lab',
slug: 'next-lab',
name: 'NExT',
slug: 'next',
logo: null,
},
];
2 changes: 0 additions & 2 deletions prisma/seed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -399,14 +399,12 @@ async function seedAssessments() {
where: { applicationId: application.id },
update: {
assessmentTemplateId: assessmentData.assessmentTemplateId,
uniqueLink: assessmentData.uniqueLink,
deadline: assessmentData.deadline,
},
create: {
id: assessmentData.id,
applicationId: application.id,
assessmentTemplateId: assessmentData.assessmentTemplateId,
uniqueLink: assessmentData.uniqueLink,
deadline: assessmentData.deadline,
},
});
Expand Down
25 changes: 16 additions & 9 deletions src/lib/components/templates/AssessmentTemplatePreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,15 +93,22 @@ export function AssessmentTemplatePreview({
<h1 className="text-display-xs text-foreground truncate font-medium">
{assessmentTemplatePreview.title}
</h1>
<div className="flex flex-row items-center gap-0.5">
<p className="text-body-s font-medium text-gray-400">Assigned to</p>
<p className="text-label-s text-sarge-primary-600 underline">
{assessmentTemplatePreview.positions.length > 0
? assessmentTemplatePreview.positions
.map((position) => position.title)
.join(', ')
: '0 positions'}
</p>
<div className="flex flex-row flex-wrap items-center gap-0.5">
<p className="text-body-s font-medium text-gray-400">Assigned to </p>
{assessmentTemplatePreview.positions.length > 0 ? (
assessmentTemplatePreview.positions.map((position, index) => (
<span key={position.id}>
<span className="text-label-s text-sarge-primary-600 underline">
{position.title}
</span>
{index < assessmentTemplatePreview.positions.length - 1 && ','}
</span>
))
) : (
<p className="text-label-s text-sarge-primary-600 underline">
0 positions
</p>
)}
</div>
</div>
<Button variant="secondary" className="h-fit px-4 py-2" asChild>
Expand Down
3 changes: 1 addition & 2 deletions src/lib/schemas/assessment.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,10 @@ export const assessmentSchema = z.object({
assessmentTemplateId: z.string(),
deadline: z.date().nullable(),
assignedAt: z.date(),
uniqueLink: z.string(),
submittedAt: z.date().nullable(),
});

export const createAssessmentSchema = assessmentSchema.omit({ id: true, uniqueLink: true });
export const createAssessmentSchema = assessmentSchema.omit({ id: true });

export const updateAssessmentSchema = assessmentSchema.partial().extend({
id: z.string(),
Expand Down
6 changes: 0 additions & 6 deletions src/lib/services/application.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import crypto from 'node:crypto';
import { prisma } from '@/lib/prisma';
import { NotFoundException, ForbiddenException } from '@/lib/utils/errors.utils';
import { type AddApplicationWithCandidateDataDTO } from '@/lib/schemas/application.schema';
Expand Down Expand Up @@ -65,7 +64,6 @@ async function addApplicationToPosition(
data: {
applicationId: createdApplication.id,
assessmentTemplateId: position.assessmentId,
uniqueLink: crypto.randomUUID(),
},
});

Expand Down Expand Up @@ -93,7 +91,6 @@ async function addApplicationToPosition(
assessment: {
select: {
id: true,
uniqueLink: true,
submittedAt: true,
},
},
Expand Down Expand Up @@ -184,7 +181,6 @@ async function batchAddApplicationsToPosition(
data: {
applicationId: application.id,
assessmentTemplateId,
uniqueLink: crypto.randomUUID(),
},
});

Expand Down Expand Up @@ -218,7 +214,6 @@ async function batchAddApplicationsToPosition(
assessment: {
select: {
id: true,
uniqueLink: true,
submittedAt: true,
},
},
Expand Down Expand Up @@ -270,7 +265,6 @@ async function getPositionApplications(
assessment: {
select: {
id: true,
uniqueLink: true,
submittedAt: true,
},
},
Expand Down
8 changes: 1 addition & 7 deletions src/lib/services/assessment.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,19 +75,14 @@ async function createAssessment(
`Assessment Template with id ${assessment.assessmentTemplateId} not found`
);
}
// the unique link shouldn't be the full link (bc the env of the link matters) so we just use id
const id = crypto.randomUUID();
const newAssessment = await prisma.assessment.create({
data: { ...assessment, id, uniqueLink: id },
data: { ...assessment, id },
});

return newAssessment;
}

function buildAssessmentLinkToken() {
return crypto.randomUUID();
}

async function assignTemplateToPosition(params: {
positionId: string;
assessmentTemplateId: string;
Expand Down Expand Up @@ -165,7 +160,6 @@ async function assignTemplateToPosition(params: {
data: {
applicationId: application.id,
assessmentTemplateId,
uniqueLink: buildAssessmentLinkToken(),
},
});

Expand Down
3 changes: 0 additions & 3 deletions src/lib/services/candidate.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ async function addCandidateToPosition(
assessment: {
select: {
id: true,
uniqueLink: true,
submittedAt: true,
},
},
Expand Down Expand Up @@ -149,7 +148,6 @@ async function batchAddCandidatesToPosition(
assessment: {
select: {
id: true,
uniqueLink: true,
submittedAt: true,
},
},
Expand Down Expand Up @@ -198,7 +196,6 @@ async function getPositionCandidates(
assessment: {
select: {
id: true,
uniqueLink: true,
submittedAt: true,
},
},
Expand Down
2 changes: 1 addition & 1 deletion src/lib/services/email.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export async function sendAssessmentInvitationEmail(

const baseUrl =
process.env.BETTER_AUTH_URL ?? process.env.NEXT_PUBLIC_APP_URL ?? 'http://localhost:3000';
const assessmentUrl = `${baseUrl}/assessment/${assessment.uniqueLink}`;
const assessmentUrl = `${baseUrl}/assessment/${assessment.id}`;
const logoUrl = `${baseUrl}/Sarge_logo.svg`;

//placeholder duration and expiration
Expand Down
2 changes: 0 additions & 2 deletions src/lib/services/position.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,6 @@ async function getPositionPreview(positionId: string, orgId: string): Promise<Po
assessment: {
select: {
id: true,
uniqueLink: true,
submittedAt: true,
assessmentTemplate: {
select: {
Expand Down Expand Up @@ -206,7 +205,6 @@ async function getPositionPreview(positionId: string, orgId: string): Promise<Po
assessment: app.assessment
? {
id: app.assessment.id,
uniqueLink: app.assessment.uniqueLink,
submittedAt: app.assessment.submittedAt,
reviews: app.assessment.reviews.map((review) => ({
reviewer: review.reviewer,
Expand Down
8 changes: 4 additions & 4 deletions src/lib/templates/invitation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export function generateAssessmentInvitationHTML(data: AssessmentInvitationEmail
</head>
<body style="margin: 0; padding: 20px; background-color: #f5f5f5; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;">
<div style="max-width: 600px; margin: 0 auto; background-color: #ffffff; border: 1px solid #e5e5e7; border-radius: 12px; overflow: hidden;">

<!-- Header -->
<div style="background-color: #4D38EF; padding: 24px; display: flex; align-items: flex-end; justify-content: space-between; gap: 20px;">
<div style="flex: 1;">
Expand All @@ -34,7 +34,7 @@ export function generateAssessmentInvitationHTML(data: AssessmentInvitationEmail
<!-- Body -->
<div style="padding: 32px 24px; color: #000000;">
<p style="margin: 0 0 16px 0; font-size: 16px; line-height: 1.5;">Hello ${data.candidateName},</p>

<p style="margin: 0 0 24px 0; font-size: 14px; line-height: 1.6; color: #333333;">
Thank you for your application and interest in ${data.organizationName}! The first step in our application process is a coding assessment to evaluate your technical and problem-solving skills.
</p>
Expand All @@ -59,8 +59,8 @@ export function generateAssessmentInvitationHTML(data: AssessmentInvitationEmail
</div>

<div style="text-align: center; margin: 0 0 24px 0;">
<a
href="/assessment/${data.assessmentId}"
<a
href="${data.assessmentUrl}"
style="display: inline-block; background-color: #5D5BF7; color: white; font-weight: 500; padding: 12px 28px; text-decoration: none; border-radius: 8px; font-size: 15px;"
>
Open Assessment
Expand Down
3 changes: 0 additions & 3 deletions src/lib/types/position.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ export interface ApplicationDisplayInfo {
};
assessment: {
id: string;
uniqueLink: string;
submittedAt: Date | null;
} | null;
grader: {
Expand Down Expand Up @@ -55,7 +54,6 @@ export interface PositionPreviewCandidate {
};
assessment: {
id: string;
uniqueLink: string;
submittedAt: Date | null;
reviews: {
reviewer: {
Expand Down Expand Up @@ -106,7 +104,6 @@ export interface PositionPreviewResponse {
};
assessment: {
id: string;
uniqueLink: string;
submittedAt: string | null;
reviews: {
reviewer: {
Expand Down
Loading