xtablo-source/api/src/notes.ts

83 lines
2.2 KiB
TypeScript
Raw Normal View History

2025-10-26 14:38:48 +00:00
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 });
});