- Admin layout: SVG icons, active highlight, divider between nav sections - Scrape page: status filter pills with counts, text + status combined search - Audio page: status filter pills, cancel jobs, retry failed jobs, mobile cards for cache tab - Translation page: status filter pills (incl. cancelled), cancel + retry jobs, mobile cancel/retry cards, i18n for all labels - AI Jobs page: fix concurrent cancel (Set instead of single slot), per-job cancel errors inline, full mobile card layout, i18n title/heading - Text-gen page: tagline editable input + copy, warnings copy, i18n title/heading - Book page: chapter cover Save button, audio monitor link, currentShelf pre-populated from server - pocketbase.ts: add getBookShelf(), shelf field on UserLibraryEntry - New API route: POST /api/admin/translation/bulk (proxy for translation retry) - i18n: 15 new admin_translation_*, admin_ai_jobs_*, admin_text_gen_* keys across all 5 locales
36 lines
1.1 KiB
TypeScript
36 lines
1.1 KiB
TypeScript
/**
|
|
* POST /api/admin/image-gen/save-chapter-image
|
|
*
|
|
* Admin-only proxy: persists a pre-generated base64 image as a chapter
|
|
* illustration in MinIO without re-calling Cloudflare AI.
|
|
*
|
|
* Body: { slug: string, chapter: number, image_b64: string }
|
|
*/
|
|
|
|
import { json, error } from '@sveltejs/kit';
|
|
import type { RequestHandler } from './$types';
|
|
import { log } from '$lib/server/logger';
|
|
import { backendFetch } from '$lib/server/scraper';
|
|
|
|
export const POST: RequestHandler = async ({ request, locals }) => {
|
|
if (!locals.user || locals.user.role !== 'admin') {
|
|
throw error(403, 'Forbidden');
|
|
}
|
|
|
|
const body = await request.text();
|
|
let res: Response;
|
|
try {
|
|
res = await backendFetch('/api/admin/image-gen/save-chapter-image', {
|
|
method: 'POST',
|
|
headers: { 'content-type': 'application/json' },
|
|
body
|
|
});
|
|
} catch (e) {
|
|
log.error('admin/image-gen/save-chapter-image', 'backend proxy error', { err: String(e) });
|
|
throw error(502, 'Could not reach backend');
|
|
}
|
|
|
|
const data = await res.json().catch(() => ({}));
|
|
return json(data, { status: res.status });
|
|
};
|