import type { SupabaseClient, User } from "@supabase/supabase-js"; import { Hono } from "hono"; import { checkTabloMember } from "./helpers.js"; import type { Database } from "./database.types.js"; import { authMiddleware } from "./middleware.js"; export const notesRouter = new Hono<{ Variables: { user: User; supabase: SupabaseClient; }; }>(); type Note = Database["public"]["Tables"]["notes"]["Row"]; notesRouter.use(authMiddleware); /** * Fetch notes shared with a specific tablo */ notesRouter.get("/:tabloId", checkTabloMember, async (c) => { const { tabloId } = c.req.param(); if (!tabloId) { return c.json({ error: "Tablo ID is required" }, 400); } const supabase = c.get("supabase"); // Find the tablo owner const { data: tabloData, error: tabloError } = await supabase .from("tablos") .select("owner_id") .eq("id", tabloId) .single(); if (tabloError) { console.error("Error fetching tablo:", tabloError); return c.json({ error: "Failed to fetch tablo" }, 500); } if (!tabloData) { return c.json({ error: "Tablo not found" }, 404); } const tabloOwnerId = tabloData.owner_id; // Find notes shared with this specific tablo or all tablos const { data, error } = await supabase .from("note_access") .select(` note_id, notes!inner ( id, title, content, user_id, created_at, updated_at, deleted_at ) `) .eq("is_active", true) .eq("user_id", tabloOwnerId) .or(`tablo_id.eq.${tabloId},tablo_id.is.null`) .is("notes.deleted_at", null); if (error) { return c.json({ error: "An error occurred" }, 500); } // Extract notes from the join result and remove duplicates type JoinedResult = { note_id: string; notes: Note[] }; const extractedNotes = (data as JoinedResult[]) .map((item) => (Array.isArray(item.notes) ? item.notes[0] : item.notes)) .filter((note) => note !== null && note !== undefined); // Remove duplicates by note id (in case a note is shared both with all tablos and this specific tablo) const uniqueNotes = Array.from(new Map(extractedNotes.map((note) => [note.id, note])).values()); return c.json({ notes: uniqueNotes }); });