PATCH /mangas/:id, PUT /mangas/:id/cover and DELETE /mangas/:id/cover
took the current user but never compared it against the row's
uploaded_by. Any signed-in user could overwrite or clear any manga's
metadata and cover. Add require_can_edit gate: non-NULL uploaded_by
must match the caller; legacy NULL rows stay open until an admin role
lands (per migration 0011 historical-data note).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds PUT /mangas/:id/cover (multipart) and DELETE /mangas/:id/cover so
covers can be replaced or cleared after creation, and wires a dedicated
/manga/[id]/edit SvelteKit route that combines the existing PATCH with
the new cover endpoints. Cover PUT cleans up the old blob when the
extension changes, swallowing StorageError::NotFound so a manually-gone
file doesn't surface as a 404 to the client. Edit link on the manga
detail page is gated on session.user, matching the auth posture of the
underlying handlers.
Also pins the local-dev port story via loadEnv() in vite.config.ts so
VITE_PORT / BACKEND_URL from a (gitignored) .env keep the dev URL
stable across runs.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>