feat: Add is_system column to notes and update task note handling for system notes

This commit is contained in:
Chop
2025-06-19 22:12:07 +02:00
parent d40af1ff31
commit 3762f2e6f8
5 changed files with 93 additions and 36 deletions

View File

@@ -28,7 +28,7 @@ export async function GET(req) {
// POST: Add a note to a task // POST: Add a note to a task
export async function POST(req) { export async function POST(req) {
try { try {
const { task_id, note } = await req.json(); const { task_id, note, is_system } = await req.json();
if (!task_id || !note) { if (!task_id || !note) {
return NextResponse.json( 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 }); return NextResponse.json({ success: true });
} catch (error) { } catch (error) {
console.error("Error adding task note:", error); console.error("Error adding task note:", error);

View File

@@ -516,9 +516,7 @@ export default function ProjectTasksSection({ projectId }) {
</div> </div>
</td> </td>
</tr> </tr>
)} )} {/* Notes row (expandable) */}
{/* Notes row (expandable) */}
{expandedNotes[task.id] && ( {expandedNotes[task.id] && (
<tr className="bg-gray-50"> <tr className="bg-gray-50">
<td colSpan="6" className="px-4 py-4"> <td colSpan="6" className="px-4 py-4">
@@ -534,9 +532,20 @@ export default function ProjectTasksSection({ projectId }) {
{taskNotes[task.id].map((note) => ( {taskNotes[task.id].map((note) => (
<div <div
key={note.note_id} key={note.note_id}
className="bg-white p-3 rounded border flex justify-between items-start" className={`p-3 rounded border flex justify-between items-start ${
note.is_system
? 'bg-blue-50 border-blue-200'
: 'bg-white border-gray-200'
}`}
> >
<div className="flex-1"> <div className="flex-1">
<div className="flex items-center gap-2 mb-1">
{note.is_system && (
<span className="px-2 py-1 text-xs bg-blue-100 text-blue-700 rounded-full font-medium">
System
</span>
)}
</div>
<p className="text-sm text-gray-800"> <p className="text-sm text-gray-800">
{note.note} {note.note}
</p> </p>
@@ -550,6 +559,7 @@ export default function ProjectTasksSection({ projectId }) {
).toLocaleTimeString()} ).toLocaleTimeString()}
</p> </p>
</div> </div>
{!note.is_system && (
<button <button
onClick={() => onClick={() =>
handleDeleteNote( handleDeleteNote(
@@ -562,6 +572,7 @@ export default function ProjectTasksSection({ projectId }) {
> >
× ×
</button> </button>
)}
</div> </div>
))} ))}
</div> </div>

View File

@@ -137,7 +137,6 @@ export default function initializeDatabase() {
} catch (e) { } catch (e) {
// Column migration already done or geo_info doesn't exist, ignore error // Column migration already done or geo_info doesn't exist, ignore error
} }
// Migration: Add date_started column to project_tasks table // Migration: Add date_started column to project_tasks table
try { try {
db.exec(` db.exec(`
@@ -146,4 +145,13 @@ export default function initializeDatabase() {
} catch (e) { } catch (e) {
// Column already exists, ignore error // 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
}
} }

View File

@@ -19,10 +19,11 @@ export function getNotesByTaskId(task_id) {
.all(task_id); .all(task_id);
} }
export function addNoteToTask(task_id, note) { export function addNoteToTask(task_id, note, is_system = false) {
db.prepare(`INSERT INTO notes (task_id, note) VALUES (?, ?)`).run( db.prepare(`INSERT INTO notes (task_id, note, is_system) VALUES (?, ?, ?)`).run(
task_id, task_id,
note note,
is_system ? 1 : 0
); );
} }

View File

@@ -1,4 +1,5 @@
import db from "../db.js"; import db from "../db.js";
import { addNoteToTask } from "./notes.js";
// Get all task templates (for dropdown selection) // Get all task templates (for dropdown selection)
export function getAllTaskTemplates() { export function getAllTaskTemplates() {
@@ -59,25 +60,33 @@ export function getProjectTasks(projectId) {
// Create a new project task // Create a new project task
export function createProjectTask(data) { export function createProjectTask(data) {
let result;
let taskName;
if (data.task_template_id) { if (data.task_template_id) {
// Creating from template - explicitly set custom_max_wait_days to NULL so COALESCE uses template value // Creating from template - explicitly set custom_max_wait_days to NULL so COALESCE uses template value
const stmt = db.prepare(` const stmt = db.prepare(`
INSERT INTO project_tasks (project_id, task_template_id, custom_max_wait_days, status, priority) INSERT INTO project_tasks (project_id, task_template_id, custom_max_wait_days, status, priority)
VALUES (?, ?, NULL, ?, ?) VALUES (?, ?, NULL, ?, ?)
`); `);
return stmt.run( result = stmt.run(
data.project_id, data.project_id,
data.task_template_id, data.task_template_id,
data.status || "pending", data.status || "pending",
data.priority || "normal" 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 { } else {
// Creating custom task // Creating custom task
const stmt = db.prepare(` const stmt = db.prepare(`
INSERT INTO project_tasks (project_id, custom_task_name, custom_max_wait_days, custom_description, status, priority) INSERT INTO project_tasks (project_id, custom_task_name, custom_max_wait_days, custom_description, status, priority)
VALUES (?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?)
`); `);
return stmt.run( result = stmt.run(
data.project_id, data.project_id,
data.custom_task_name, data.custom_task_name,
data.custom_max_wait_days || 0, data.custom_max_wait_days || 0,
@@ -85,31 +94,50 @@ export function createProjectTask(data) {
data.status || "pending", data.status || "pending",
data.priority || "normal" 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 // Update project task status
export function updateProjectTaskStatus(taskId, status) { export function updateProjectTaskStatus(taskId, status) {
// First get the current status to check if we're transitioning from pending to in_progress // First get the current task details for logging
const getCurrentStatus = db.prepare( const getCurrentTask = db.prepare(`
"SELECT status FROM project_tasks WHERE id = ?" SELECT
); pt.status,
const currentTask = getCurrentStatus.get(taskId); 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 stmt;
let result;
if ( if (oldStatus === "pending" && status === "in_progress") {
currentTask &&
currentTask.status === "pending" &&
status === "in_progress"
) {
// Starting a task - set date_started // Starting a task - set date_started
stmt = db.prepare(` stmt = db.prepare(`
UPDATE project_tasks UPDATE project_tasks
SET status = ?, date_started = CURRENT_TIMESTAMP SET status = ?, date_started = CURRENT_TIMESTAMP
WHERE id = ? WHERE id = ?
`); `);
return stmt.run(status, taskId); result = stmt.run(status, taskId);
} else { } else {
// Just updating status without changing date_started // Just updating status without changing date_started
stmt = db.prepare(` stmt = db.prepare(`
@@ -117,8 +145,17 @@ export function updateProjectTaskStatus(taskId, status) {
SET status = ? SET status = ?
WHERE id = ? 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 // Delete a project task