Some checks failed
Deploy / Deploy Production (push) Has been skipped
Deploy / Cleanup Preview (push) Has been skipped
Deploy / Deploy Preview (push) Failing after 0s
CI / Scraper / Test (pull_request) Successful in 11s
CI / UI / Build (pull_request) Failing after 14s
CI / Scraper / Lint (pull_request) Successful in 23s
CI / Scraper / Build (pull_request) Successful in 24s
iOS CI / Build (push) Has been cancelled
iOS CI / Test (push) Has been cancelled
iOS CI / Build (pull_request) Failing after 2s
iOS CI / Test (pull_request) Has been skipped
- iOS SwiftUI app (ios/LibNovel/) targeting iOS 17+, generated via xcodegen - Full feature set: auth, home, library, book detail, chapter reader, browse, audio player, profile - Kingfisher for image loading, swift-markdown-ui for chapter rendering - Base URL: https://v2.libnovel.kalekber.cc - SvelteKit JSON API routes (ui/src/routes/api/) for iOS consumption: auth/login, auth/register, auth/me, auth/logout, auth/change-password, home, library, book/[slug], chapter/[slug]/[n], search, ranking, progress/[slug], presign/audio (updated) - Gitea Actions CI: .gitea/workflows/ios.yaml (build + test on macos-latest) - justfile: ios-gen, ios-build, ios-test recipes
35 lines
1.0 KiB
TypeScript
35 lines
1.0 KiB
TypeScript
import { json, error } from '@sveltejs/kit';
|
|
import type { RequestHandler } from './$types';
|
|
import { setProgress } from '$lib/server/pocketbase';
|
|
import { log } from '$lib/server/logger';
|
|
|
|
/**
|
|
* POST /api/progress/[slug]
|
|
* Body: { chapter: number }
|
|
* Records the user's reading position for a specific book.
|
|
*
|
|
* This is a slug-in-path variant of POST /api/progress (which takes slug in body).
|
|
* Used by the iOS app where slug is part of the URL path.
|
|
*/
|
|
export const POST: RequestHandler = async ({ params, request, locals }) => {
|
|
const { slug } = params;
|
|
const body = await request.json().catch(() => null);
|
|
|
|
if (!body || typeof body.chapter !== 'number') {
|
|
error(400, 'Invalid body — expected { chapter: number }');
|
|
}
|
|
|
|
try {
|
|
await setProgress(locals.sessionId, slug, body.chapter, locals.user?.id);
|
|
} catch (e) {
|
|
log.error('api/progress/[slug]', 'setProgress failed', {
|
|
slug,
|
|
chapter: body.chapter,
|
|
err: String(e)
|
|
});
|
|
error(500, 'Failed to save progress');
|
|
}
|
|
|
|
return json({ ok: true });
|
|
};
|