Skip to content

feat(quota): cost-based monthly quota — per-allocation USD spend cap (Phase 33)#89

Merged
timcsy merged 2 commits into
mainfrom
046-cost-quota
Jun 13, 2026
Merged

feat(quota): cost-based monthly quota — per-allocation USD spend cap (Phase 33)#89
timcsy merged 2 commits into
mainfrom
046-cost-quota

Conversation

@timcsy

@timcsy timcsy commented Jun 13, 2026

Copy link
Copy Markdown
Owner

階段 33(046):成本制配額(跨端點統一額度上限)

補上「非 token 端點(OCR/圖片/語音/即時字幕…)繞過 token 月配額」的治理缺口(原則 1)。每分配新增選填每月花費上限(USD),以花費為跨單位共同分母治理所有端點。

做了什麼

  • modelallocations.quota_cost_usd_per_month(migration 0020 純加 nullable 欄);CallOutcome.rejected_cost_quota_exceeded(VARCHAR enum、無 migration)。
  • quota 服務current_month_costsum(cost_usd)、命中既有索引)+ is_over_cost_quota,對稱既有 token helper。未定價cost_usd NULL)coalesce 0 → 不計入、不被擋(誠實)。
  • preflight:token 後並列一道 cost 檢查,任一超過即擋;拒絕記新 outcome、綁分配。
  • realtime:連線中 watcher 擴充——committed 月花費 + 本連線 in-flight ≥ cap → 主動 close + 已累計時長落帳(任何 close 都落帳)。
  • admin:create/patch 收選填上限(>=0、null 清除);patch 寫 allocation_cost_quota_updated 稽核(FR-008);前端配額 Dialog 加欄。
  • 成員/me/allocations 回上限 + 本月花費;分配卡顯示「本月花費 / 上限」+ 接近上限提示。
  • 自適應池隔離:池只動 token 額度 → cost 上限不被再分配,整合測試固化(SC-005)。

測試

  • 全套件 759 passed(零回歸);ruff+mypy 乾淨;前端 tsc + 164 vitest + build 綠。
  • SC-003:既有 quota contract 測試未動。
  • 順手修 0015 migration-replay 測試的既有脆弱點(ORM 反映 head schema → 改 raw SQL seed,experience 教訓)。

部署

有 migration → --set migrationJob.enabled=true;驗 alembic current = 0020

🤖 Generated with Claude Code

…(Phase 33)

Closes the governance gap where non-token endpoints (OCR/image/TTS/realtime/…)
bypassed the token-only monthly quota entirely. Adds an optional per-allocation
monthly USD cap that governs EVERY endpoint via the cost common denominator.

- model: allocations.quota_cost_usd_per_month (migration 0020, additive nullable);
  CallOutcome.rejected_cost_quota_exceeded (VARCHAR enum, no migration).
- quota service: current_month_cost (sum cost_usd, hits the existing index) +
  is_over_cost_quota; mirrors the token quota helpers. Unpriced (cost_usd NULL)
  calls coalesce to 0 → not counted, not blocked (honest; admin must price them).
- preflight: cost check alongside the token check — either cap trips. Rejected
  calls are recorded with the new outcome (attributed to the allocation).
- realtime: in-connection cost watch extends the revocation watcher — committed
  month cost + this connection's in-flight cost ≥ cap → close + bill accrued time
  (any close path bills, FR-004). New close_reason "cost_exceeded".
- admin: create/patch accept quota_cost_usd_per_month (>=0, null clears); patch
  audits allocation_cost_quota_updated (FR-008). Frontend quota dialog gains the
  cost-cap field.
- members: /me/allocations exposes quota_cost_usd_per_month + cost_used_this_month;
  the allocation card shows "本月花費 / 上限" with a near-cap warning.
- adaptive pool isolation: the rebalance pool only touches token quota, so the cost
  cap is untouched —固化 by an integration test (SC-005).

Fix: the 0015 migration-replay test seeded an allocation via the HEAD-schema ORM;
switched to raw SQL so a later column (0020) doesn't break it (experience lesson).

Full suite 759 passed (zero regression); ruff+mypy clean; frontend tsc + 164 vitest
+ build green. Existing quota contract tests untouched (SC-003).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 13, 2026 06:55

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

- test_me_allocations: add the US3 /me/allocations cost-cap+spend assertion (the
  original append was lost to a tool glitch; the serialization was already shipped).
- test_credential_migration: remove ORM imports left unused after switching the
  0014-era seed to raw SQL (CI ruff caught them — re-run ruff after edits).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@timcsy timcsy merged commit fca0cd0 into main Jun 13, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants