/** * Gantt Board Task CRUD Utilities * Full CRUD operations on gantt board tasks via Supabase */ const SUPABASE_URL = "https://qnatchrjlpehiijwtreh.supabase.co"; const SERVICE_KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InFuYXRjaHJqbHBlaGlpand0cmVoIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImlhdCI6MTc3MTY0MDQzNiwiZXhwIjoyMDg3MjE2NDM2fQ.rHoc3NfL59S4lejU4-ArSzox1krQkQG-TnfXb6sslm0"; const HEADERS = { "apikey": SERVICE_KEY, "Authorization": `Bearer ${SERVICE_KEY}`, "Content-Type": "application/json", }; /** * Generate UUID v4 */ function generateUUID(): string { return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => { const r = (Math.random() * 16) | 0; const v = c === "x" ? r : (r & 0x3) | 0x8; return v.toString(16); }); } /** * Get current ISO timestamp */ function nowISO(): string { return new Date().toISOString(); } /** * Task interface */ export interface GanttTask { id: string; title: string; description?: string; status: "open" | "todo" | "blocked" | "in-progress" | "review" | "validate" | "archived" | "canceled" | "done"; priority: "low" | "medium" | "high" | "urgent"; type?: "idea" | "task" | "bug" | "research" | "plan"; project_id: string; sprint_id?: string; assignee_id?: string; created_at: string; updated_at: string; due_date?: string; tags?: string[]; comments?: unknown[]; attachments?: unknown[]; } /** * LIST all tasks (optionally filtered by status) */ export async function listTasks(status?: string): Promise { let url = `${SUPABASE_URL}/rest/v1/tasks?select=*&order=created_at.desc`; if (status) { url = `${SUPABASE_URL}/rest/v1/tasks?select=*&status=eq.${status}&order=created_at.desc`; } const res = await fetch(url, { headers: HEADERS }); if (!res.ok) throw new Error(`Failed to list tasks: ${res.status}`); return res.json(); } /** * GET a single task by ID */ export async function getTask(taskId: string): Promise { const url = `${SUPABASE_URL}/rest/v1/tasks?id=eq.${taskId}&select=*`; const res = await fetch(url, { headers: HEADERS }); if (!res.ok) throw new Error(`Failed to get task: ${res.status}`); const tasks = await res.json(); return tasks[0] || null; } /** * CREATE a new task */ export async function createTask(params: { title: string; description?: string; status?: GanttTask["status"]; priority?: GanttTask["priority"]; type?: GanttTask["type"]; projectId?: string; assigneeId?: string; dueDate?: string; tags?: string[]; }): Promise { const task: Partial = { id: generateUUID(), title: params.title, description: params.description, status: params.status || "open", priority: params.priority || "medium", type: params.type || "task", project_id: params.projectId || "1", assignee_id: params.assigneeId || "9c29cc99-81a1-4e75-8dff-cd7cc5ceb5aa", // Max created_at: nowISO(), updated_at: nowISO(), due_date: params.dueDate, tags: params.tags || [], comments: [], attachments: [], }; const res = await fetch(`${SUPABASE_URL}/rest/v1/tasks`, { method: "POST", headers: HEADERS, body: JSON.stringify(task), }); if (!res.ok) throw new Error(`Failed to create task: ${res.status}`); return task as GanttTask; } /** * UPDATE a task (partial update) */ export async function updateTask( taskId: string, updates: Partial> ): Promise { const payload = { ...updates, updated_at: nowISO(), }; const res = await fetch(`${SUPABASE_URL}/rest/v1/tasks?id=eq.${taskId}`, { method: "PATCH", headers: HEADERS, body: JSON.stringify(payload), }); if (!res.ok) throw new Error(`Failed to update task: ${res.status}`); } /** * DELETE a task */ export async function deleteTask(taskId: string): Promise { const res = await fetch(`${SUPABASE_URL}/rest/v1/tasks?id=eq.${taskId}`, { method: "DELETE", headers: HEADERS, }); if (!res.ok) throw new Error(`Failed to delete task: ${res.status}`); } /** * Update task status (convenience method) */ export async function updateTaskStatus( taskId: string, status: GanttTask["status"] ): Promise { return updateTask(taskId, { status }); } /** * Assign task to user (convenience method) */ export async function assignTask( taskId: string, assigneeId: string ): Promise { return updateTask(taskId, { assignee_id: assigneeId }); } /** * Mark task as done (convenience method) */ export async function completeTask(taskId: string): Promise { return updateTask(taskId, { status: "done" }); } // Example usage: // const task = await createTask({ title: "New feature", priority: "high" }); // await updateTaskStatus(task.id, "in-progress"); // await completeTask(task.id);