Files
fourge-portal/api/delete-project.js
Krao Hasanee 04e0911e9f fix: crash bugs in TeamInvoices + faster load
Bug fixes:
- TeamInvoices: add useAuth import/currentUser (invoice-create crash)
- TeamInvoices: setChartYear -> setExportYear (year-dropdown crash)
- TeamDashboard: drop redundant setState-in-effect (cascading renders)
- Companies: delete dead _UnusedClientCompanies (illegal hook calls)
- annotate intentional empty PDF-fallback catches

Load speed:
- preconnect/dns-prefetch to Supabase origin
- lazy-load heic-to in Converters: page chunk 2737KB -> 9KB
- split recharts into its own 'charts' vendor chunk

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 12:59:11 -04:00

62 lines
2.9 KiB
JavaScript

import { createClient } from '@supabase/supabase-js';
export default async function handler(req, res) {
if (req.method !== 'DELETE') return res.status(405).json({ error: 'Method not allowed' });
const authHeader = req.headers.authorization || '';
if (!authHeader.startsWith('Bearer ')) return res.status(401).json({ error: 'Unauthorized' });
const supabaseUrl = process.env.VITE_SUPABASE_URL || process.env.SUPABASE_URL;
const anonKey = process.env.VITE_SUPABASE_ANON_KEY || process.env.SUPABASE_ANON_KEY;
const serviceKey = process.env.SUPABASE_SERVICE_ROLE_KEY;
const callerClient = createClient(supabaseUrl, anonKey, {
auth: { persistSession: false, autoRefreshToken: false },
global: { headers: { Authorization: authHeader } },
});
const { data: userData } = await callerClient.auth.getUser();
if (!userData?.user) return res.status(401).json({ error: 'Unauthorized' });
const { data: profile } = await callerClient.from('profiles').select('id, role').eq('id', userData.user.id).single();
if (!profile || !['team', 'client'].includes(profile.role)) return res.status(403).json({ error: 'Forbidden' });
const projectId = req.query.id;
if (!projectId) return res.status(400).json({ error: 'Project ID required' });
const admin = createClient(supabaseUrl, serviceKey, {
auth: { persistSession: false, autoRefreshToken: false },
});
if (profile.role === 'client') {
const { data: proj, error: projErr } = await callerClient.from('projects').select('id').eq('id', projectId).single();
if (projErr || !proj) return res.status(404).json({ error: 'Project not found or access denied' });
}
const { data: tasks } = await admin.from('tasks').select('id').eq('project_id', projectId);
const taskIds = (tasks || []).map(t => t.id);
if (taskIds.length) {
const { data: subs } = await admin.from('submissions').select('id').in('task_id', taskIds);
const subIds = (subs || []).map(s => s.id);
if (subIds.length) {
const { data: subFiles } = await admin.from('submission_files').select('storage_path').in('submission_id', subIds);
const subPaths = (subFiles || []).map(f => f.storage_path).filter(Boolean);
if (subPaths.length) await admin.storage.from('submissions').remove(subPaths);
const { data: deliveries } = await admin.from('deliveries').select('id').in('submission_id', subIds);
const delIds = (deliveries || []).map(d => d.id);
if (delIds.length) {
const { data: delFiles } = await admin.from('delivery_files').select('storage_path').in('delivery_id', delIds);
const delPaths = (delFiles || []).map(f => f.storage_path).filter(Boolean);
if (delPaths.length) await admin.storage.from('deliveries').remove(delPaths);
}
}
}
const { error } = await admin.from('projects').delete().eq('id', projectId);
if (error) return res.status(500).json({ error: error.message });
return res.status(200).json({ ok: true });
}