feat(admin): add OCR admin routes — overview, global history, sender detail
Some checks failed
CI / Backend Unit Tests (push) Failing after 2m45s
CI / Unit & Component Tests (pull_request) Failing after 2m32s
CI / OCR Service Tests (pull_request) Successful in 27s
CI / Backend Unit Tests (pull_request) Failing after 2m44s
CI / Unit & Component Tests (push) Failing after 2m35s
CI / OCR Service Tests (push) Successful in 30s

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-04-18 01:05:08 +02:00
parent 0d8ac46639
commit 8acb830649
9 changed files with 241 additions and 0 deletions

View File

@@ -0,0 +1,16 @@
import { error } from '@sveltejs/kit';
import type { PageServerLoad } from './$types';
import { createApiClient } from '$lib/api.server';
import { getErrorMessage } from '$lib/errors';
export const load: PageServerLoad = async ({ fetch }) => {
const api = createApiClient(fetch);
const result = await api.GET('/api/ocr/training-info/global');
if (!result.response.ok) {
const code = (result.error as unknown as { code?: string })?.code;
throw error(result.response.status, getErrorMessage(code));
}
return { history: result.data! };
};

View File

@@ -0,0 +1,30 @@
<script lang="ts">
import type { PageData } from './$types';
import TrainingHistory from '$lib/components/TrainingHistory.svelte';
let { data }: { data: PageData } = $props();
</script>
<div class="flex flex-col gap-6 p-6">
<div class="flex items-center gap-4">
<a
href="/admin/ocr"
class="group inline-flex items-center text-xs font-bold tracking-widest text-gray-500 uppercase transition-colors hover:text-brand-navy"
>
<svg
class="mr-2 h-4 w-4 transform transition-transform group-hover:-translate-x-1"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
stroke-width="2"
><path stroke-linecap="round" stroke-linejoin="round" d="M15 19l-7-7 7-7" /></svg
>
OCR
</a>
<h1 class="font-sans text-lg font-bold tracking-widest text-brand-navy uppercase">
Global History
</h1>
</div>
<TrainingHistory runs={data.history.runs ?? []} personNames={data.history.personNames ?? {}} />
</div>

View File

@@ -0,0 +1,27 @@
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { load } from './+page.server';
const mockApi = { GET: vi.fn() };
vi.mock('$lib/api.server', () => ({ createApiClient: () => mockApi }));
beforeEach(() => vi.clearAllMocks());
describe('admin/ocr/global — load', () => {
it('returns history from API', async () => {
mockApi.GET.mockResolvedValue({
response: { ok: true },
data: { runs: [{ id: 'run1' }], personNames: {} }
});
const result = (await load({ fetch } as never))!;
expect(result.history.runs).toHaveLength(1);
});
it('throws error when API call fails', async () => {
mockApi.GET.mockResolvedValue({ response: { ok: false, status: 500 }, error: {} });
await expect(load({ fetch } as never)).rejects.toMatchObject({ status: 500 });
});
});