feat: implement server-side image compression with sharp and cleanup RLS policies
This commit is contained in:
@@ -7,38 +7,47 @@ import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
export async function saveBottle(
|
||||
metadata: BottleMetadata,
|
||||
base64Image: string,
|
||||
_ignoredUserId: string // Keeping for signature compatibility if needed, but using session internally
|
||||
base64Image: string | null,
|
||||
_ignoredUserId: string, // Keeping for signature compatibility
|
||||
preUploadedUrl?: string
|
||||
) {
|
||||
const supabase = createServerActionClient({ cookies });
|
||||
|
||||
try {
|
||||
// Verify user session and get ID from the server side (secure)
|
||||
const { data: { session } } = await supabase.auth.getSession();
|
||||
if (!session) {
|
||||
throw new Error('Nicht autorisiert oder Session abgelaufen.');
|
||||
}
|
||||
|
||||
const userId = session.user.id;
|
||||
let finalImageUrl = preUploadedUrl;
|
||||
|
||||
// 1. Upload Image to Storage
|
||||
const base64Data = base64Image.split(',')[1] || base64Image;
|
||||
const buffer = Buffer.from(base64Data, 'base64');
|
||||
const fileName = `${userId}/${uuidv4()}.jpg`;
|
||||
// 1. Upload Image to Storage if not already uploaded
|
||||
if (!finalImageUrl && base64Image) {
|
||||
const base64Data = base64Image.split(',')[1] || base64Image;
|
||||
const buffer = Buffer.from(base64Data, 'base64');
|
||||
const fileName = `${userId}/${uuidv4()}.jpg`;
|
||||
|
||||
const { data: uploadData, error: uploadError } = await supabase.storage
|
||||
.from('bottles')
|
||||
.upload(fileName, buffer, {
|
||||
contentType: 'image/jpeg',
|
||||
upsert: true,
|
||||
});
|
||||
const { error: uploadError } = await supabase.storage
|
||||
.from('bottles')
|
||||
.upload(fileName, buffer, {
|
||||
contentType: 'image/jpeg',
|
||||
upsert: true,
|
||||
});
|
||||
|
||||
if (uploadError) throw new Error(`Upload Error: ${uploadError.message}`);
|
||||
if (uploadError) throw new Error(`Upload Error: ${uploadError.message}`);
|
||||
|
||||
// Get Public URL
|
||||
const { data: { publicUrl } } = supabase.storage
|
||||
.from('bottles')
|
||||
.getPublicUrl(fileName);
|
||||
// Get Public URL
|
||||
const { data: { publicUrl } } = supabase.storage
|
||||
.from('bottles')
|
||||
.getPublicUrl(fileName);
|
||||
|
||||
finalImageUrl = publicUrl;
|
||||
}
|
||||
|
||||
if (!finalImageUrl) {
|
||||
throw new Error('Kein Bild zum Speichern vorhanden.');
|
||||
}
|
||||
|
||||
// 2. Save Metadata to Database
|
||||
const { data: bottleData, error: dbError } = await supabase
|
||||
@@ -51,8 +60,8 @@ export async function saveBottle(
|
||||
abv: metadata.abv,
|
||||
age: metadata.age,
|
||||
whiskybase_id: metadata.whiskybaseId,
|
||||
image_url: publicUrl,
|
||||
status: 'sealed', // Default status
|
||||
image_url: finalImageUrl,
|
||||
status: 'sealed',
|
||||
is_whisky: metadata.is_whisky ?? true,
|
||||
confidence: metadata.confidence ?? 100,
|
||||
distilled_at: metadata.distilled_at,
|
||||
|
||||
Reference in New Issue
Block a user