JB/web/src/app/api/jobs/[id]/route.ts

130 lines
3.5 KiB
TypeScript

import { NextResponse } from "next/server";
import { getServerSession } from "next-auth/next";
import { authOptions } from "@/lib/auth";
import { prisma } from "@/lib/prisma";
import { calculateMatchScore, ResumeData } from "@/lib/matching";
import { getAuthUser, canManageJob, recordAuditLog } from "@/lib/authorization";
export async function GET(
req: Request,
{ params }: { params: { id: string } }
) {
try {
const session = await getServerSession(authOptions);
const userId = (session?.user as any)?.id;
const jobId = params.id;
const job = await prisma.job.findUnique({
where: { id: jobId },
include: {
companyRef: {
select: {
id: true,
name: true,
logoUrl: true,
location: true,
website: true,
description: true,
cultureInfo: true,
_count: {
select: { reviews: true, jobs: true },
},
},
},
_count: {
select: { applications: true },
},
},
});
if (!job) {
return NextResponse.json({ error: "Job posting not found" }, { status: 404 });
}
let userInteraction = null;
let matchScore: number | null = null;
if (userId) {
userInteraction = await prisma.userJobInteraction.findUnique({
where: {
userId_jobId: {
userId,
jobId,
},
},
});
const activeResume = await prisma.resume.findFirst({
where: { userId, isActiveForMatching: true },
});
if (activeResume?.data) {
try {
const resumeData: ResumeData =
typeof activeResume.data === "string"
? JSON.parse(activeResume.data)
: (activeResume.data as unknown as ResumeData);
matchScore = calculateMatchScore(resumeData, job.title, job.description);
} catch {
matchScore = null;
}
}
}
return NextResponse.json({
job: {
...job,
status: userInteraction?.status || null,
notes: userInteraction?.notes || null,
matchScore,
},
});
} catch (err: any) {
console.error("GET /api/jobs/[id] error:", err);
return NextResponse.json({ error: err.message || "Failed to fetch job posting" }, { status: 500 });
}
}
export async function DELETE(
req: Request,
{ params }: { params: { id: string } }
) {
const user = await getAuthUser();
if (!user) {
return NextResponse.json({ error: "Unauthorized: Please log in." }, { status: 401 });
}
try {
const jobId = params.id;
const job = await prisma.job.findUnique({
where: { id: jobId },
});
if (!job) {
return NextResponse.json({ error: "Job posting not found" }, { status: 404 });
}
if (!canManageJob(user, job, "job:delete")) {
return NextResponse.json(
{ error: "Forbidden: You do not have permission to delete this job posting." },
{ status: 403 }
);
}
await prisma.job.delete({
where: { id: jobId },
});
await recordAuditLog({
actorId: user.id,
action: "JOB_DELETE",
targetId: jobId,
details: { title: job.title, company: job.company },
});
return NextResponse.json({ success: true, message: "Job posting deleted successfully." });
} catch (err: any) {
console.error("DELETE /api/jobs/[id] error:", err);
return NextResponse.json({ error: err.message || "Failed to delete job posting" }, { status: 500 });
}
}