gpt-engineer-app[bot] 85b88d9ee0 Run SQL migrations
2025-03-10 08:55:23 +00:00

156 lines
5.0 KiB
TypeScript

import "https://deno.land/x/xhr@0.1.0/mod.ts";
import { serve } from "https://deno.land/std@0.168.0/http/server.ts";
import { createClient } from "https://esm.sh/@supabase/supabase-js@2.38.1";
const corsHeaders = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',
};
const OPENAI_API_KEY = Deno.env.get('OPENAI_API_KEY');
const SUPABASE_URL = Deno.env.get('SUPABASE_URL') || "https://ffwcnetryatmpcnjkegg.supabase.co";
const SUPABASE_SERVICE_ROLE_KEY = Deno.env.get('SUPABASE_SERVICE_ROLE_KEY') || "";
serve(async (req) => {
// Handle CORS preflight requests
if (req.method === 'OPTIONS') {
return new Response(null, { headers: corsHeaders });
}
try {
const { uploadId, userId, filePath, fileType } = await req.json();
// Create Supabase client with service role key to bypass RLS
const supabase = createClient(SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY, {
auth: {
persistSession: false,
},
});
// Fetch the file content from Supabase Storage
const { data: fileData, error: fileError } = await supabase
.storage
.from('documents')
.download(filePath);
if (fileError) {
console.error('Error downloading file:', fileError);
return new Response(
JSON.stringify({ error: 'Error downloading file' }),
{ status: 500, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
);
}
// Convert file content to text
const text = await fileData.text();
// Extract tasks using OpenAI
const tasks = await extractTasksWithOpenAI(text, uploadId, userId);
// Save extracted tasks to the database
for (const task of tasks) {
const { error: taskError } = await supabase
.from('tasks')
.insert(task);
if (taskError) {
console.error('Error inserting task:', taskError);
}
}
// Update upload status to 'Completed'
const { error: updateError } = await supabase
.from('uploads')
.update({ status: 'Completed' })
.eq('id', uploadId);
if (updateError) {
console.error('Error updating upload status:', updateError);
return new Response(
JSON.stringify({ error: 'Error updating upload status' }),
{ status: 500, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
);
}
return new Response(
JSON.stringify({ success: true, tasksExtracted: tasks.length }),
{ headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
);
} catch (error) {
console.error('Error processing document:', error);
return new Response(
JSON.stringify({ error: error.message }),
{ status: 500, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
);
}
});
async function extractTasksWithOpenAI(text: string, uploadId: string, userId: string) {
try {
// Call OpenAI API to extract tasks
const response = await fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': `Bearer ${OPENAI_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: 'gpt-4o-mini',
messages: [
{
role: 'system',
content: `
You are a specialized task extractor for IT security and compliance policy documents.
Your job is to identify specific actionable tasks from policy documents.
For each task, extract the following information:
1. Task name (short, clear description of what needs to be done)
2. Description (more detailed explanation)
3. Priority (High, Medium, Low)
4. Due date (if mentioned)
Format your response as a valid JSON array of task objects with these properties:
[
{
"task_name": "string",
"description": "string",
"priority": "string",
"due_date": "ISO date string or null"
}
]
If no due date is mentioned for a task, return null for that field.
Only return the JSON array, nothing else.
`
},
{
role: 'user',
content: text
}
]
}),
});
const data = await response.json();
const extractedTasksJson = data.choices[0].message.content;
// Parse the extracted tasks
const extractedTasks = JSON.parse(extractedTasksJson);
// Format tasks for database insertion
return extractedTasks.map((task: any) => ({
upload_id: uploadId,
user_id: userId,
task_name: task.task_name,
description: task.description,
priority: task.priority,
due_date: task.due_date,
status: 'Open'
}));
} catch (error) {
console.error('Error extracting tasks with OpenAI:', error);
throw new Error('Failed to extract tasks from document');
}
}