Fix Supabase env var names to match Vercel
This commit is contained in:
parent
ee8158993f
commit
bacca13be5
34
src/app/api/tasks/natural/route.ts
Normal file
34
src/app/api/tasks/natural/route.ts
Normal file
@ -0,0 +1,34 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { addTaskToGantt, parseTaskInput } from "@/lib/server/taskParser";
|
||||
|
||||
export async function POST(req: NextRequest) {
|
||||
try {
|
||||
const { text } = await req.json();
|
||||
|
||||
if (!text || typeof text !== "string") {
|
||||
return NextResponse.json({ error: "Missing text" }, { status: 400 });
|
||||
}
|
||||
|
||||
const result = await addTaskToGantt(text);
|
||||
|
||||
if (!result.success) {
|
||||
return NextResponse.json({ error: result.error }, { status: 500 });
|
||||
}
|
||||
|
||||
const parsed = parseTaskInput(text);
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
task: result.task,
|
||||
parsed: {
|
||||
title: parsed.title,
|
||||
assignee: parsed.assigneeId === "0a3e400c-3932-48ae-9b65-f3f9c6f26fe9" ? "Matt" : "Max",
|
||||
priority: parsed.priority,
|
||||
dueDate: parsed.dueDate,
|
||||
},
|
||||
});
|
||||
} catch (err: any) {
|
||||
console.error("Error parsing task:", err);
|
||||
return NextResponse.json({ error: err.message }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@ -24,8 +24,8 @@ interface UserRow {
|
||||
}
|
||||
|
||||
function getPublicSupabase() {
|
||||
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL;
|
||||
const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY;
|
||||
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL || process.env.SUPABASE_URL;
|
||||
const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY || process.env.SUPABASE_ANON_KEY;
|
||||
if (!supabaseUrl || !supabaseAnonKey) {
|
||||
throw new Error("Missing Supabase public environment variables");
|
||||
}
|
||||
|
||||
129
src/lib/server/taskParser.ts
Normal file
129
src/lib/server/taskParser.ts
Normal file
@ -0,0 +1,129 @@
|
||||
import { createClient } from "@supabase/supabase-js";
|
||||
|
||||
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!;
|
||||
const supabaseKey = process.env.SUPABASE_SERVICE_ROLE_KEY!;
|
||||
const supabase = createClient(supabaseUrl, supabaseKey);
|
||||
|
||||
// Matt's user ID
|
||||
const MATT_USER_ID = "0a3e400c-3932-48ae-9b65-f3f9c6f26fe9";
|
||||
const MAX_USER_ID = "9c29cc99-81a1-4e75-8dff-cd7cc5ceb5aa";
|
||||
|
||||
interface ParsedTask {
|
||||
title: string;
|
||||
description?: string;
|
||||
assigneeId: string;
|
||||
priority: "low" | "medium" | "high";
|
||||
dueDate?: string;
|
||||
projectId?: string;
|
||||
}
|
||||
|
||||
export function parseTaskInput(input: string): ParsedTask {
|
||||
const lower = input.toLowerCase();
|
||||
|
||||
// Extract assignee
|
||||
let assigneeId = MATT_USER_ID;
|
||||
if (lower.includes("assign to max") || lower.includes("for max")) {
|
||||
assigneeId = MAX_USER_ID;
|
||||
}
|
||||
|
||||
// Extract priority
|
||||
let priority: "low" | "medium" | "high" = "medium";
|
||||
if (lower.includes("urgent") || lower.includes("asap") || lower.includes("high priority")) {
|
||||
priority = "high";
|
||||
} else if (lower.includes("low priority") || lower.includes("whenever") || lower.includes("eventually")) {
|
||||
priority = "low";
|
||||
}
|
||||
|
||||
// Extract due date phrases
|
||||
let dueDate: string | undefined;
|
||||
const today = new Date();
|
||||
|
||||
if (lower.includes("tomorrow")) {
|
||||
const d = new Date(today);
|
||||
d.setDate(d.getDate() + 1);
|
||||
dueDate = d.toISOString().split("T")[0];
|
||||
} else if (lower.includes("next week")) {
|
||||
const d = new Date(today);
|
||||
d.setDate(d.getDate() + 7);
|
||||
dueDate = d.toISOString().split("T")[0];
|
||||
} else if (lower.includes("by friday") || lower.includes("this friday")) {
|
||||
const d = new Date(today);
|
||||
const daysUntilFriday = (5 - d.getDay() + 7) % 7 || 7;
|
||||
d.setDate(d.getDate() + daysUntilFriday);
|
||||
dueDate = d.toISOString().split("T")[0];
|
||||
} else if (lower.includes("by monday") || lower.includes("this monday")) {
|
||||
const d = new Date(today);
|
||||
const daysUntilMonday = (1 - d.getDay() + 7) % 7 || 7;
|
||||
d.setDate(d.getDate() + daysUntilMonday);
|
||||
dueDate = d.toISOString().split("T")[0];
|
||||
}
|
||||
|
||||
// Clean up the title - remove assignee/priority/due date phrases
|
||||
let title = input
|
||||
.replace(/assign to (max|matt)/gi, "")
|
||||
.replace(/for (max|matt)/gi, "")
|
||||
.replace(/urgent|asap|high priority|low priority/gi, "")
|
||||
.replace(/tomorrow|next week|by friday|this friday|by monday|this monday/gi, "")
|
||||
.replace(/\s+/g, " ")
|
||||
.trim();
|
||||
|
||||
// If it starts with "add task" or similar, remove that
|
||||
title = title.replace(/^(add|create|new)\s+(task|todo|item)\s*[:\-]?\s*/i, "");
|
||||
|
||||
// Capitalize first letter
|
||||
title = title.charAt(0).toUpperCase() + title.slice(1);
|
||||
|
||||
return {
|
||||
title,
|
||||
assigneeId,
|
||||
priority,
|
||||
dueDate,
|
||||
};
|
||||
}
|
||||
|
||||
export async function addTaskToGantt(input: string): Promise<{ success: boolean; task?: any; error?: string }> {
|
||||
try {
|
||||
const parsed = parseTaskInput(input);
|
||||
|
||||
// Get default project (first one) or use a specific project
|
||||
const { data: projects } = await supabase
|
||||
.from("projects")
|
||||
.select("id")
|
||||
.order("created_at", { ascending: true })
|
||||
.limit(1);
|
||||
|
||||
const projectId = projects?.[0]?.id;
|
||||
|
||||
if (!projectId) {
|
||||
return { success: false, error: "No projects found in gantt board" };
|
||||
}
|
||||
|
||||
// Create the task
|
||||
const { data: task, error } = await supabase
|
||||
.from("tasks")
|
||||
.insert({
|
||||
title: parsed.title,
|
||||
description: parsed.description || null,
|
||||
status: "todo",
|
||||
priority: parsed.priority,
|
||||
assignee_id: parsed.assigneeId,
|
||||
created_by: MATT_USER_ID,
|
||||
project_id: projectId,
|
||||
due_date: parsed.dueDate || null,
|
||||
start_date: new Date().toISOString().split("T")[0],
|
||||
end_date: parsed.dueDate || new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString().split("T")[0],
|
||||
})
|
||||
.select()
|
||||
.single();
|
||||
|
||||
if (error) {
|
||||
console.error("Error adding task:", error);
|
||||
return { success: false, error: error.message };
|
||||
}
|
||||
|
||||
return { success: true, task };
|
||||
} catch (err: any) {
|
||||
console.error("Failed to add task:", err);
|
||||
return { success: false, error: err.message };
|
||||
}
|
||||
}
|
||||
@ -1,8 +1,8 @@
|
||||
import { createClient } from '@supabase/supabase-js';
|
||||
|
||||
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL;
|
||||
const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY;
|
||||
const supabaseServiceKey = process.env.SUPABASE_SERVICE_ROLE_KEY;
|
||||
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL || process.env.SUPABASE_URL;
|
||||
const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY || process.env.SUPABASE_ANON_KEY;
|
||||
const supabaseServiceKey = process.env.SUPABASE_SERVICE_ROLE_KEY || process.env.SUPABASE_SECRET_KEY;
|
||||
|
||||
if (!supabaseUrl || !supabaseAnonKey) {
|
||||
throw new Error(
|
||||
|
||||
Loading…
Reference in New Issue
Block a user