First commit

This commit is contained in:
AlacrisDevs
2026-02-04 23:01:44 +02:00
commit cfec43f7ef
78 changed files with 9509 additions and 0 deletions

132
src/lib/api/documents.ts Normal file
View File

@@ -0,0 +1,132 @@
import type { SupabaseClient } from '@supabase/supabase-js';
import type { Database, Document } from '$lib/supabase/types';
export interface DocumentWithChildren extends Document {
children?: DocumentWithChildren[];
}
export async function fetchDocuments(
supabase: SupabaseClient<Database>,
orgId: string
): Promise<Document[]> {
const { data, error } = await supabase
.from('documents')
.select('*')
.eq('org_id', orgId)
.order('type', { ascending: false }) // folders first
.order('name');
if (error) throw error;
return data ?? [];
}
export async function createDocument(
supabase: SupabaseClient<Database>,
orgId: string,
name: string,
type: 'folder' | 'document',
parentId: string | null = null,
userId: string
): Promise<Document> {
const { data, error } = await supabase
.from('documents')
.insert({
org_id: orgId,
name,
type,
parent_id: parentId,
created_by: userId,
content: type === 'document' ? { type: 'doc', content: [] } : null
})
.select()
.single();
if (error) throw error;
return data;
}
export async function updateDocument(
supabase: SupabaseClient<Database>,
id: string,
updates: Partial<Pick<Document, 'name' | 'content' | 'parent_id'>>
): Promise<Document> {
const { data, error } = await supabase
.from('documents')
.update({ ...updates, updated_at: new Date().toISOString() })
.eq('id', id)
.select()
.single();
if (error) throw error;
return data;
}
export async function deleteDocument(
supabase: SupabaseClient<Database>,
id: string
): Promise<void> {
const { error } = await supabase.from('documents').delete().eq('id', id);
if (error) throw error;
}
export async function moveDocument(
supabase: SupabaseClient<Database>,
id: string,
newParentId: string | null
): Promise<void> {
const { error } = await supabase
.from('documents')
.update({ parent_id: newParentId, updated_at: new Date().toISOString() })
.eq('id', id);
if (error) throw error;
}
export function buildDocumentTree(documents: Document[]): DocumentWithChildren[] {
const map = new Map<string, DocumentWithChildren>();
const roots: DocumentWithChildren[] = [];
// First pass: create map
documents.forEach((doc) => {
map.set(doc.id, { ...doc, children: [] });
});
// Second pass: build tree
documents.forEach((doc) => {
const node = map.get(doc.id)!;
if (doc.parent_id && map.has(doc.parent_id)) {
map.get(doc.parent_id)!.children!.push(node);
} else {
roots.push(node);
}
});
return roots;
}
export function subscribeToDocuments(
supabase: SupabaseClient<Database>,
orgId: string,
onInsert: (doc: Document) => void,
onUpdate: (doc: Document) => void,
onDelete: (id: string) => void
) {
return supabase
.channel(`documents:${orgId}`)
.on(
'postgres_changes',
{ event: 'INSERT', schema: 'public', table: 'documents', filter: `org_id=eq.${orgId}` },
(payload) => onInsert(payload.new as Document)
)
.on(
'postgres_changes',
{ event: 'UPDATE', schema: 'public', table: 'documents', filter: `org_id=eq.${orgId}` },
(payload) => onUpdate(payload.new as Document)
)
.on(
'postgres_changes',
{ event: 'DELETE', schema: 'public', table: 'documents', filter: `org_id=eq.${orgId}` },
(payload) => onDelete((payload.old as { id: string }).id)
)
.subscribe();
}