Files
panel/src/app/api/project-tasks/route.js

139 lines
3.8 KiB
JavaScript

import {
getAllTaskTemplates,
getProjectTasks,
createProjectTask,
} from "@/lib/queries/tasks";
import { NextResponse } from "next/server";
import db from "@/lib/db";
import { withReadAuth, withUserAuth } from "@/lib/middleware/auth";
// GET: Get all project tasks or task templates based on query params
async function getProjectTasksHandler(req) {
const { searchParams } = new URL(req.url);
const projectId = searchParams.get("project_id");
if (projectId) {
// Get tasks for a specific project
const tasks = getProjectTasks(projectId);
return NextResponse.json(tasks);
} else {
// Default: return all task templates
const templates = getAllTaskTemplates();
return NextResponse.json(templates);
}
}
// POST: Create a new project task
async function createProjectTaskHandler(req) {
try {
const data = await req.json();
if (!data.project_id) {
return NextResponse.json(
{ error: "project_id is required" },
{ status: 400 }
);
}
// Check if it's a template task or custom task
if (!data.task_template_id && !data.custom_task_name) {
return NextResponse.json(
{ error: "Either task_template_id or custom_task_name is required" },
{ status: 400 }
);
}
// Add user tracking information from authenticated session
const taskData = {
...data,
created_by: req.user?.id || null,
};
// Set assigned_to: if specified, use it; otherwise default to creator only if they're not admin
if (data.assigned_to) {
taskData.assigned_to = data.assigned_to;
} else if (req.user?.id) {
// Check if the creator is an admin - if so, don't assign to them
const userRole = db.prepare('SELECT role FROM users WHERE id = ?').get(req.user.id);
taskData.assigned_to = userRole?.role === 'admin' ? null : req.user.id;
} else {
taskData.assigned_to = null;
}
const result = createProjectTask(taskData);
return NextResponse.json({ success: true, id: result.lastInsertRowid });
} catch (error) {
console.error("Error creating project task:", error);
return NextResponse.json(
{ error: "Failed to create project task", details: error.message },
{ status: 500 }
);
}
}
// PATCH: Handle special operations like migration
export async function PATCH(req) {
try {
const data = await req.json();
if (data.action === "fix_max_wait_days") {
console.log(
"Running migration to fix template-based tasks max_wait_days..."
);
// Update existing template-based tasks to set custom_max_wait_days to NULL
const result = db
.prepare(
`
UPDATE project_tasks
SET custom_max_wait_days = NULL
WHERE task_template_id IS NOT NULL
AND custom_max_wait_days = 0
`
)
.run();
console.log(
`Migration completed. Updated ${result.changes} template-based tasks.`
);
// Return updated tasks to verify
const updatedTasks = db
.prepare(
`
SELECT
pt.id,
pt.task_template_id,
pt.custom_max_wait_days,
t.max_wait_days as template_max,
t.name as template_name,
COALESCE(pt.custom_max_wait_days, t.max_wait_days) as calculated_max
FROM project_tasks pt
LEFT JOIN tasks t ON pt.task_template_id = t.task_id
WHERE pt.task_template_id IS NOT NULL
`
)
.all();
return NextResponse.json({
success: true,
message: `Updated ${result.changes} template-based tasks`,
updatedTasksCount: result.changes,
updatedTasks,
});
}
return NextResponse.json({ error: "Unknown action" }, { status: 400 });
} catch (error) {
console.error("Migration failed:", error);
return NextResponse.json(
{ error: "Migration failed", details: error.message },
{ status: 500 }
);
}
}
// Protected routes - require authentication
export const GET = withReadAuth(getProjectTasksHandler);
export const POST = withUserAuth(createProjectTaskHandler);