130 lines
3.5 KiB
TypeScript
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 });
|
|
}
|
|
}
|