From c06877069f03e975d5eff3bb10690a67ab668790 Mon Sep 17 00:00:00 2001 From: Admin Date: Tue, 10 Mar 2026 20:20:24 +0500 Subject: [PATCH] fix: add missing DELETE handler and fix comment delete/vote URLs (web + iOS) The /api/comments/[id] delete route was never created; the deleteComment helper in pocketbase.ts existed but was unreachable. Added DELETE /api/comment/[id] route handler alongside the existing vote route. Updated CommentsSection.svelte and iOS APIClient to use /api/comment/{id} for both delete and (already fixed) vote, keeping all comment-mutation endpoints under the singular /api/comment/ prefix to avoid SvelteKit route conflicts with /api/comments/[slug]. --- .../LibNovel/Networking/APIClient.swift | 2 +- ui/src/lib/components/CommentsSection.svelte | 2 +- ui/src/routes/api/comment/[id]/+server.ts | 26 +++++++++++++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 ui/src/routes/api/comment/[id]/+server.ts diff --git a/ios/LibNovel/LibNovel/Networking/APIClient.swift b/ios/LibNovel/LibNovel/Networking/APIClient.swift index 0e6a410..072cbca 100644 --- a/ios/LibNovel/LibNovel/Networking/APIClient.swift +++ b/ios/LibNovel/LibNovel/Networking/APIClient.swift @@ -348,7 +348,7 @@ actor APIClient { /// Delete a comment (and its replies) by ID. Only the owner can delete. func deleteComment(commentId: String) async throws { struct Empty: Decodable {} - let _: Empty = try await fetch("/api/comments/\(commentId)", method: "DELETE") + let _: Empty = try await fetch("/api/comment/\(commentId)", method: "DELETE") } } diff --git a/ui/src/lib/components/CommentsSection.svelte b/ui/src/lib/components/CommentsSection.svelte index f165fae..89e73c7 100644 --- a/ui/src/lib/components/CommentsSection.svelte +++ b/ui/src/lib/components/CommentsSection.svelte @@ -156,7 +156,7 @@ if (deletingIds.has(commentId)) return; deletingIds = new Set([...deletingIds, commentId]); try { - const res = await fetch(`/api/comments/${commentId}`, { method: 'DELETE' }); + const res = await fetch(`/api/comment/${commentId}`, { method: 'DELETE' }); if (!res.ok) return; if (parentId) { // Remove reply from parent diff --git a/ui/src/routes/api/comment/[id]/+server.ts b/ui/src/routes/api/comment/[id]/+server.ts new file mode 100644 index 0000000..8bb998b --- /dev/null +++ b/ui/src/routes/api/comment/[id]/+server.ts @@ -0,0 +1,26 @@ +import { error } from '@sveltejs/kit'; +import type { RequestHandler } from './$types'; +import { deleteComment } from '$lib/server/pocketbase'; +import { log } from '$lib/server/logger'; + +/** + * DELETE /api/comment/[id] + * Deletes a comment and its replies. Only the comment owner may delete. + * Requires authentication. + */ +export const DELETE: RequestHandler = async ({ params, locals }) => { + if (!locals.user) error(401, 'Login required'); + + const { id } = params; + + try { + await deleteComment(id, locals.user.id); + return new Response(null, { status: 204 }); + } catch (e) { + const msg = String(e); + if (msg.includes('Not authorized')) error(403, 'Not authorized to delete this comment'); + if (msg.includes('not found')) error(404, 'Comment not found'); + log.error('api/comment/[id]', 'deleteComment failed', { id, err: msg }); + error(500, 'Failed to delete comment'); + } +};