Delete Projects Batch

0e4980d4 — batch delete: accepts multiple project ids in one call.

Repeated query param: DELETE /projects?project_id=id1&project_id=id2. Query params (not a DELETE body) are used deliberately — httpx/many HTTP clients and proxies don't reliably support a request body on DELETE, while repeated query params are universally supported and match FastAPI's native list[str] = Query(...) binding.

Complements the single-project DELETE /projects/{project_id} above by driving db_module.delete_project with a list, which runs each child-table DELETE once with a single WHERE project_id IN (...) across the whole batch instead of looping the full per-table statement set once per project (see the db function's docstring for the batching rationale).

All-or-nothing like the single-project path: every id is validated to exist (404, naming the unknown ids) and the in-progress-task guard is checked across the whole batch (409) before anything is deleted — a guard violation or an unknown id aborts the entire batch, not just the offending project.

3f4ba195 — explicit PERM_SETTINGS guard (authorization-bypass fix). _required_perm_for_request (meridian/_deps.py) maps whole-project deletion to PERM_SETTINGS only via its path.startswith("/projects/") branch, which the bare /projects path this batch route answers on never satisfies — it silently fell through to the PERM_WRITE default, so a cross-workspace 'member' (PERM_WRITE but not PERM_SETTINGS) could delete an owner's project through this batch form even though the identical action via the singular DELETE /projects/{project_id} route is correctly owner/admin-gated by that same middleware mapping. Rather than change the generic path-prefix mapping in _deps.py (out of scope for this fix), enforce the same requirement explicitly here — independent of the middleware's coarser default — mirroring the inline _require_workspace_perm guard routes/export.py uses for POST /account/delete. A no-op for self-hosted / same-workspace / non-member callers, exactly like the middleware itself (ctx is None).

delete/projects

Request

  • Base URL: https://usemeridian.us (the document declares no server; this is the origin it was published from)
  • URL: https://usemeridian.us/projects
  • Auth: none declared

Query parameters

project_idstring[] required

Response

Successful Response

object required

Changes

No recorded changes to this operation across all 1 revision of this API.