fix: wire import chapter ingestion, live task polling, a11y labels, notification user targeting
Some checks failed
Release / Test backend (push) Successful in 47s
Release / Check ui (push) Failing after 36s
Release / Docker (push) Has been skipped
Release / Gitea Release (push) Has been skipped

- NewBookImporter now takes *Store instead of raw *minio.Client (same package access)
- Runner Dependencies gains ChapterIngester interface; storeImportedChapters no-op removed
- store.IngestChapters is now actually called after PDF/EPUB extraction
- BookImport and ChapterIngester wired in runner main.go
- CreateImportTask interface gains initiatorUserID param; threaded through store/asynq/handler
- domain.ImportTask gains InitiatorUserID field; parseImportTask populates it
- Runner notifies initiator (falls back to 'admin' when empty)
- UI: import task list polls every 3s while any task is pending/running
- UI: label[for] + input[id] fix for a11y warnings in admin import page
This commit is contained in:
root
2026-04-09 11:00:01 +05:00
parent ab92bf84bb
commit fcd4b3ad7f
13 changed files with 170 additions and 74 deletions

View File

@@ -139,6 +139,16 @@
onMount(() => {
loadTasks();
});
// Poll every 3s while any task is running
$effect(() => {
const hasRunning = tasks.some((t) => t.status === 'running' || t.status === 'pending');
if (!hasRunning) return;
const timer = setInterval(() => {
loadTasks();
}, 3000);
return () => clearInterval(timer);
});
</script>
<div class="max-w-4xl">
@@ -188,8 +198,9 @@
<!-- Upload Form -->
<form onsubmit={(e) => { e.preventDefault(); analyzeFile(); }} class="mb-8 p-4 bg-(--color-surface-2) rounded-lg">
<div class="mb-4">
<label class="block text-sm font-medium mb-2">Select File (PDF or EPUB)</label>
<label for="import-file" class="block text-sm font-medium mb-2">Select File (PDF or EPUB)</label>
<input
id="import-file"
type="file"
accept=".pdf,.epub"
onchange={handleFileSelect}
@@ -197,8 +208,9 @@
/>
</div>
<div class="mb-4">
<label class="block text-sm font-medium mb-2">Book Title</label>
<label for="import-title" class="block text-sm font-medium mb-2">Book Title</label>
<input
id="import-title"
type="text"
bind:value={title}
placeholder="Enter book title"

View File

@@ -0,0 +1,11 @@
import { json, error } from '@sveltejs/kit';
import type { RequestHandler } from './$types';
import { backendFetch } from '$lib/server/scraper';
export const GET: RequestHandler = async ({ url }) => {
const userId = url.searchParams.get('user_id');
if (!userId) throw error(400, 'user_id required');
const res = await backendFetch('/api/notifications?user_id=' + userId);
const data = await res.json().catch(() => ({ notifications: [] }));
return json(data);
};

View File

@@ -0,0 +1,19 @@
import { json, error } from '@sveltejs/kit';
import type { RequestHandler } from './$types';
import { backendFetch } from '$lib/server/scraper';
export const GET: RequestHandler = async ({ url }) => {
const userId = url.searchParams.get('user_id');
if (!userId) throw error(400, 'user_id required');
const res = await backendFetch('/api/notifications?user_id=' + userId);
const data = await res.json().catch(() => ({ notifications: [] }));
return json(data);
};
export const PATCH: RequestHandler = async ({ params }) => {
const id = params.id;
if (!id) throw error(400, 'id required');
const res = await backendFetch('/api/notifications/' + id, { method: 'PATCH' });
const data = await res.json().catch(() => ({}));
return json(data);
};