since3-portal/modules/shared/queries/documents.ts
2026-09-29 16:37:48 +02:00

71 lines
2.5 KiB
TypeScript

import "server-only"
import { createClient } from "@/lib/supabase/server"
import { DOCUMENTS_BUCKET, previewKind, type DocumentItem, type Folder } from "@/modules/shared/schemas/documents"
const THUMBNAIL_TTL_SECONDS = 60 * 60
export async function getFolders(clientId: string): Promise<Folder[]> {
const supabase = await createClient()
const { data, error } = await supabase
.from("folders")
.select("id, name, documents(count)")
.eq("client_id", clientId)
.is("parent_id", null)
.order("name")
if (error) throw new Error("Ordner konnten nicht geladen werden.")
return data.map((row) => ({
id: row.id,
name: row.name,
documentCount: (row.documents as unknown as { count: number }[])[0]?.count ?? 0,
}))
}
export async function getFolder(clientId: string, folderId: string): Promise<Folder | null> {
const supabase = await createClient()
const { data, error } = await supabase
.from("folders")
.select("id, name")
.eq("client_id", clientId)
.eq("id", folderId)
.maybeSingle()
if (error) throw new Error("Ordner konnte nicht geladen werden.")
return data ? { id: data.id, name: data.name, documentCount: 0 } : null
}
export async function getDocuments(clientId: string, folderId: string): Promise<DocumentItem[]> {
const supabase = await createClient()
const { data, error } = await supabase
.from("documents")
.select("id, name, mime_type, size_bytes, created_at, storage_path")
.eq("client_id", clientId)
.eq("folder_id", folderId)
.order("created_at", { ascending: false })
if (error) throw new Error("Dokumente konnten nicht geladen werden.")
const imagePaths = data
.filter((row) => previewKind(row.mime_type) === "image")
.map((row) => row.storage_path as string)
const thumbnails = new Map<string, string>()
if (imagePaths.length > 0) {
const { data: signed } = await supabase.storage
.from(DOCUMENTS_BUCKET)
.createSignedUrls(imagePaths, THUMBNAIL_TTL_SECONDS)
for (const entry of signed ?? []) {
if (entry.path && entry.signedUrl) thumbnails.set(entry.path, entry.signedUrl)
}
}
return data.map((row) => ({
id: row.id,
name: row.name,
mimeType: row.mime_type,
sizeBytes: row.size_bytes === null ? null : Number(row.size_bytes),
createdAt: row.created_at,
thumbnailUrl: thumbnails.get(row.storage_path) ?? null,
}))
}