Files
panel/src/app/api/notes/route.js

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);