align delete status codes + document mutation contract
Created by: jedmund
Summary
Architecture audit A-14 and A-15 — tighten the mutation response contract and remove the 204-vs-200 split clients had to branch on.
A-14 · Response contract doc
Added a header comment to `src/lib/server/api-utils.ts` codifying what's already true in the codebase:
- API routes: `jsonResponse(data)` for success, `errorResponse(message, status, details?)` for errors (always `{ error: { code, message, details? } }`)
- Form actions: `throw redirect(303, path)` for success (no body), `fail(status, { message })` for errors
Documentation only — existing code already follows this.
A-15 · DELETE status code alignment
Eight detail-route DELETEs returned `204 No Content` on success while their error paths returned `500 { error: {...} }`. Clients had to branch on the success code. Flipped all eight to `200 { success: true }` so every DELETE response parses as JSON.
- `/api/posts/[id]`, `/api/projects/[id]`, `/api/tags/[id]`, `/api/photos/[id]`, `/api/albums/[id]`, `/api/media/[id]`, `/api/admin/garden/[id]`, `/api/albums/[id]/photos`
Unchanged: `/api/heart/[...path]` (CORS proxy — 204 is correct there), `media/bulk-upload` and `media/[id]/metadata` (not DELETE).
Drive-by A-1 follow-up
`src/lib/server/admin/authenticated-fetch.ts` had `detail = String(json.error)` which produced `"[object Object]"` for the structured error shape introduced in #76. Now properly extracts `.error.message`, falling back to string-`error` for backward compatibility with any external shape.
Test plan
-
`pnpm check` — baseline 116 errors / 9 warnings, no new ones -
Admin UI: delete a post → toast/success renders normally (no regression from 204 change) -
`curl -X DELETE -b session=... /api/posts/<id>` → body is `{"success":true}`, status 200 -
Trigger an admin fetch error (e.g. delete nonexistent id) → error message surfaces in the admin UI (not "[object Object]")