cm-api: quota — enforce max_active_runs on run enqueue

Adds a Quota.max_active_runs ceiling (queued + running topology runs at
once, per workspace) to stop a single workspace flooding the shared queue.
Free tier: 10, Pro: 25, Team: 100. Enforced at every /run enqueue site:
run_org, run_company, run_team, and the webhook trigger. Webhooks return
429 rather than 402 so external callers can back off — the guard is what
stops a leaked webhook token from being weaponized into a queue flood.

A single team run also spawns a tier-tree of children, so the practical
cap grows with the topology — this counts the outer runs, not every step.
This commit is contained in:
Omar Sobh
2026-07-05 18:49:03 -07:00
parent 0c57f52502
commit d2b1f0569e
5 changed files with 39 additions and 0 deletions
+1
View File
@@ -371,6 +371,7 @@ pub async fn run_team(
Json(body): Json<RunTeamRequest>,
) -> Result<(StatusCode, Json<RunAccepted>), ApiError> {
let team = cm_db::repo::teams::get_team(&state.pool, id, user.workspace_id).await?;
crate::quota::enforce_new_run(&state, user.workspace_id).await?;
let run_id = Uuid::now_v7();
cm_db::repo::topology_runs::enqueue_run(
&state.pool,