Files
sub2api-ht/docs/superpowers/specs/2026-04-27-account-bulk-edit-scope-and-compact-design.md
2026-04-27 17:21:11 +08:00

8.1 KiB

Account Bulk Edit Scope And Compact Design

Summary

This change expands admin account bulk edit in two directions:

  1. Add a second bulk-edit target scope based on the current filter result set, so operators do not need to manually select every account.
  2. Align OpenAI bulk-edit fields with single-account create/edit for the compact-related settings that are already supported elsewhere.

The design keeps the existing selected-row workflow intact and adds a unified bulk-edit entry with two explicit actions:

  • Bulk edit selected accounts
  • Bulk edit current filtered results

Current filtered results reuses the existing account-list filters. That means:

  • with no filters, it targets the whole account inventory
  • with a group filter, it targets all accounts in that group
  • with combined filters, it targets all matching accounts

Goals

  • Preserve the current selected-account bulk edit flow.
  • Let operators bulk edit the full current filtered result set without manual row selection.
  • Show the user the exact target scope before applying changes.
  • Reuse the current list filter semantics instead of inventing a separate "all accounts" or "by group" API.
  • Add the missing OpenAI bulk-edit fields:
    • OAuth codex_cli_only
    • API key openai_apikey_responses_websockets_v2_mode

Non-Goals

  • No new standalone "edit all accounts" route that ignores filters.
  • No new dedicated "edit group" route separate from list filters.
  • No change to the backend merge semantics for other bulk-edit fields.
  • No attempt in this change to refactor all account form components into a shared schema system.

Current State

Bulk edit entry

The account list currently exposes bulk edit only through selected-row actions. AccountsView.vue passes selIds, selPlatforms, and selTypes into BulkEditAccountModal.vue.

Filter state

The account page already keeps a central params object for current filters and reloads the table from that state. Group filtering already exists in AccountTableFilters.vue.

Bulk edit payload

BulkEditAccountModal.vue builds a bulk update request around explicit account IDs.

OpenAI field gap

Single-account create/edit already supports:

  • openai_passthrough
  • OAuth WS mode
  • API key WS mode
  • OAuth codex_cli_only

Bulk edit currently supports:

  • openai_passthrough
  • OAuth WS mode only

That leaves a real capability gap for operators managing large OpenAI account sets.

User Experience

Entry point

Use one compact Bulk edit dropdown button in the table-level bulk actions area above the grid.

The dropdown contains:

  • Bulk edit selected accounts
  • Bulk edit current filtered results

Behavior:

  • If there is no row selection, the selected accounts action is disabled.
  • Current filtered results is always available.
  • The existing separate immediate Edit action in the selected-row bar is replaced by this unified dropdown to avoid duplicate buttons that mean different scopes.

Modal scope messaging

The bulk edit modal gets a required scope descriptor prop.

For selected accounts:

  • show the existing count-based info banner
  • keep using explicit selected account metadata for platform/type compatibility checks

For current filtered results:

  • show a banner stating that edits apply to the current filtered result set
  • show the matched account count from a preview query
  • show a short summary of active filters when practical, especially group/search/platform/type/status filters

Safety

For filtered-result mode:

  • disable submit if the preview count is 0
  • refresh the target count when the modal opens
  • keep the final success toast count aligned with the backend result

The modal should not silently fall back from filtered mode to selected mode.

Backend/API Design

Request model

Extend bulk update to support two target modes:

  • explicit IDs
  • filter-based query

The request shape should keep backward compatibility for the selected-ID path while allowing a filter target. The backend handler can accept a payload that contains either:

  • account_ids
  • or filters

but not neither.

The filters payload should reuse the existing account-list query semantics already used by /admin/accounts and /admin/accounts/data, including:

  • search
  • platform
  • type
  • status
  • privacy_mode
  • group
  • existing sort fields may be ignored for mutation targeting if not needed

Preview count

The frontend needs an accurate target count before submit in filtered-result mode. The simplest compatible approach is:

  • call the existing account list endpoint with the current filters and a minimal page size strategy sufficient to obtain total count

If the current API makes that awkward, add a narrow preview/count helper for bulk edit target resolution. Prefer reusing the existing listing contract first.

Target resolution

For filtered-result mode, the backend must resolve matching account IDs server-side from the submitted filters rather than trusting only currently loaded page data. This is required so filtered-result mode can act on the full result set across pagination.

Compatibility metadata

The frontend still needs platform/type compatibility to determine which fields to show. For filtered-result mode, derive this from the preview result set returned from the same query used to show count. If the preview spans mixed incompatible account types, show the same warnings/conditional UI that selected mode already uses.

Frontend Design

Accounts view

AccountsView.vue will:

  • replace the direct selected-only bulk edit trigger with a dropdown action model
  • keep a reactive description of the pending bulk edit scope
  • pass either selected IDs or current filter params into the modal

The "current filtered results" action uses the live params object snapshot at open time, not a mutable live subscription while the modal is already open.

Bulk edit modal

BulkEditAccountModal.vue will accept a richer target contract, for example:

  • target mode
  • selected IDs or filter snapshot
  • preview count
  • preview platform/type coverage if needed

The modal remains one form; only the scope banner and submission target differ.

OpenAI field alignment

Add the missing OpenAI controls to bulk edit:

  • OAuth codex_cli_only
  • API key WS mode selector

Rules:

  • OAuth accounts show OAuth WS mode and codex_cli_only
  • API key accounts show API key WS mode
  • mixed OpenAI OAuth/API key selections continue to show only fields that are safe for the entire target set

The payload builder must write:

  • extra.codex_cli_only
  • extra.openai_apikey_responses_websockets_v2_mode
  • extra.openai_apikey_responses_websockets_v2_enabled

with the same enable/disable semantics already used by single-account forms.

Testing Strategy

Frontend tests

Add or extend tests for:

  • bulk edit dropdown actions in the accounts view
  • selected-account mode still calling bulk update by IDs
  • filtered-result mode calling bulk update with filter target
  • filtered-result mode showing preview count and blocking submit on zero matches
  • OAuth bulk edit supporting codex_cli_only
  • API key bulk edit supporting API key WS mode
  • no regression for existing passthrough and OAuth WS mode tests

Backend tests

Add or extend tests for:

  • bulk update request validation for IDs vs filters
  • filtered-result mode resolving all matching accounts across pagination semantics
  • mixed-channel risk checks still running for filter-target updates if applicable
  • backward compatibility for the existing selected-ID request path

Risks

  • Filter semantics can drift if bulk edit reimplements list-filter parsing differently from the listing endpoints.
  • Filtered-result mode can surprise users if the active scope is not shown clearly enough.
  • Large filtered updates may affect many rows; success/error messaging must stay explicit.

Recommendation

Implement this as a targeted extension of the existing bulk edit flow:

  • unify the entry point in the table action area
  • add filter-target bulk update support
  • align the missing OpenAI compact-related fields

This keeps the mental model simple and solves the large-account-management pain without introducing a second parallel batch-edit system.