159 lines
4.3 KiB
JavaScript
159 lines
4.3 KiB
JavaScript
// Force this API route to use Node.js runtime for database access
|
|
export const runtime = "nodejs";
|
|
|
|
import {
|
|
getProjectById,
|
|
getProjectWithContract,
|
|
updateProject,
|
|
deleteProject,
|
|
} from "@/lib/queries/projects";
|
|
import { logFieldChange } from "@/lib/queries/fieldHistory";
|
|
import { addNoteToProject } from "@/lib/queries/notes";
|
|
import initializeDatabase from "@/lib/init-db";
|
|
import { NextResponse } from "next/server";
|
|
import { withReadAuth, withUserAuth, withTeamLeadAuth } from "@/lib/middleware/auth";
|
|
import {
|
|
logApiActionSafe,
|
|
AUDIT_ACTIONS,
|
|
RESOURCE_TYPES,
|
|
} from "@/lib/auditLogSafe.js";
|
|
import { getUserLanguage, serverT } from "@/lib/serverTranslations";
|
|
|
|
// Make sure the DB is initialized before queries run
|
|
initializeDatabase();
|
|
|
|
async function getProjectHandler(req, { params }) {
|
|
const { id } = await params;
|
|
const project = getProjectWithContract(parseInt(id));
|
|
|
|
if (!project) {
|
|
return NextResponse.json({ error: "Project not found" }, { status: 404 });
|
|
}
|
|
|
|
// Log project view
|
|
await logApiActionSafe(
|
|
req,
|
|
AUDIT_ACTIONS.PROJECT_VIEW,
|
|
RESOURCE_TYPES.PROJECT,
|
|
id,
|
|
req.auth, // Use req.auth instead of req.session
|
|
{ project_name: project.project_name }
|
|
);
|
|
|
|
return NextResponse.json(project);
|
|
}
|
|
|
|
async function updateProjectHandler(req, { params }) {
|
|
try {
|
|
const { id } = await params;
|
|
const data = await req.json();
|
|
|
|
// Get user ID from authenticated request
|
|
const userId = req.user?.id;
|
|
|
|
// Get original project data for audit log and field tracking
|
|
const originalProject = getProjectById(parseInt(id));
|
|
|
|
if (!originalProject) {
|
|
return NextResponse.json({ error: "Project not found" }, { status: 404 });
|
|
}
|
|
|
|
// Track field changes for specific fields we want to monitor
|
|
const fieldsToTrack = ['finish_date', 'project_status', 'assigned_to', 'contract_id', 'wartosc_zlecenia'];
|
|
|
|
for (const fieldName of fieldsToTrack) {
|
|
if (data.hasOwnProperty(fieldName)) {
|
|
const oldValue = originalProject[fieldName];
|
|
const newValue = data[fieldName];
|
|
|
|
if (oldValue !== newValue) {
|
|
try {
|
|
logFieldChange('projects', parseInt(id), fieldName, oldValue, newValue, userId);
|
|
} catch (error) {
|
|
console.error(`Failed to log field change for ${fieldName}:`, error);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Special handling for project cancellation
|
|
if (data.project_status === 'cancelled' && originalProject.project_status !== 'cancelled') {
|
|
const now = new Date();
|
|
const cancellationDate = now.toLocaleDateString('pl-PL', {
|
|
year: 'numeric',
|
|
month: '2-digit',
|
|
day: '2-digit',
|
|
hour: '2-digit',
|
|
minute: '2-digit'
|
|
});
|
|
|
|
const language = getUserLanguage();
|
|
const cancellationNote = `${serverT("Project cancelled on", language)} ${cancellationDate}`;
|
|
|
|
try {
|
|
addNoteToProject(parseInt(id), cancellationNote, userId, true); // true for is_system
|
|
} catch (error) {
|
|
console.error('Failed to log project cancellation:', error);
|
|
}
|
|
}
|
|
|
|
updateProject(parseInt(id), data, userId);
|
|
|
|
// Get updated project
|
|
const updatedProject = getProjectById(parseInt(id));
|
|
|
|
// Log project update
|
|
await logApiActionSafe(
|
|
req,
|
|
AUDIT_ACTIONS.PROJECT_UPDATE,
|
|
RESOURCE_TYPES.PROJECT,
|
|
id,
|
|
req.auth, // Use req.auth instead of req.session
|
|
{
|
|
originalData: originalProject,
|
|
updatedData: data,
|
|
changedFields: Object.keys(data),
|
|
}
|
|
);
|
|
|
|
return NextResponse.json(updatedProject);
|
|
} catch (error) {
|
|
console.error("Error in updateProjectHandler:", error);
|
|
return NextResponse.json(
|
|
{ error: "Internal server error", details: error.message },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|
|
|
|
async function deleteProjectHandler(req, { params }) {
|
|
const { id } = await params;
|
|
|
|
// Get project data before deletion for audit log
|
|
const project = getProjectById(parseInt(id));
|
|
|
|
deleteProject(parseInt(id));
|
|
|
|
// Log project deletion
|
|
await logApiActionSafe(
|
|
req,
|
|
AUDIT_ACTIONS.PROJECT_DELETE,
|
|
RESOURCE_TYPES.PROJECT,
|
|
id,
|
|
req.auth, // Use req.auth instead of req.session
|
|
{
|
|
deletedProject: {
|
|
project_name: project?.project_name,
|
|
project_number: project?.project_number,
|
|
},
|
|
}
|
|
);
|
|
|
|
return NextResponse.json({ success: true });
|
|
}
|
|
|
|
// Protected routes - require authentication
|
|
export const GET = withReadAuth(getProjectHandler);
|
|
export const PUT = withUserAuth(updateProjectHandler);
|
|
export const DELETE = withTeamLeadAuth(deleteProjectHandler);
|