feat: implement server-side image compression with sharp and cleanup RLS policies
This commit is contained in:
69
src/app/api/upload/route.ts
Normal file
69
src/app/api/upload/route.ts
Normal file
@@ -0,0 +1,69 @@
|
||||
import sharp from 'sharp';
|
||||
import { createRouteHandlerClient } from '@supabase/auth-helpers-nextjs';
|
||||
import { cookies } from 'next/headers';
|
||||
import { NextResponse } from 'next/server';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
export async function POST(req: Request) {
|
||||
try {
|
||||
const supabase = createRouteHandlerClient({ cookies });
|
||||
|
||||
// Check session
|
||||
const { data: { session } } = await supabase.auth.getSession();
|
||||
if (!session) {
|
||||
return NextResponse.json({ error: 'Nicht autorisiert' }, { status: 401 });
|
||||
}
|
||||
|
||||
const userId = session.user.id;
|
||||
const formData = await req.formData();
|
||||
const file = formData.get('file') as File;
|
||||
|
||||
if (!file) {
|
||||
return NextResponse.json({ error: 'Keine Datei empfangen' }, { status: 400 });
|
||||
}
|
||||
|
||||
// 1. Buffer aus dem Upload erstellen
|
||||
const arrayBuffer = await file.arrayBuffer();
|
||||
const buffer = Buffer.from(arrayBuffer);
|
||||
|
||||
// 2. Mit Sharp optimieren
|
||||
const optimizedBuffer = await sharp(buffer)
|
||||
.resize(1200, 1200, {
|
||||
fit: 'inside',
|
||||
withoutEnlargement: true
|
||||
})
|
||||
.webp({ quality: 80 })
|
||||
.toBuffer();
|
||||
|
||||
// 3. Optimiertes Bild an Supabase Storage senden
|
||||
// Wir nutzen den userId/uuid.webp Pfad wie im Schema gefordert
|
||||
const fileName = `${userId}/${uuidv4()}.webp`;
|
||||
|
||||
const { data, error } = await supabase.storage
|
||||
.from('bottles')
|
||||
.upload(fileName, optimizedBuffer, {
|
||||
contentType: 'image/webp',
|
||||
upsert: true
|
||||
});
|
||||
|
||||
if (error) {
|
||||
console.error('Upload Error:', error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
// 4. Public URL generieren
|
||||
const { data: { publicUrl } } = supabase.storage
|
||||
.from('bottles')
|
||||
.getPublicUrl(fileName);
|
||||
|
||||
return NextResponse.json({
|
||||
path: data.path,
|
||||
url: publicUrl
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Optimization error:', error);
|
||||
return NextResponse.json({
|
||||
error: error instanceof Error ? error.message : 'Fehler bei der Bildverarbeitung'
|
||||
}, { status: 500 });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user