mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-21 06:12:17 +03:00
* fix(usage) handle OpenRouter PAYG credit percentage OpenRouter PAYG accounts without a per-key limit previously rendered the credits row as 'total: 0, remainingPercentage: 100, unlimited: true', treating /credits balance as unlimited even when a real credit pool was present. Route the credit pool through the credits renderer with the real denominator: total = totalCredits when positive, used = total - creditBalance, remaining = creditBalance, remainingPercentage = round(balance / total * 100), isCredits: true, unlimited: false. Per-key limit still wins. A non-positive pool surfaces the row but never invents a 100% bar. Tests cover: explicit key limit, PAYG account credits without key limit, key limit taking priority over account credits, and a balance without a positive denominator. * fix(usage) render OpenRouter PAYG quota as a metered percentage bar The frontend parser was routing every OpenRouter 'credits' quota through buildCreditsQuota(), which sets isCredits: true. QuotaCardExpanded short-circuits on that flag and shows only the USD balance as a bare number, so a real PAYG payload (used: 7.33, total: 10, remaining: 2.67, remainingPercentage: 27) was rendered as '$2.67' instead of the '27% left / 7.33 / 10' bar the backend already computed. Drop isCredits: true for any payload whose total is a positive finite number - the row then goes through the normal normalizeQuotaEntry() path with currency preserved as an extra. The balance-only fallback (total 0 or non-finite denominator, used by legacy /credits responses) still uses buildCreditsQuota() so the row stays renderable, and never invents a 100% percentage. The frontend test now asserts: - PAYG positive denominator -> total: 10, remainingPercentage: 27, currency: 'USD', isCredits !== true. - Balance-only payload -> isCredits === true, creditCount === 2.67, total: 0, no fabricated 100%. - NaN denominator -> balance-only fallback. - Non-credits keys -> unchanged normalizeQuotaEntry() path. - Mixed payload -> normal quota row + PAYG row, both kept. * docs(changelog): add OpenRouter PAYG fix fragment * docs(changelog): remove self credit
changelog.d/ — changelog fragments
A PR never edits CHANGELOG.md directly during the cycle. Instead it adds ONE new
file here — its changelog entry as a fragment. Two PRs never touch the same file, so
changelog merge conflicts (the "CHANGELOG-eat" cascade that forced a re-sync push + full
CI re-run after every sibling merge) are structurally impossible.
Convention
| Directory | Aggregates under |
|---|---|
features/ |
### ✨ New Features |
fixes/ |
### 🐛 Bug Fixes |
maintenance/ |
### 📝 Maintenance |
- Filename:
<PR-number>-<short-slug>.md(e.g.fixes/6700-dockerfile-better-sqlite3.md). The PR number prefix keeps aggregation order deterministic. - Content: the exact bullet line(s) that should land in
CHANGELOG.md, starting with-. Multi-line (continuation) bullets are fine. Keep the repo's credit format:(#PR — thanks @user). - One fragment per PR (rarely more, e.g. a PR that both fixes and adds).
Example
changelog.d/fixes/6496-cloudflare-relay-worker-syntax.md:
- **fix(providers):** Cloudflare relay Worker deploys use Service Worker syntax with `body_part` metadata ([#6496](https://github.com/diegosouzapw/OmniRoute/pull/6496)) — thanks @SeaXen
Aggregation
The release captain (or /generate-release) folds all fragments into CHANGELOG.md and
deletes them:
node scripts/release/aggregate-changelog.mjs # write + delete fragments
node scripts/release/aggregate-changelog.mjs --dry-run # preview only
Fragment well-formedness is enforced by npm run check:changelog-integrity (the same
gate that guards against CHANGELOG-eat for legacy direct edits).