feat: async chapter-names AI generation with review & apply
All checks were successful
Release / Test backend (push) Successful in 40s
Release / Check ui (push) Successful in 1m38s
Release / Docker / caddy (push) Successful in 41s
Release / Docker / backend (push) Successful in 3m15s
Release / Docker / runner (push) Successful in 4m34s
Release / Upload source maps (push) Successful in 1m33s
Release / Docker / ui (push) Successful in 3m39s
Release / Gitea Release (push) Successful in 40s
All checks were successful
Release / Test backend (push) Successful in 40s
Release / Check ui (push) Successful in 1m38s
Release / Docker / caddy (push) Successful in 41s
Release / Docker / backend (push) Successful in 3m15s
Release / Docker / runner (push) Successful in 4m34s
Release / Upload source maps (push) Successful in 1m33s
Release / Docker / ui (push) Successful in 3m39s
Release / Gitea Release (push) Successful in 40s
- Add POST /api/admin/text-gen/chapter-names/async backend endpoint: fire-and-forget, returns job_id immediately (HTTP 202), runs batch generation in background goroutine, persists proposed titles in ai_job payload when done - Register new route in server.go alongside existing SSE endpoint (backward compat) - Add SvelteKit proxy at /api/admin/text-gen/chapter-names/async - Add SvelteKit proxy for GET /api/admin/ai-jobs/[id] (job detail with payload) - Add Review button on ai-jobs page for done chapter-names jobs; inline panel shows editable title table (old to new) with Apply All button that POSTs to chapter-names/apply
This commit is contained in:
31
ui/src/routes/api/admin/ai-jobs/[id]/+server.ts
Normal file
31
ui/src/routes/api/admin/ai-jobs/[id]/+server.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* GET /api/admin/ai-jobs/[id]
|
||||
*
|
||||
* Admin-only proxy to the Go backend's AI job detail endpoint.
|
||||
* Returns the full job record including the payload field (which contains
|
||||
* results for completed chapter-names jobs).
|
||||
*/
|
||||
|
||||
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 GET: RequestHandler = async ({ params, locals }) => {
|
||||
if (!locals.user || locals.user.role !== 'admin') {
|
||||
throw error(403, 'Forbidden');
|
||||
}
|
||||
|
||||
const { id } = params;
|
||||
|
||||
let res: Response;
|
||||
try {
|
||||
res = await backendFetch(`/api/admin/ai-jobs/${id}`, { method: 'GET' });
|
||||
} catch (e) {
|
||||
log.error('admin/ai-jobs/get', 'backend proxy error', { id, err: String(e) });
|
||||
throw error(502, 'Could not reach backend');
|
||||
}
|
||||
|
||||
const data = await res.json().catch(() => ({}));
|
||||
return json(data, { status: res.status });
|
||||
};
|
||||
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* POST /api/admin/text-gen/chapter-names/async
|
||||
*
|
||||
* Fire-and-forget variant: forwards to the Go backend's async endpoint and
|
||||
* returns {job_id} immediately (HTTP 202). The backend runs generation in the
|
||||
* background; the client polls GET /api/admin/ai-jobs/{id} for progress and
|
||||
* then reviews/applies via POST /api/admin/text-gen/chapter-names/apply.
|
||||
*/
|
||||
|
||||
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/text-gen/chapter-names/async', {
|
||||
method: 'POST',
|
||||
headers: { 'content-type': 'application/json' },
|
||||
body
|
||||
});
|
||||
} catch (e) {
|
||||
log.error('admin/text-gen/chapter-names/async', '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 });
|
||||
};
|
||||
Reference in New Issue
Block a user