Skip to content

fix(user-usage): keep manual resets out of reset cycles - #458

Open
Rerowros wants to merge 3 commits into
PasarGuard:devfrom
Rerowros:fix/user-usage-reset-cycle
Open

fix(user-usage): keep manual resets out of reset cycles#458
Rerowros wants to merge 3 commits into
PasarGuard:devfrom
Rerowros:fix/user-usage-reset-cycle

Conversation

@Rerowros

@Rerowros Rerowros commented May 10, 2026

Copy link
Copy Markdown
Contributor

Stack order: 3/4. Depends on #756 and #758. Merge after #758 with Squash and merge.

Summary

This pull request fixes how traffic reset cycles are calculated when a user is reset manually from the panel or API.

Previously, all reset events were stored as the same kind of usage reset log. The panel then used the latest reset log as the anchor for the next periodic reset. Because of that, a manual reset could accidentally move a user's monthly, weekly, daily, or yearly reset date forward.

That behavior makes manual paid resets less useful: if a user pays only to clear current traffic usage, the regular plan reset should not be postponed.

Traffic Reset Cycle Logic

  • Added explicit reset source tracking for user usage reset logs in app/db/models.py, distinguishing manual, scheduled, and next_plan reset events.
  • Added a database migration for user_usage_logs.reset_source in app/db/migrations/versions/b8e4e47b9f2c_add_user_usage_reset_source.py. Existing reset logs are marked as legacy. They remain a transitional fallback anchor until the first trusted scheduled or next_plan reset, preserving the existing cycle without misclassifying historical manual resets.
  • Updated periodic reset selection in app/db/crud/user.py so trusted scheduled and next_plan resets take precedence; before the first trusted reset, the latest legacy event is used as a transitional fallback. Manual resets never move the cycle.
  • Updated the scheduled reset job in app/jobs/reset_user_data_usage.py to write reset logs with reset_source=scheduled.
  • Updated next-plan activation in app/db/crud/user.py to write reset logs with reset_source=next_plan, because applying a next plan should start a new usage cycle.

Manual and API Reset Behavior

  • Kept manual user resets as reset_source=manual in app/db/crud/user.py, so panel/API resets clear current usage without changing the user's plan reset cycle.
  • Updated bulk user reset handling in app/db/crud/user.py so bulk manual resets use the same source-aware logic.
  • Updated global reset-all handling in app/db/crud/bulk.py to log manual reset events instead of deleting reset history. This preserves lifetime traffic accounting while still preventing manual resets from moving scheduled reset dates.

Reset Date Visibility

  • Added last_traffic_reset_at and next_traffic_reset_at to user response models in app/models/user.py.
  • Populated reset date fields for subscription users in app/operation/subscription.py.
  • Displayed the next traffic reset date on the subscription HTML page in app/templates/subscription/index.html.
  • Added reset date fields to dashboard API types in dashboard/src/service/api/index.ts.
  • Displayed last and next traffic reset dates in the dashboard user modal in dashboard/src/features/users/dialogs/user-modal.tsx.

Dashboard Date Handling

  • Updated user expiration sorting to use the shared date parser instead of native date coercion in dashboard/src/features/users/components/columns.tsx.
  • Updated status badge expiry parsing to use the shared date parser in dashboard/src/features/users/components/status-badge.tsx.
  • Updated cleanup date filters to send full-day ranges instead of raw picker timestamps in dashboard/src/pages/_dashboard.settings.cleanup.tsx.

Test Coverage

  • Added a regression test in tests/api/test_user_usage_reset_cycle.py proving that a manual reset does not delay the next periodic reset.
  • Extended subscription tests in tests/api/test_user.py to verify reset dates are exposed through subscription info and rendered on the subscription HTML page.
  • Updated API test setup in tests/api/conftest.py so JWT secret lookups use the test database consistently.

Why This Is Better

The new model separates business intent instead of inferring it from a timestamp.

A scheduled reset means the user's plan cycle advanced. A next-plan reset means the user's next plan was activated and should also become the new cycle anchor. A manual reset means an admin or API caller cleared current usage immediately, but did not change the user's regular reset schedule.

This makes the behavior more predictable for operators and fairer for users who buy or receive an extra traffic reset. Manual reset becomes an additive action instead of something that can silently postpone the normal plan reset.

@coderabbitai

coderabbitai Bot commented May 10, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e7534572-0243-4e43-9da7-a91994d2f884

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@M03ED

M03ED commented May 10, 2026

Copy link
Copy Markdown
Contributor

thanks for pr, there are some points i should write here
first of all why these 3 pr are related ? they have completely different subjects
second is this behavior was implemented since day one and it will be counted as major change,
third this remember me something i forgot to do, using next_plan and reset strategy at the same time should be rejected by api, its better for user to use only one of them (at some periods i had plan to remove next plan but that is not happening, at least today) and i don't know why people use 2 strategy at the same time

i check 2 other pr later but this pr stays open for a now, i will discuss it with other developers

@Rerowros

Copy link
Copy Markdown
Contributor Author

thanks for pr, there are some points i should write here first of all why these 3 pr are related ? they have completely different subjects second is this behavior was implemented since day one and it will be counted as major change, third this remember me something i forgot to do, using next_plan and reset strategy at the same time should be rejected by api, its better for user to use only one of them (at some periods i had plan to remove next plan but that is not happening, at least today) and i don't know why people use 2 strategy at the same time

Thanks for reviewing.

About the behavior change: I agree this is user-visible and can be considered major. I proposed it because the current implementation uses the latest usage reset log as the cycle anchor, so a manual/API reset also postpones the user's monthly/weekly/daily/yearly reset.

Manual/API reset and scheduled reset have different meanings: manual/API reset is a one-off administrative action, while scheduled reset is the user's reset-cycle boundary. Right now both actions use the same anchor, so a manual reset can unexpectedly change the next scheduled reset.

I do not want to force this behavior if the project considers the old logic intentional. I can adjust the PR to make the behavior explicit/backward-compatible, for example by adding an option such as reset_cycle / preserve_reset_cycle, or by separating "reset usage only" from "reset usage and restart cycle" in the API/UI.

Regarding next_plan + reset strategy: I agree this combination is confusing. My intent with reset_source=next_plan was only to say that applying a next plan starts a new usage cycle. If the preferred direction is to reject next_plan together with a reset strategy, I can move that validation into a separate PR and keep this PR focused only on manual resets not silently changing the scheduled cycle.

I can also remove the unrelated dashboard date parsing changes from this PR to keep the scope smaller.

@Rerowros
Rerowros force-pushed the fix/user-usage-reset-cycle branch 2 times, most recently from 9dfdcfc to f22f79e Compare August 9, 2026 21:44
@Rerowros
Rerowros force-pushed the fix/user-usage-reset-cycle branch from f22f79e to 04a53c4 Compare August 10, 2026 01:43
@Rerowros
Rerowros force-pushed the fix/user-usage-reset-cycle branch from 04a53c4 to b74a091 Compare August 10, 2026 01:51
@Rerowros
Rerowros force-pushed the fix/user-usage-reset-cycle branch from b74a091 to 1626478 Compare August 10, 2026 04:13
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