![]() Server : Apache/2 System : Linux server-15-235-50-60 5.15.0-164-generic #174-Ubuntu SMP Fri Nov 14 20:25:16 UTC 2025 x86_64 User : gositeme ( 1004) PHP Version : 8.2.29 Disable Function : exec,system,passthru,shell_exec,proc_close,proc_open,dl,popen,show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname Directory : /home/gositeme/backups/lavocat.quebec/backup-20250730-021618/src/pages/api/cases/ |
import { NextApiRequest, NextApiResponse } from 'next';
import { getServerSession } from 'next-auth/next';
import { authOptions } from '@/lib/auth';
import { PrismaClient } from '@prisma/client';
import { canAccessCase, getCasePermissions } from '@/lib/case-permissions';
const prisma = new PrismaClient();
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const session = await getServerSession(req, res, authOptions);
if (!session?.user?.id) {
return res.status(401).json({ error: 'Unauthorized' });
}
const { id } = req.query;
if (!id || typeof id !== 'string') {
return res.status(400).json({ error: 'Case ID is required' });
}
switch (req.method) {
case 'GET':
return await getCaseById(req, res, id, session);
case 'PUT':
return await updateCase(req, res, id, session);
case 'PATCH':
return await patchCase(req, res, id, session);
case 'DELETE':
return await deleteCase(req, res, id, session);
default:
return res.status(405).json({ error: 'Method not allowed' });
}
}
async function getCaseById(req: NextApiRequest, res: NextApiResponse, id: string, session: any) {
try {
const caseData = await prisma.legalCase.findUnique({
where: { id },
include: {
leadLawyer: {
select: {
id: true,
name: true,
email: true,
title: true,
specialization: true,
lawFirm: {
select: {
id: true,
name: true,
shortName: true
}
}
}
},
creator: {
select: {
id: true,
name: true,
email: true
}
},
registrations: {
select: {
id: true,
firstName: true,
lastName: true,
status: true,
createdAt: true
},
orderBy: { createdAt: 'desc' },
take: 10
},
caseUpdates: {
select: {
id: true,
title: true,
description: true,
updateType: true,
isPublic: true,
createdAt: true,
author: {
select: {
name: true
}
}
},
orderBy: { createdAt: 'desc' },
take: 10
},
_count: {
select: {
registrations: true,
caseAssignments: true,
caseUpdates: true
}
}
}
});
if (!caseData) {
return res.status(404).json({ error: 'Case not found' });
}
// Check if user can access this case
if (!canAccessCase(session.user, caseData)) {
return res.status(403).json({ error: 'Access denied' });
}
// Get case-specific permissions for the user
const permissions = getCasePermissions(session.user, caseData);
res.status(200).json({
case: caseData,
permissions
});
} catch (error) {
console.error('Error fetching case:', error);
res.status(500).json({ error: 'Failed to fetch case' });
}
}
async function updateCase(req: NextApiRequest, res: NextApiResponse, id: string, session: any) {
try {
// First get the case to check permissions
const existingCase = await prisma.legalCase.findUnique({
where: { id },
include: {
leadLawyer: true,
creator: true
}
});
if (!existingCase) {
return res.status(404).json({ error: 'Case not found' });
}
// Check if user can update this case
const permissions = getCasePermissions(session.user, existingCase);
if (!permissions.canEdit) {
return res.status(403).json({ error: 'You do not have permission to edit this case' });
}
const {
title,
description,
caseNumber,
caseType,
jurisdiction,
court,
leadLawyerId,
priority,
budget,
status,
applicationDeadline,
isAcceptingApplications,
isPublic,
requiredDocuments,
eligibilityCriteria
} = req.body;
// Validation
if (!title || !description || !caseType || !jurisdiction) {
return res.status(400).json({
error: 'Missing required fields: title, description, caseType, jurisdiction'
});
}
// Verify lead lawyer exists and has appropriate role (if changed)
if (leadLawyerId && leadLawyerId !== existingCase.leadLawyerId) {
const leadLawyer = await prisma.user.findUnique({
where: { id: leadLawyerId },
select: { id: true, role: true, name: true, email: true }
});
if (!leadLawyer || !['LAWYER', 'ADMIN', 'SUPERADMIN'].includes(leadLawyer.role)) {
return res.status(400).json({ error: 'Invalid lead lawyer' });
}
}
// Check if case number already exists (if changed and provided)
if (caseNumber && caseNumber !== existingCase.caseNumber) {
const existingCaseWithNumber = await prisma.legalCase.findFirst({
where: {
caseNumber,
NOT: { id } // Exclude current case
}
});
if (existingCaseWithNumber) {
return res.status(400).json({ error: 'Case number already exists' });
}
}
const updatedCase = await prisma.legalCase.update({
where: { id },
data: {
title,
description,
caseNumber,
caseType,
jurisdiction,
court,
leadLawyerId: leadLawyerId || existingCase.leadLawyerId,
priority,
budget: budget ? parseFloat(budget) : null,
status,
applicationDeadline: applicationDeadline ? new Date(applicationDeadline) : null,
isAcceptingApplications,
isPublic,
requiredDocuments: requiredDocuments ? JSON.stringify(requiredDocuments) : existingCase.requiredDocuments,
eligibilityCriteria: eligibilityCriteria ? JSON.stringify(eligibilityCriteria) : existingCase.eligibilityCriteria
},
include: {
leadLawyer: {
select: {
id: true,
name: true,
email: true,
title: true,
specialization: true,
lawFirm: {
select: {
id: true,
name: true,
shortName: true
}
}
}
},
creator: {
select: {
id: true,
name: true,
email: true
}
}
}
});
// Create update log
await prisma.caseUpdate.create({
data: {
caseId: id,
title: 'Case Updated',
description: `Case "${title}" has been updated.`,
updateType: 'procedural',
isPublic: false,
createdBy: session.user.id
}
});
res.status(200).json(updatedCase);
} catch (error) {
console.error('Error updating case:', error);
res.status(500).json({ error: 'Failed to update case' });
}
}
async function patchCase(req: NextApiRequest, res: NextApiResponse, id: string, session: any) {
try {
// First get the case to check permissions
const existingCase = await prisma.legalCase.findUnique({
where: { id },
include: {
creator: true
}
});
if (!existingCase) {
return res.status(404).json({ error: 'Case not found' });
}
// Check if user can update this case (only case creator can change logo)
if (existingCase.createdBy !== session.user.id && !['ADMIN', 'SUPERADMIN'].includes(session.user.role)) {
return res.status(403).json({ error: 'You do not have permission to update this case' });
}
const { logoUrl } = req.body;
// Only allow logoUrl updates for now
if (!logoUrl) {
return res.status(400).json({ error: 'logoUrl is required' });
}
const updatedCase = await prisma.legalCase.update({
where: { id },
data: {
logoUrl
},
include: {
leadLawyer: {
select: {
id: true,
name: true,
email: true,
title: true,
specialization: true,
lawFirm: {
select: {
id: true,
name: true,
shortName: true
}
}
}
},
creator: {
select: {
id: true,
name: true,
email: true
}
}
}
});
res.status(200).json(updatedCase);
} catch (error) {
console.error('Error patching case:', error);
res.status(500).json({ error: 'Failed to update case' });
}
}
async function deleteCase(req: NextApiRequest, res: NextApiResponse, id: string, session: any) {
try {
// First get the case to check permissions
const existingCase = await prisma.legalCase.findUnique({
where: { id },
include: {
creator: true
}
});
if (!existingCase) {
return res.status(404).json({ error: 'Case not found' });
}
// Check if user can delete this case
const permissions = getCasePermissions(session.user, existingCase);
if (!permissions.canDelete) {
return res.status(403).json({ error: 'You do not have permission to delete this case' });
}
// Delete the case (this will cascade to related records)
await prisma.legalCase.delete({
where: { id }
});
res.status(200).json({ message: 'Case deleted successfully' });
} catch (error) {
console.error('Error deleting case:', error);
res.status(500).json({ error: 'Failed to delete case' });
}
}