import { redirect } from '@sveltejs/kit'; import { createApiClient } from '$lib/shared/api.server'; import { getErrorMessage } from '$lib/shared/errors'; import type { components } from '$lib/generated/api'; const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i; async function resolvePersonName( id: string, api: ReturnType ): Promise { if (!UUID_RE.test(id)) return ''; try { const result = await api.GET('/api/persons/{id}', { params: { path: { id } } }); if (!result.response.ok) return ''; return result.data?.displayName ?? ''; } catch (e) { console.error('[resolvePersonName] failed for id', id, e); return ''; } } type DocumentSearchItem = components['schemas']['DocumentSearchItem']; const VALID_SORTS = ['DATE', 'TITLE', 'SENDER', 'RECEIVER', 'UPLOAD_DATE', 'RELEVANCE'] as const; type ValidSort = (typeof VALID_SORTS)[number]; const VALID_DIRS = ['asc', 'desc'] as const; type ValidDir = (typeof VALID_DIRS)[number]; const PAGE_SIZE = 50; export async function load({ url, fetch }) { const q = url.searchParams.get('q') || ''; const from = url.searchParams.get('from') || ''; const to = url.searchParams.get('to') || ''; const senderId = url.searchParams.get('senderId') || ''; const receiverId = url.searchParams.get('receiverId') || ''; const tags = url.searchParams.getAll('tag'); const rawSort = url.searchParams.get('sort') ?? 'DATE'; const sort: ValidSort = (VALID_SORTS as readonly string[]).includes(rawSort) ? (rawSort as ValidSort) : 'DATE'; const rawDir = url.searchParams.get('dir') ?? 'desc'; const dir: ValidDir = (VALID_DIRS as readonly string[]).includes(rawDir) ? (rawDir as ValidDir) : 'desc'; const tagQ = url.searchParams.get('tagQ') || ''; const tagOp = url.searchParams.get('tagOp') === 'OR' ? 'OR' : 'AND'; const page = Math.max(0, Number(url.searchParams.get('page') ?? '0') || 0); const api = createApiClient(fetch); let result; let initialSenderName = ''; let initialReceiverName = ''; try { [result, [initialSenderName, initialReceiverName]] = await Promise.all([ api.GET('/api/documents/search', { params: { query: { q: q || undefined, from: from || undefined, to: to || undefined, senderId: senderId || undefined, receiverId: receiverId || undefined, tag: tags.length ? tags : undefined, tagQ: tagQ && !tags.length ? tagQ : undefined, tagOp: tagOp === 'OR' ? 'OR' : undefined, sort, dir: dir || undefined, page, size: PAGE_SIZE } } }), Promise.all([resolvePersonName(senderId, api), resolvePersonName(receiverId, api)]) ]); } catch { return { items: [] as DocumentSearchItem[], totalElements: 0, pageNumber: 0, pageSize: PAGE_SIZE, totalPages: 0, q, from, to, senderId, receiverId, initialSenderName: '', initialReceiverName: '', tags, sort, dir, tagQ, tagOp, error: 'Daten konnten nicht geladen werden.' as string | null }; } if (result.response.status === 401) { throw redirect(302, '/login'); } const errorMessage: string | null = !result.response.ok ? (getErrorMessage((result.error as unknown as { code?: string })?.code) ?? 'Daten konnten nicht geladen werden.') : null; return { items: (result.data?.items ?? []) as DocumentSearchItem[], totalElements: result.data?.totalElements ?? 0, pageNumber: result.data?.pageNumber ?? page, pageSize: result.data?.pageSize ?? PAGE_SIZE, totalPages: result.data?.totalPages ?? 0, q, from, to, senderId, receiverId, initialSenderName, initialReceiverName, tags, sort, dir, tagQ, tagOp, error: errorMessage }; }