unbridled-41 opened a new pull request, #4255:
URL: https://github.com/apache/rocketmq-dashboard/pull/4255
Fixes #4250.
## Problem / Evidence
`GeneralSettingsTab` fetches the general settings once on mount and builds
every save payload from that snapshot, including the
`llmProvider`/`model`/`baseUrl` fields the tab never renders or edits. The AI
assistant tab writes the same persisted record through `/llm/config` while the
general tab stays mounted (antd Tabs keep visited panes alive), so every
general save posts the mount-time LLM values back and silently reverts the AI
configuration.
Repro: open `/settings` (snapshot: `llmProvider=openai`) → AI tab, switch
provider/model/base URL, save → back on the general tab (still mounted), change
the session timeout, save → `POST /api/settings/general/save` carries the stale
`llmProvider`/`model`/`baseUrl` and overwrites the row.
## Root cause / Fix
The tab must not send fields it does not manage from its own snapshot.
`persistPreference` and `mergeAndSave` now re-read the persisted settings
(`loadFreshSettings`) before building each payload, so unmanaged fields are
sent as currently stored; on a fresh-read failure the previous snapshot is used
as fallback (baseline behavior). After a preference save succeeds, local state
is synced to the fresh base plus the saved patch so the theme/compact controls
keep showing the saved value. `loadFreshSettings` takes the current snapshot as
its fallback parameter, which also keeps the `Promise<GeneralSettings>`
contract type-clean.
## Priority & scoring
PRIORITY 74 = impact 30 (any general save silently reverts the AI
provider/model/base URL — persisted data loss; the AI chat then calls the wrong
provider or billing model with a possibly mismatched key, no error shown) +
scope 14 (every save path on the tab: security form, notification form, theme,
compact, three notification-test buttons) + reproducibility 18 (deterministic
4-step repro, covered by a regression test) + maintenance value 12 (fresh-read
convention; #2863's server-side null-backfill cannot address stale non-null
client values, as recorded in #4250). FIX_CONFIDENCE 88: mechanism verified
red→green, fallback preserves baseline behavior on read failure.
## Tests
- New regression `saves llm fields from a fresh read instead of the
mount-time snapshot` mocks a mount-time `openai` snapshot and a fresh-read
`deepseek` record, submits the security form and asserts the save payload
carries the fresh `deepseek` values.
- Red on the unfixed code:
`src/pages/settings/__tests__/GeneralSettingsTab.test.tsx` → `Tests 1 failed |
6 passed (7)` with `× saves llm fields from a fresh read instead of the
mount-time snapshot` (`expected "vi.fn()" to be called with arguments:
[ObjectContaining{…}]` — payload carried the stale `openai` values).
- The existing theme test additionally asserts the 深色 option stays selected
after the save completes; this assertion fails when the post-save state sync is
omitted (`Expected the element to have class: ant-segmented-item-selected`), so
the visible-preference behavior is pinned.
- Green with the fix: `Tests 7 passed (7)` (re-run after the final commit,
including lint-staged reformatting).
- Full web suite `npx vitest run`: 982 tests, 2 failed —
`ClusterPage.test.tsx` and `ConsumerPage.test.tsx`, files this branch does not
touch and known load-fragile cases under the parallel run; re-run in isolation:
ClusterPage `Tests 25 passed (25)`, ConsumerPage `Tests 31 passed (31)`.
- `npx tsc -b` clean; `npm run build` (tsc -b + vite build) succeeds; `npx
eslint .` 0 errors (10 warnings, all in files this branch does not touch).
## Risk
One extra GET before each save (settings-page frequency makes this
negligible); on a fresh-read failure the save still proceeds from the previous
snapshot, matching today's behavior. State after a successful preference save
now reflects server truth plus the patch. No API or type changes beyond this
component and its test.
Head: ea4ea0a1 (fix/settings-general-save-stale-llm-rollback, 1 commit).
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]