// 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 (?, ?, ?, ?, datetime('now', 'localtime')) ` ) .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 } = await 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 }); } // Protected routes - require authentication export const GET = withReadAuth(getNotesHandler); export const POST = withUserAuth(createNoteHandler); export const DELETE = withUserAuth(deleteNoteHandler);