185 lines
4.4 KiB
JavaScript
185 lines
4.4 KiB
JavaScript
// Force this API route to use Node.js runtime for database access
|
|
export const runtime = "nodejs";
|
|
|
|
import db from "@/lib/db";
|
|
import { NextResponse } from "next/server";
|
|
import { withUserAuth, withReadAuth } from "@/lib/middleware/auth";
|
|
import {
|
|
logApiActionSafe,
|
|
AUDIT_ACTIONS,
|
|
RESOURCE_TYPES,
|
|
} from "@/lib/auditLogSafe.js";
|
|
|
|
async function getNotesHandler(req) {
|
|
const { searchParams } = new URL(req.url);
|
|
const projectId = searchParams.get("project_id");
|
|
const taskId = searchParams.get("task_id");
|
|
|
|
let query;
|
|
let params;
|
|
|
|
if (projectId) {
|
|
query = `
|
|
SELECT n.*,
|
|
u.name as created_by_name,
|
|
u.username as created_by_username
|
|
FROM notes n
|
|
LEFT JOIN users u ON n.created_by = u.id
|
|
WHERE n.project_id = ?
|
|
ORDER BY n.note_date DESC
|
|
`;
|
|
params = [projectId];
|
|
} else if (taskId) {
|
|
query = `
|
|
SELECT n.*,
|
|
u.name as created_by_name,
|
|
u.username as created_by_username
|
|
FROM notes n
|
|
LEFT JOIN users u ON n.created_by = u.id
|
|
WHERE n.task_id = ?
|
|
ORDER BY n.note_date DESC
|
|
`;
|
|
params = [taskId];
|
|
} else {
|
|
return NextResponse.json({ error: "project_id or task_id is required" }, { status: 400 });
|
|
}
|
|
|
|
try {
|
|
const notes = db.prepare(query).all(...params);
|
|
return NextResponse.json(notes);
|
|
} catch (error) {
|
|
console.error("Error fetching notes:", error);
|
|
return NextResponse.json(
|
|
{ error: "Failed to fetch notes" },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|
|
|
|
async function createNoteHandler(req) {
|
|
const { project_id, task_id, note } = await req.json();
|
|
|
|
if (!note || (!project_id && !task_id)) {
|
|
return NextResponse.json({ error: "Missing fields" }, { status: 400 });
|
|
}
|
|
|
|
try {
|
|
const result = db
|
|
.prepare(
|
|
`
|
|
INSERT INTO notes (project_id, task_id, note, created_by, note_date)
|
|
VALUES (?, ?, ?, ?, CURRENT_TIMESTAMP)
|
|
`
|
|
)
|
|
.run(project_id || null, task_id || null, note, req.user?.id || null);
|
|
|
|
// Get the created note with user info
|
|
const createdNote = db
|
|
.prepare(
|
|
`
|
|
SELECT n.*,
|
|
u.name as created_by_name,
|
|
u.username as created_by_username
|
|
FROM notes n
|
|
LEFT JOIN users u ON n.created_by = u.id
|
|
WHERE n.note_id = ?
|
|
`
|
|
)
|
|
.get(result.lastInsertRowid);
|
|
|
|
// Log note creation
|
|
await logApiActionSafe(
|
|
req,
|
|
AUDIT_ACTIONS.NOTE_CREATE,
|
|
RESOURCE_TYPES.NOTE,
|
|
result.lastInsertRowid.toString(),
|
|
req.auth, // Use req.auth instead of req.session
|
|
{
|
|
noteData: { project_id, task_id, note_length: note.length },
|
|
}
|
|
);
|
|
|
|
return NextResponse.json(createdNote);
|
|
} catch (error) {
|
|
console.error("Error creating note:", error);
|
|
return NextResponse.json(
|
|
{ error: "Failed to create note", details: error.message },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|
|
|
|
async function deleteNoteHandler(req, { params }) {
|
|
const { id } = params;
|
|
|
|
// Get note data before deletion for audit log
|
|
const note = db.prepare("SELECT * FROM notes WHERE note_id = ?").get(id);
|
|
|
|
db.prepare("DELETE FROM notes WHERE note_id = ?").run(id);
|
|
|
|
// Log note deletion
|
|
await logApiActionSafe(
|
|
req,
|
|
AUDIT_ACTIONS.NOTE_DELETE,
|
|
RESOURCE_TYPES.NOTE,
|
|
id,
|
|
req.auth, // Use req.auth instead of req.session
|
|
{
|
|
deletedNote: {
|
|
project_id: note?.project_id,
|
|
task_id: note?.task_id,
|
|
note_length: note?.note?.length || 0,
|
|
},
|
|
}
|
|
);
|
|
|
|
return NextResponse.json({ success: true });
|
|
}
|
|
|
|
async function updateNoteHandler(req, { params }) {
|
|
const noteId = params.id;
|
|
const { note } = await req.json();
|
|
|
|
if (!note || !noteId) {
|
|
return NextResponse.json({ error: "Missing note or ID" }, { status: 400 });
|
|
}
|
|
|
|
// Get original note for audit log
|
|
const originalNote = db
|
|
.prepare("SELECT * FROM notes WHERE note_id = ?")
|
|
.get(noteId);
|
|
|
|
db.prepare(
|
|
`
|
|
UPDATE notes SET note = ? WHERE note_id = ?
|
|
`
|
|
).run(note, noteId);
|
|
|
|
// Log note update
|
|
await logApiActionSafe(
|
|
req,
|
|
AUDIT_ACTIONS.NOTE_UPDATE,
|
|
RESOURCE_TYPES.NOTE,
|
|
noteId,
|
|
req.auth, // Use req.auth instead of req.session
|
|
{
|
|
originalNote: {
|
|
note_length: originalNote?.note?.length || 0,
|
|
project_id: originalNote?.project_id,
|
|
task_id: originalNote?.task_id,
|
|
},
|
|
updatedNote: {
|
|
note_length: note.length,
|
|
},
|
|
}
|
|
);
|
|
|
|
return NextResponse.json({ success: true });
|
|
}
|
|
|
|
// Protected routes - require authentication
|
|
export const GET = withReadAuth(getNotesHandler);
|
|
export const POST = withUserAuth(createNoteHandler);
|
|
export const DELETE = withUserAuth(deleteNoteHandler);
|
|
export const PUT = withUserAuth(updateNoteHandler);
|