Skip to content

fix(billing): treat weekends and configured holidays as off-peak - #412

Merged
argszero merged 1 commit into
mainfrom
fix/billing-peak-hour-weekday
Oct 16, 2026
Merged

argszero merged 1 commit into
mainfrom
fix/billing-peak-hour-weekday

Conversation

@argszero

Copy link
Copy Markdown
Owner

Summary

billing::is_peak_hour() looked at the hour only, so every day of the week was billed at the DeepSeek peak price between 9:00-12:00 and 14:00-18:00 Beijing time. DeepSeek's own rule is narrower: peak is Monday to Friday, excluding Chinese statutory holidays; everything else — including weekends and holidays, all day — is off-peak, and the off-peak price is half the peak price. So deepseek-flash / deepseek-v4-pro calls on a Saturday or Sunday were charged double: the platform billed users more than the upstream rule justifies.

The weekday part is code; the statutory-holiday calendar is data, and it now comes from a new [billing] holidays table. The work order left that choice to the implementer and recommended configuration, because a table in code would force a release every year.

Rant: 2026-10-16T14:08:13.986531+08:00 — 【计费】高峰时段判定不看星期几 —— 周末按 2 倍价扣点,而 DeepSeek 官方在周末是空闲价 / "the peak-hour test ignores the day of the week — weekends are charged double, while DeepSeek charges the off-peak rate on weekends" (translated from the Chinese original).

Related Issue

No issue — the input is this project's own rant queue; the rant timestamp is named above.

Changes

  • src/billing.rs — is_peak_hour(utc, holidays): a weekend returns off-peak; a date listed in holidays returns off-peak; the 9-12 / 14-18 window itself is unchanged. Doc comment updated.
  • src/config.rs — new Billing { holidays: Vec<NaiveDate> }, optional ([billing] absent ⇒ empty table ⇒ weekends only), plus tests pinning the YYYY-MM-DD format, the empty default, and a malformed date being a startup error.
  • src/gateway.rs — the single production call site passes &st.cfg.billing.holidays.
  • config/config.example.toml — new [billing] section documenting the rule and the table, and the [[models]] note no longer says the peak window is Monday to Sunday.

⚠️ Operator note: config/config.toml is gitignored and is not part of this repository, so this PR ships the tracked example only. An instance with no [billing] section gets the weekend fix immediately and exempts no holidays until holidays is filled in from the official annual calendar. No holiday dates are invented here — the shipped table is empty on purpose.

Deliberately out of scope: the marketplace i18n strings (mk.peak.title, mk.detail.peakVal) name the peak window (9-12 / 14-18) and stay true; effective_prices()'s "peak_* = 0 means keep the off-peak price" semantics and every other pricing path are untouched.

Tests

  • cargo test — 564 passed / 0 failed (562 on main; this PR adds 2 config tests and rewrites the peak-hour test).
  • New legs: Monday 9:00 peak, 8:59 off, 12:00 off, 11:59 peak, 14:00 peak, 13:59 off, 18:00 off, 17:59 peak; Friday 10:00 peak; Monday 0:00 and 23:00 off; Saturday 10:00 off, Sunday 10:00 off; a listed holiday 10:00 off while its neighbouring weekday stays peak; and the empty table meaning "weekends only".
  • Mutation check as the work order requires: with the weekday guard reduced to a never-matching arm, the Saturday leg fails at src/billing.rs:327; restoring the guard makes it pass.
  • cargo fmt --check clean; cargo clippy --all-targets -- -D warnings clean.
  • git grep 周一至周日 → zero hits in tracked files.

Checklist

  • Branch name follows the convention (fix/…)
  • Commit message uses Conventional Commits
  • Configuration change mirrored in config/config.example.toml
  • Single purpose, smallest reasonable diff

Peak pricing only looked at the hour, so every day of the week was billed at
the DeepSeek peak price between 9:00-12:00 and 14:00-18:00 Beijing time.
DeepSeek's own rule is narrower: peak is Monday to Friday, excluding Chinese
statutory holidays; weekends and holidays are off-peak for the whole day, at
half the peak price. Weekends were therefore charged double.

- is_peak_hour() takes the configured holiday dates and returns false on a
  weekend or on a listed date (rant 2026-10-16T14:08:13).
- new optional [billing] holidays table (empty = weekends only), documented in
  config/config.example.toml; a malformed date fails at startup.

rant: 2026-10-16T14:08:13.986531+08:00
@argszero
argszero merged commit ada9043 into main Oct 16, 2026
2 checks passed
@argszero
argszero deleted the fix/billing-peak-hour-weekday branch October 16, 2026 13:51
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.

1 participant