Skip to content

[codex] add account enable scheduling toggle#108

Merged
james-6-23 merged 2 commits into
james-6-23:mainfrom
Cshvee:codex/account-enable-scheduling-toggle
Apr 30, 2026
Merged

[codex] add account enable scheduling toggle#108
james-6-23 merged 2 commits into
james-6-23:mainfrom
Cshvee:codex/account-enable-scheduling-toggle

Conversation

@Cshvee
Copy link
Copy Markdown
Contributor

@Cshvee Cshvee commented Apr 30, 2026

Summary

  • add a persisted account enabled flag and admin API for toggling scheduling eligibility
  • exclude disabled accounts only from dispatch/scheduler selection
  • add per-account and batch enable/disable controls in the admin accounts UI
  • add regression coverage for scheduler gating and for probes/auto-clean remaining independent

Validation

  • npm --prefix frontend run typecheck
  • npm --prefix frontend run build
  • go test ./...

Summary by CodeRabbit

  • New Features

    • Admins can toggle account enable/disable via a new admin action; state is persisted and reflected in the UI.
    • Disabled accounts are excluded from dispatch/scheduling but still receive background probes/maintenance.
    • Accounts page: "disabled" status filter, per-row and batch enable/disable controls, badges, toasts, and localization text added.
  • Tests

    • End-to-end and scheduler tests added to verify enable/disable behavior and defaults.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 30, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 023bad0a-db95-454f-8ef3-6af736b68a22

📥 Commits

Reviewing files that changed from the base of the PR and between 132ea2b and e563488.

📒 Files selected for processing (4)
  • admin/handler.go
  • database/postgres.go
  • database/sqlite_test.go
  • frontend/src/pages/Accounts.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • frontend/src/pages/Accounts.tsx

📝 Walkthrough

Walkthrough

Adds account enable/disable support end-to-end: DB column and migration, admin API endpoint to toggle enabled, in-memory store flag to exclude disabled accounts from dispatch, scheduler integration, tests, frontend API, UI controls, and localization strings.

Changes

Cohort / File(s) Summary
Admin API & Handler
admin/handler.go
New POST /api/admin/accounts/:id/enable handler (ToggleAccountEnabled) accepts { enabled }, validates input, calls db.SetAccountEnabled, and applies runtime state via store.ApplyAccountEnabled. accountResponse gains enabled field.
Database schema & queries
database/postgres.go, database/sqlite.go, database/sqlite_test.go
Adds accounts.enabled column (default TRUE/1). AccountRow includes Enabled. Queries use COALESCE(enabled, true). New SetAccountEnabled persists state; SQLite migration and tests added.
Store & Scheduler
auth/store.go, auth/fast_scheduler.go, auth/fast_scheduler_test.go
Adds DispatchPaused (atomic) to Account, integrates into availability checks to skip paused accounts for dispatch, and exposes ApplyAccountEnabled to toggle runtime dispatch participation. Tests ensure dispatch skipping while preserving probe/recovery behavior.
Frontend API, types & UI
frontend/src/api.ts, frontend/src/types.ts, frontend/src/pages/Accounts.tsx
Client toggleAccountEnabled added. AccountRow includes optional enabled. Accounts page: filter for disabled, per-row badge and toggle buttons, batch enable/disable actions, toasts, and reloads.
Localization
frontend/src/locales/en.json, frontend/src/locales/zh.json
Added i18n strings for enable/disable labels, hints, success/failure messages, filter label, and batch completion summaries.

Sequence Diagram

sequenceDiagram
    participant User as User
    participant Frontend as Frontend UI
    participant API as Admin Handler
    participant DB as Database
    participant Store as Account Store
    participant Scheduler as Fast Scheduler

    User->>Frontend: Click enable/disable
    Frontend->>API: POST /api/admin/accounts/{id}/enable<br/>{ enabled }
    API->>DB: SetAccountEnabled(id, enabled)
    DB-->>API: OK / Err
    API->>Store: ApplyAccountEnabled(id, enabled)
    Store->>Store: Set DispatchPaused flag (atomic)
    Store->>Scheduler: Update account state
    Scheduler-->>Store: Acknowledged
    API-->>Frontend: MessageResponse
    Frontend->>Frontend: Show toast and reload accounts
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 A toggle, a tap, accounts take a rest,
DB, store, and UI all pass the test,
Paused for a probe, still watched from afar,
We hop through the code and cheer for the star!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title '[codex] add account enable scheduling toggle' clearly and concisely describes the main change: adding a feature to enable/disable accounts and control their scheduling eligibility.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

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

Review rate limit: 2/3 reviews remaining, refill in 20 minutes.

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

@Cshvee Cshvee force-pushed the codex/account-enable-scheduling-toggle branch from b41b203 to 6978bee Compare April 30, 2026 05:11
@Cshvee Cshvee force-pushed the codex/account-enable-scheduling-toggle branch from 6978bee to 132ea2b Compare April 30, 2026 05:12
@Cshvee Cshvee marked this pull request as ready for review April 30, 2026 09:21
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (2)
database/sqlite_test.go (1)

54-60: ⚡ Quick win

Add a length assertion before rows[0] access in the second read.

After the second ListActive, asserting length first avoids panic-style failures and keeps diagnostics clear.

Suggested fix
 	rows, err = db.ListActive(ctx)
 	if err != nil {
 		t.Fatalf("ListActive 返回错误: %v", err)
 	}
+	if len(rows) != 1 {
+		t.Fatalf("ListActive 返回 %d 条,want 1", len(rows))
+	}
 	if rows[0].Enabled {
 		t.Fatal("disabled account Enabled = true, want false")
 	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@database/sqlite_test.go` around lines 54 - 60, The test calls db.ListActive
and immediately indexes rows[0] without verifying the slice length; add an
assertion (e.g., require or t.Fatalf) that len(rows) > 0 (or equals the expected
count) after the second db.ListActive call and before accessing rows[0] to
prevent panics and produce clearer diagnostics; update the test around the
ListActive result handling (the rows variable and the surrounding test function)
to check length and fail with a helpful message if it's empty.
frontend/src/pages/Accounts.tsx (1)

797-814: ⚡ Quick win

Harden batch loading cleanup with finally

setBatchLoading(false) should be in a finally block so the toolbar never gets stuck disabled if this handler grows or throws in future edits.

Suggested diff
 const handleBatchEnabled = async (enabled: boolean) => {
   if (selected.size === 0) return
   setBatchLoading(true)
   let success = 0
   let fail = 0
-  for (const id of selected) {
-    try {
-      await api.toggleAccountEnabled(id, enabled)
-      success++
-    } catch {
-      fail++
-    }
-  }
-  showToast(t(enabled ? 'accounts.batchEnableDone' : 'accounts.batchDisableDone', { success, fail }))
-  setBatchLoading(false)
-  setSelected(new Set())
-  void reload()
+  try {
+    for (const id of selected) {
+      try {
+        await api.toggleAccountEnabled(id, enabled)
+        success++
+      } catch {
+        fail++
+      }
+    }
+    showToast(t(enabled ? 'accounts.batchEnableDone' : 'accounts.batchDisableDone', { success, fail }))
+    setSelected(new Set())
+    void reload()
+  } finally {
+    setBatchLoading(false)
+  }
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/pages/Accounts.tsx` around lines 797 - 814, The handler function
handleBatchEnabled can leave the UI stuck in loading if an unexpected error
occurs before setBatchLoading(false); wrap the main work in a try/finally so
setBatchLoading(false) always runs: move the for-loop and toast/show logic into
a try block and call setBatchLoading(false) in a finally block; also ensure
setSelected(new Set()) and void reload() remain in the finally (or after the
finally) as appropriate so selection is cleared and reload always runs
regardless of errors.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@admin/handler.go`:
- Around line 1688-1701: The request binding currently uses Enabled bool which
treats a missing field as false and can accidentally disable accounts; change
the inline req struct to use Enabled *bool `json:"enabled" binding:"required"`
(or otherwise validate presence) and return writeError(c, http.StatusBadRequest,
...) when req.Enabled == nil so the client must supply the field; additionally,
when calling h.db.SetAccountEnabled(ctx, id, req.Enabled) detect a not-found DB
error (e.g., sql.ErrNoRows or your repo's ErrNotFound) and return writeError(c,
http.StatusNotFound, ...) instead of treating it as a 500, otherwise continue to
return 500 for other errors.

In `@database/postgres.go`:
- Around line 2029-2033: In SetAccountEnabled on DB, check the ExecContext
result's RowsAffected and return sql.ErrNoRows when it is 0 instead of treating
it as success: change the call to capture the sql.Result (e.g., res, err :=
db.conn.ExecContext(...)), handle and return any err immediately, then call
res.RowsAffected(), and if that returns 0 return sql.ErrNoRows; otherwise return
nil. Ensure you import/use sql.ErrNoRows and keep the function signature
unchanged.

In `@frontend/src/pages/Accounts.tsx`:
- Around line 1341-1349: The row-level enable/disable button uses reversed
icons: swap the icons used in the Button where handleToggleEnabled is invoked so
that when account.enabled === false (the enable action) it renders the Power
icon and when enabled it renders PowerOff, matching the batch controls; update
the JSX inside the Button (the conditional that currently returns PowerOff for
the false case and Power for the true case) accordingly.

---

Nitpick comments:
In `@database/sqlite_test.go`:
- Around line 54-60: The test calls db.ListActive and immediately indexes
rows[0] without verifying the slice length; add an assertion (e.g., require or
t.Fatalf) that len(rows) > 0 (or equals the expected count) after the second
db.ListActive call and before accessing rows[0] to prevent panics and produce
clearer diagnostics; update the test around the ListActive result handling (the
rows variable and the surrounding test function) to check length and fail with a
helpful message if it's empty.

In `@frontend/src/pages/Accounts.tsx`:
- Around line 797-814: The handler function handleBatchEnabled can leave the UI
stuck in loading if an unexpected error occurs before setBatchLoading(false);
wrap the main work in a try/finally so setBatchLoading(false) always runs: move
the for-loop and toast/show logic into a try block and call
setBatchLoading(false) in a finally block; also ensure setSelected(new Set())
and void reload() remain in the finally (or after the finally) as appropriate so
selection is cleared and reload always runs regardless of errors.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: ed176282-4f14-4ed8-9251-9ef417899e1b

📥 Commits

Reviewing files that changed from the base of the PR and between ed6d300 and 132ea2b.

📒 Files selected for processing (12)
  • admin/handler.go
  • auth/fast_scheduler.go
  • auth/fast_scheduler_test.go
  • auth/store.go
  • database/postgres.go
  • database/sqlite.go
  • database/sqlite_test.go
  • frontend/src/api.ts
  • frontend/src/locales/en.json
  • frontend/src/locales/zh.json
  • frontend/src/pages/Accounts.tsx
  • frontend/src/types.ts

Comment thread admin/handler.go
Comment thread database/postgres.go
Comment thread frontend/src/pages/Accounts.tsx
@james-6-23 james-6-23 merged commit d47e531 into james-6-23:main Apr 30, 2026
6 checks passed
@Cshvee Cshvee deleted the codex/account-enable-scheduling-toggle branch April 30, 2026 18:30
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