# Account Bulk Edit Scope And Compact Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Add filter-result bulk edit to admin accounts, unify the table-level bulk-edit entry, and align OpenAI bulk-edit controls with the existing compact-related single-account settings.
**Architecture:** Extend the existing `/admin/accounts/bulk-update` flow to accept either explicit account IDs or a server-resolved filter target. Reuse the current account-list filter contract for scope resolution, then update the accounts view and bulk-edit modal so the UI can launch either selected-account edits or current-filter-result edits from one compact dropdown. Keep the existing bulk-edit form, but expand its target contract and OpenAI-specific field coverage.
// construct BulkUpdateAccountsInput with Filters and no AccountIDs
// stub repository list/search path to return matching IDs
// assert BulkUpdate is called with all matching account IDs
}
```
- [ ] **Step 4: Run test to verify it fails**
Run: `GOCACHE=/tmp/go-build GOMODCACHE=/tmp/go-mod go test ./backend/internal/service -run TestAdminServiceBulkUpdateAccounts_ResolvesIDsFromFilters -count=1`
Expected: FAIL because `BulkUpdateAccountsInput` and service logic only use explicit `AccountIDs`.
// call the existing repository list/search path with the submitted filters
// page through all matching rows or use a dedicated ID-only query helper
// return unique IDs in stable order
}
```
- [ ] **Step 4: Run targeted backend tests**
Run: `GOCACHE=/tmp/go-build GOMODCACHE=/tmp/go-mod go test ./backend/internal/handler/admin ./backend/internal/service -run 'TestBulkUpdateAcceptsFilterTargetRequest|TestAdminServiceBulkUpdateAccounts_ResolvesIDsFromFilters' -count=1`
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