diff --git a/src/app/api/task-notes/route.js b/src/app/api/task-notes/route.js index 8631073..28652ac 100644 --- a/src/app/api/task-notes/route.js +++ b/src/app/api/task-notes/route.js @@ -28,7 +28,7 @@ export async function GET(req) { // POST: Add a note to a task export async function POST(req) { try { - const { task_id, note } = await req.json(); + const { task_id, note, is_system } = await req.json(); if (!task_id || !note) { return NextResponse.json( @@ -37,7 +37,7 @@ export async function POST(req) { ); } - addNoteToTask(task_id, note); + addNoteToTask(task_id, note, is_system); return NextResponse.json({ success: true }); } catch (error) { console.error("Error adding task note:", error); diff --git a/src/components/ProjectTasksSection.js b/src/components/ProjectTasksSection.js index 2bb6874..3d8a7c8 100644 --- a/src/components/ProjectTasksSection.js +++ b/src/components/ProjectTasksSection.js @@ -516,9 +516,7 @@ export default function ProjectTasksSection({ projectId }) { - )} - - {/* Notes row (expandable) */} + )} {/* Notes row (expandable) */} {expandedNotes[task.id] && ( @@ -534,9 +532,20 @@ export default function ProjectTasksSection({ projectId }) { {taskNotes[task.id].map((note) => (
+
+ {note.is_system && ( + + System + + )} +

{note.note}

@@ -550,18 +559,20 @@ export default function ProjectTasksSection({ projectId }) { ).toLocaleTimeString()}

- + {!note.is_system && ( + + )}
))} diff --git a/src/lib/init-db.js b/src/lib/init-db.js index 925994a..d29a17d 100644 --- a/src/lib/init-db.js +++ b/src/lib/init-db.js @@ -137,7 +137,6 @@ export default function initializeDatabase() { } catch (e) { // Column migration already done or geo_info doesn't exist, ignore error } - // Migration: Add date_started column to project_tasks table try { db.exec(` @@ -146,4 +145,13 @@ export default function initializeDatabase() { } catch (e) { // Column already exists, ignore error } + + // Migration: Add is_system column to notes table + try { + db.exec(` + ALTER TABLE notes ADD COLUMN is_system INTEGER DEFAULT 0; + `); + } catch (e) { + // Column already exists, ignore error + } } diff --git a/src/lib/queries/notes.js b/src/lib/queries/notes.js index b1befbe..a134d46 100644 --- a/src/lib/queries/notes.js +++ b/src/lib/queries/notes.js @@ -19,10 +19,11 @@ export function getNotesByTaskId(task_id) { .all(task_id); } -export function addNoteToTask(task_id, note) { - db.prepare(`INSERT INTO notes (task_id, note) VALUES (?, ?)`).run( +export function addNoteToTask(task_id, note, is_system = false) { + db.prepare(`INSERT INTO notes (task_id, note, is_system) VALUES (?, ?, ?)`).run( task_id, - note + note, + is_system ? 1 : 0 ); } diff --git a/src/lib/queries/tasks.js b/src/lib/queries/tasks.js index 6e558aa..33fb821 100644 --- a/src/lib/queries/tasks.js +++ b/src/lib/queries/tasks.js @@ -1,4 +1,5 @@ import db from "../db.js"; +import { addNoteToTask } from "./notes.js"; // Get all task templates (for dropdown selection) export function getAllTaskTemplates() { @@ -59,25 +60,33 @@ export function getProjectTasks(projectId) { // Create a new project task export function createProjectTask(data) { + let result; + let taskName; + if (data.task_template_id) { // Creating from template - explicitly set custom_max_wait_days to NULL so COALESCE uses template value const stmt = db.prepare(` INSERT INTO project_tasks (project_id, task_template_id, custom_max_wait_days, status, priority) VALUES (?, ?, NULL, ?, ?) `); - return stmt.run( + result = stmt.run( data.project_id, data.task_template_id, data.status || "pending", data.priority || "normal" ); + + // Get the template name for the log + const templateStmt = db.prepare("SELECT name FROM tasks WHERE task_id = ?"); + const template = templateStmt.get(data.task_template_id); + taskName = template?.name || "Unknown template"; } else { // Creating custom task const stmt = db.prepare(` INSERT INTO project_tasks (project_id, custom_task_name, custom_max_wait_days, custom_description, status, priority) VALUES (?, ?, ?, ?, ?, ?) `); - return stmt.run( + result = stmt.run( data.project_id, data.custom_task_name, data.custom_max_wait_days || 0, @@ -85,31 +94,50 @@ export function createProjectTask(data) { data.status || "pending", data.priority || "normal" ); + + taskName = data.custom_task_name; } + + // Add system note for task creation + if (result.lastInsertRowid) { + const priority = data.priority || "normal"; + const status = data.status || "pending"; + const logMessage = `Task "${taskName}" created with priority: ${priority}, status: ${status}`; + addNoteToTask(result.lastInsertRowid, logMessage, true); + } + + return result; } // Update project task status export function updateProjectTaskStatus(taskId, status) { - // First get the current status to check if we're transitioning from pending to in_progress - const getCurrentStatus = db.prepare( - "SELECT status FROM project_tasks WHERE id = ?" - ); - const currentTask = getCurrentStatus.get(taskId); + // First get the current task details for logging + const getCurrentTask = db.prepare(` + SELECT + pt.status, + COALESCE(pt.custom_task_name, t.name) as task_name + FROM project_tasks pt + LEFT JOIN tasks t ON pt.task_template_id = t.task_id + WHERE pt.id = ? + `); + const currentTask = getCurrentTask.get(taskId); + if (!currentTask) { + throw new Error(`Task with ID ${taskId} not found`); + } + + const oldStatus = currentTask.status; let stmt; + let result; - if ( - currentTask && - currentTask.status === "pending" && - status === "in_progress" - ) { + if (oldStatus === "pending" && status === "in_progress") { // Starting a task - set date_started stmt = db.prepare(` UPDATE project_tasks SET status = ?, date_started = CURRENT_TIMESTAMP WHERE id = ? `); - return stmt.run(status, taskId); + result = stmt.run(status, taskId); } else { // Just updating status without changing date_started stmt = db.prepare(` @@ -117,8 +145,17 @@ export function updateProjectTaskStatus(taskId, status) { SET status = ? WHERE id = ? `); - return stmt.run(status, taskId); + result = stmt.run(status, taskId); } + + // Add system note for status change (only if status actually changed) + if (result.changes > 0 && oldStatus !== status) { + const taskName = currentTask.task_name || "Unknown task"; + const logMessage = `Status changed from "${oldStatus}" to "${status}"`; + addNoteToTask(taskId, logMessage, true); + } + + return result; } // Delete a project task