{error}
diff --git a/src/services/save-tasting.ts b/src/services/save-tasting.ts
index a96fddf..6768fe7 100644
--- a/src/services/save-tasting.ts
+++ b/src/services/save-tasting.ts
@@ -6,11 +6,13 @@ import { revalidatePath } from 'next/cache';
export async function saveTasting(data: {
bottle_id: string;
+ session_id?: string;
rating: number;
nose_notes?: string;
palate_notes?: string;
finish_notes?: string;
is_sample?: boolean;
+ buddy_ids?: string[];
}) {
const supabase = createServerActionClient({ cookies });
@@ -23,6 +25,7 @@ export async function saveTasting(data: {
.insert({
bottle_id: data.bottle_id,
user_id: session.user.id,
+ session_id: data.session_id,
rating: data.rating,
nose_notes: data.nose_notes,
palate_notes: data.palate_notes,
@@ -34,6 +37,23 @@ export async function saveTasting(data: {
if (error) throw error;
+ // Add buddy tags if any
+ if (data.buddy_ids && data.buddy_ids.length > 0) {
+ const tags = data.buddy_ids.map(buddyId => ({
+ tasting_id: tasting.id,
+ buddy_id: buddyId
+ }));
+ const { error: tagError } = await supabase
+ .from('tasting_tags')
+ .insert(tags);
+
+ if (tagError) {
+ console.error('Error adding tasting tags:', tagError);
+ // We don't throw here to not fail the whole tasting save,
+ // but in a real app we might want more robust error handling
+ }
+ }
+
revalidatePath(`/bottles/${data.bottle_id}`);
return { success: true, data: tasting };
diff --git a/supa_schema.sql b/supa_schema.sql
index bc67ce1..84f5bdd 100644
--- a/supa_schema.sql
+++ b/supa_schema.sql
@@ -5,7 +5,7 @@ CREATE TABLE IF NOT EXISTS profiles (
id UUID REFERENCES auth.users ON DELETE CASCADE PRIMARY KEY,
username TEXT UNIQUE,
avatar_url TEXT,
- updated_at TIMESTAMP WITH TIME ZONE DEFAULT timezone('utc'::text, now())
+ updated_at TIMESTAMP WITH TIME ZONE DEFAULT timezone('Europe/Berlin'::text, now())
);
-- Function to handle new user signup
@@ -42,21 +42,54 @@ CREATE TABLE IF NOT EXISTS bottles (
image_url TEXT,
is_whisky BOOLEAN DEFAULT true,
confidence INTEGER DEFAULT 100,
- created_at TIMESTAMP WITH TIME ZONE DEFAULT timezone('utc'::text, now()),
- updated_at TIMESTAMP WITH TIME ZONE DEFAULT timezone('utc'::text, now())
+ created_at TIMESTAMP WITH TIME ZONE DEFAULT timezone('Europe/Berlin'::text, now()),
+ updated_at TIMESTAMP WITH TIME ZONE DEFAULT timezone('Europe/Berlin'::text, now())
);
--- Tastings table
+-- Buddies table
+CREATE TABLE IF NOT EXISTS buddies (
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
+ user_id UUID REFERENCES profiles(id) ON DELETE CASCADE NOT NULL,
+ name TEXT NOT NULL,
+ buddy_profile_id UUID REFERENCES profiles(id) ON DELETE SET NULL, -- Link to real account
+ created_at TIMESTAMP WITH TIME ZONE DEFAULT timezone('Europe/Berlin'::text, now())
+);
+
+-- Tasting Sessions table
+CREATE TABLE IF NOT EXISTS tasting_sessions (
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
+ user_id UUID REFERENCES profiles(id) ON DELETE CASCADE NOT NULL,
+ name TEXT NOT NULL,
+ scheduled_at TIMESTAMP WITH TIME ZONE DEFAULT timezone('Europe/Berlin'::text, now()),
+ created_at TIMESTAMP WITH TIME ZONE DEFAULT timezone('Europe/Berlin'::text, now())
+);
+
+-- Session Participants junction
+CREATE TABLE IF NOT EXISTS session_participants (
+ session_id UUID REFERENCES tasting_sessions(id) ON DELETE CASCADE NOT NULL,
+ buddy_id UUID REFERENCES buddies(id) ON DELETE CASCADE NOT NULL,
+ PRIMARY KEY (session_id, buddy_id)
+);
+
+-- Tastings table (updated with session and buddy tagging)
CREATE TABLE IF NOT EXISTS tastings (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
bottle_id UUID REFERENCES bottles(id) ON DELETE CASCADE NOT NULL,
user_id UUID REFERENCES profiles(id) ON DELETE CASCADE NOT NULL,
+ session_id UUID REFERENCES tasting_sessions(id) ON DELETE SET NULL,
rating INTEGER CHECK (rating >= 0 AND rating <= 100),
nose_notes TEXT,
palate_notes TEXT,
finish_notes TEXT,
audio_transcript_url TEXT,
- created_at TIMESTAMP WITH TIME ZONE DEFAULT timezone('utc'::text, now())
+ created_at TIMESTAMP WITH TIME ZONE DEFAULT timezone('Europe/Berlin'::text, now())
+);
+
+-- Tasting Tagging (to tag buddies in a tasting)
+CREATE TABLE IF NOT EXISTS tasting_tags (
+ tasting_id UUID REFERENCES tastings(id) ON DELETE CASCADE NOT NULL,
+ buddy_id UUID REFERENCES buddies(id) ON DELETE CASCADE NOT NULL,
+ PRIMARY KEY (tasting_id, buddy_id)
);
-- Enable Row Level Security (RLS)
@@ -88,6 +121,15 @@ CREATE POLICY "Users can delete their own bottles" ON bottles
CREATE POLICY "Users can view their own tastings" ON tastings
FOR SELECT USING (auth.uid() = user_id);
+-- Geteilte Tastings für Buddies sichtbar machen (wenn verknüpft)
+CREATE POLICY "Users can view tastings they are tagged in" ON tastings
+ FOR SELECT USING (
+ id IN (
+ SELECT tasting_id FROM tasting_tags
+ WHERE buddy_id IN (SELECT id FROM buddies WHERE buddy_profile_id = auth.uid())
+ )
+ );
+
CREATE POLICY "Users can insert their own tastings" ON tastings
FOR INSERT WITH CHECK (auth.uid() = user_id);
@@ -97,6 +139,47 @@ CREATE POLICY "Users can update their own tastings" ON tastings
CREATE POLICY "Users can delete their own tastings" ON tastings
FOR DELETE USING (auth.uid() = user_id);
+-- Policies for Buddies
+ALTER TABLE buddies ENABLE ROW LEVEL SECURITY;
+CREATE POLICY "Users can manage their own buddies" ON buddies
+ FOR ALL USING (auth.uid() = user_id);
+CREATE POLICY "Users can see buddies linked to their profile" ON buddies
+ FOR SELECT USING (buddy_profile_id = auth.uid());
+
+-- Policies for Tasting Sessions
+ALTER TABLE tasting_sessions ENABLE ROW LEVEL SECURITY;
+CREATE POLICY "Users can manage their own sessions" ON tasting_sessions
+ FOR ALL USING (auth.uid() = user_id);
+CREATE POLICY "Users can see sessions they participate in" ON tasting_sessions
+ FOR SELECT USING (
+ id IN (
+ SELECT session_id FROM session_participants
+ WHERE buddy_id IN (SELECT id FROM buddies WHERE buddy_profile_id = auth.uid())
+ )
+ );
+
+-- Policies for Session Participants
+ALTER TABLE session_participants ENABLE ROW LEVEL SECURITY;
+CREATE POLICY "Users can manage participants of their sessions" ON session_participants
+ FOR ALL USING (
+ session_id IN (SELECT id FROM tasting_sessions WHERE user_id = auth.uid())
+ );
+CREATE POLICY "Participants can see session membership" ON session_participants
+ FOR SELECT USING (
+ buddy_id IN (SELECT id FROM buddies WHERE buddy_profile_id = auth.uid())
+ );
+
+-- Policies for Tasting Tags
+ALTER TABLE tasting_tags ENABLE ROW LEVEL SECURITY;
+CREATE POLICY "Users can manage tags on their tastings" ON tasting_tags
+ FOR ALL USING (
+ tasting_id IN (SELECT id FROM tastings WHERE user_id = auth.uid())
+ );
+CREATE POLICY "Tagged users can see the tags" ON tasting_tags
+ FOR SELECT USING (
+ buddy_id IN (SELECT id FROM buddies WHERE buddy_profile_id = auth.uid())
+ );
+
-- STORAGE SETUP
-- Create 'bottles' bucket if it doesn't exist
INSERT INTO storage.buckets (id, name, public)