import { supabaseAdmin } from "../config/supabase"; import { HttpError } from "../utils/httpError"; export async function listConversations(userId: string) { const { data, error } = await supabaseAdmin .from("conversations") .select(` id, match_id, created_at, updated_at, match:matches(id, status, compatibility_score, profile_a_id, profile_b_id) `) .order("updated_at", { ascending: false }); if (error) { throw error; } const { data: profile, error: profileError } = await supabaseAdmin .from("profiles") .select("id") .eq("user_id", userId) .maybeSingle(); if (profileError) { throw profileError; } return (data ?? []).filter((conversation) => { const match = conversation.match as unknown as { profile_a_id?: string; profile_b_id?: string }; return match.profile_a_id === profile?.id || match.profile_b_id === profile?.id; }); } export async function listMessages(userId: string, conversationId: string) { await assertConversationParticipant(userId, conversationId); const { data, error } = await supabaseAdmin .from("messages") .select("*") .eq("conversation_id", conversationId) .order("created_at", { ascending: true }); if (error) { throw error; } return data ?? []; } export async function sendMessage(userId: string, conversationId: string, body: string) { await assertConversationParticipant(userId, conversationId); const { data, error } = await supabaseAdmin .from("messages") .insert({ conversation_id: conversationId, sender_user_id: userId, body }) .select("*") .single(); if (error) { throw error; } await supabaseAdmin.from("conversations").update({ updated_at: new Date().toISOString() }).eq("id", conversationId); return data; } async function assertConversationParticipant(userId: string, conversationId: string) { const { data: profile, error: profileError } = await supabaseAdmin .from("profiles") .select("id") .eq("user_id", userId) .maybeSingle(); if (profileError) { throw profileError; } if (!profile) { throw new HttpError(404, "profile_not_found", "Profile not found"); } const { data, error } = await supabaseAdmin .from("conversations") .select("id, match:matches(profile_a_id, profile_b_id, status)") .eq("id", conversationId) .maybeSingle(); if (error) { throw error; } const match = data?.match as unknown as { profile_a_id?: string; profile_b_id?: string; status?: string } | undefined; const isParticipant = match?.profile_a_id === profile.id || match?.profile_b_id === profile.id; if (!data || !match || !isParticipant || !["accepted", "active"].includes(match.status ?? "")) { throw new HttpError(403, "conversation_forbidden", "Conversation is not available for this user"); } }