Skip to content

fix(web): keep an autoscan source's stored config on unrelated edits - #2084

Merged
Quick104 merged 2 commits into
Silo-Server:mainfrom
blurbery:fix/web-autoscan-keep-source-config
Oct 10, 2026
Merged

Quick104 merged 2 commits into
Silo-Server:mainfrom
blurbery:fix/web-autoscan-keep-source-config

Conversation

@blurbery

@blurbery blurbery commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Problem

Related issue: #1230
Validation tasks: touches #1232 C1 (no result yet)

Saving an autoscan source in the edit dialog can restart its polling from now, even when only the label, interval or path mappings changed. The dialog always rebuilds source_config from the form before sending it. That fills in declared defaults, drops keys the descriptor no longer declares, and folds the legacy CephFS path keys. If the rebuilt map differs from the stored one, UpdateSource treats it as a config change and clears the poll marker (#1935), so whatever the source's server changed since the last poll is never reported. This change sends the stored config back unchanged unless the config form or the webhook provider was edited.

Quick found this in the #1935 review, and it was left for after the editor rewrite in #1929. Sonarr and Radarr sources have no config form and aren't affected. The trigger is a plugin with one, such as CephFS: a source whose stored config lacks a field with a default (for example after Exclusions was cleared, which repeats on every save).

Approach

  • editedSourceBody sends source_config exactly as stored unless the draft's configDirty flag is set (the schema form sets it on any change) or the webhook provider differs from the stored one. The provider has its own control that deliberately doesn't set configDirty, so it's compared directly.
  • A CephFS row that still holds the legacy nested-path keys is still sent rebuilt on its first save, so the editor keeps migrating it forward as designed. That reset happens once per row, as before. A row whose stored values aren't trimmed, as migration 172 can leave them, also resets once on its first save: the server trims the config before comparing it with the stored row, so the client can't avoid that one.
  • When the config was edited, the body is built as before, so defaults and legacy-key folding still apply to an actual config change.
  • This matches sourceUpdateBody, which the list's enable switch already uses and which sends the stored config unchanged.

Validation

  • Three new sourceForm tests: a label and interval edit sends the stored config even when the rebuilt one has an extra default, a provider change sends the rebuilt config, and a CephFS row with legacy keys is still migrated on a label edit. The first fails on ca186fe: it sends { lookback: '24h', window: '7d' } instead of the stored { lookback: '24h' }. The existing test that builds the PUT from an edited config now marks the config as edited, which is what it covers.
  • pnpm exec vitest run src/pages/admin/autoscan/: 16 files, 179 tests pass. tsc -p tsconfig.app.json --noEmit, ESLint and Prettier on the changed files: clean.
  • CI on dd71e13: every web job passed (run). The Evidence check waits on the evidence link below.
  • Not run against a live CephFS source.

Benchmarks

Not applicable. This changes which config the dialog sends, not how much work a save does.

Evidence

Evidence: https://evidence.siloserver.org/r/silo-server/pr-2084/

The dialog looks the same before and after. What changes is the request it sends for a save that didn't touch the config, shown as before and after PUT bodies from the test, and whether the source keeps its poll position afterwards. I don't have a CephFS source to capture from.

Risks

None identified. A save that edits the config behaves as before; one that doesn't sends what is already stored.

Checklist

  • I read and can explain the complete diff.
  • This pull request addresses one concern.
  • The Evidence section shows every change a user can see, or says there is none.

AI Disclosure

AI-assisted with Claude Opus. I directed the task and designed the work.

Saving the source edit dialog always rebuilt source_config from the
form, which fills in declared defaults, drops keys the descriptor no
longer declares and folds legacy keys. When that differed from the
stored map, the server took it as a config change and reset the
source's poll marker, so a label or interval edit restarted the source
from now. Send the stored config back unless the config form or the
webhook provider was changed, as the list's enable switch already does.
A row holding the superseded nested-path keys is migrated forward by its
first save from the editor. Keep doing that when only another field was
edited, instead of leaving the legacy keys until the config is changed.
@silo-kody

silo-kody Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Silo Kody — review complete

Review finished. Check the inline comments for findings and verify each suggestion against the code and tests.

Reviewing changes in Silo
  • Include the related issue, expected behavior, and validation steps in the PR description.
  • For API changes, describe the effect on Apple and Android clients and Jellyfin compatibility.
  • For plugin changes, identify the affected SDK contract, plugin, and catalog entry.
  • Follow this repository's AGENTS.md and CONTRIBUTING.md.
  • Request another review with @kody start-review in a PR comment.
  • React with 👍 or 👎 to give feedback on individual suggestions.
Review settings
Review Options

The following review options are enabled or disabled:

Options Enabled
Bug ✅
Performance ✅
Security ✅
Business Logic ❌

@Quick104 Quick104 added priority: P2 Limited scope, workaround exists, or polish impact: usability Core flow broken or severely blocked labels Oct 8, 2026 — with Cursor
@coderabbitai

coderabbitai Bot commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 12842a65-8e57-4103-9f67-559d35b6f35f

📥 Commits

Reviewing files that changed from the base of the PR and between ca186fe and dd71e13.


📒 Files selected for processing (2)
  • web/src/pages/admin/autoscan/sourceForm.test.ts
  • web/src/pages/admin/autoscan/sourceForm.ts

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 0 remain after this review.



📝 Walkthrough

Walkthrough

The source edit flow now preserves stored source_config when no qualifying config change applies. It detects config edits, webhook-provider changes, and legacy CephFS keys. Tests cover preservation and migration behavior.

Changes

Autoscan source configuration

Layer / File(s) Summary
Config edit detection and payload
web/src/pages/admin/autoscan/sourceForm.ts, web/src/pages/admin/autoscan/sourceForm.test.ts
The form detects config edits, webhook-provider changes, and legacy CephFS keys. It preserves stored source_config when none apply. Tests cover these cases.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Suggested reviewers: rhainland


Merge Risk: ⚪ Minimal · up to dd71e

Editing unrelated fields on an autoscan source now keeps its stored configuration, and legacy CephFS keys are still migrated on first save. No merge-blocking issues were found.

Pre-merge checks | Passed 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 2 files.
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.
Title check Passed The title clearly and concisely describes the main change: preserving an autoscan source's stored configuration when unrelated fields are edited.
Description check Passed The description is directly related to the changeset. It explains the problem, implementation, migration behavior, tests, validation, and risks.


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


  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@Quick104 Quick104 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Reviewed at dd71e13. One minor finding, about the PR description rather than the code. The summary comment has what I checked and the scores.

Reviewed with Claude Code (claude-opus-5-5).

Comment thread web/src/pages/admin/autoscan/sourceForm.ts
@Quick104

Copy link
Copy Markdown
Contributor

Review summary

Reviewed head: dd71e13

Fit: 8/10 · Readiness: 8/10 · conditional

Fit. This is a bounded fix in the web client for a real correctness problem: a label or interval edit made a poll source lose its place. It saves the way the list's enable switch already does. It isn't 9 or higher because the root cause is in UpdateSource, which clears the marker on any config difference. Any other client that sends a full PUT with defaults filled in will still restart polling. Comparing against the normalized stored config on the server would cover every writer. That belongs in a follow-up, not this PR.

Readiness. I found no defect in the code, and the checks pass. It isn't 9 or higher because no save has been made against a live poll source, and #1232 C1 hasn't been run.

Findings

  • Minor, PR description (fixed). A row that migration 172 left with untrimmed values still resets once on its first save, because the server trims the config before comparing. I corrected the description and changed no code.

What I checked

  • The dialog's controls. Every control in SourceDialog.tsx that writes the config either sets configDirty or is the webhook provider, and configEdited compares the provider directly. The schema form sets the flag at line 521. When the descriptor loads, the dialog re-parses the config from the stored row, so leaving the flag unset there is correct. selectPlugin runs only when adding a source.
  • The server. It resets the marker with a jsonb IS DISTINCT FROM, so resending the stored map keeps the marker whatever the key order. HandleUpdateSource doesn't check the config against the descriptor, so an older stored config can't block a label or interval save. The v2 PUT goes through the same handler.
  • Concurrent edits. A save that didn't touch the config now sends the live stored config instead of the dialog's snapshot, so it no longer overwrites another admin's config change. If another admin changes the webhook provider while the dialog is open, a save still reverts it, as it did before this PR.
  • Tests. Each new test fails when its branch of configEdited is removed (checked by mutation). pnpm exec vitest run src/pages/admin/autoscan/ at dd71e13: 16 files, 179 tests pass. The CI web jobs pass.
  • Not verified: no save against a running server with a poll source. The evidence is the source code and unit tests.
  • Cross-provider review: didn't run. Both attempts with Codex failed on an expired login, so this review is single-provider.

Validated features

No passed case on the v1.0 board is reached. The Autoscan web admin case, #1232 C1, hasn't been run yet. The PR body's Validation tasks: line names it as touched, which is accurate.

Other checks

  • User manual: unaffected. The manual doesn't describe when autoscan resets its poll position.
  • Apple and Android: nothing needed. This is a web admin change with no API change.
  • jellycompat: not applicable.

Reviewed with Claude Code (claude-opus-5-5).

@Quick104
Quick104 merged commit 970a214 into Silo-Server:main Oct 10, 2026
24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

impact: usability Core flow broken or severely blocked priority: P2 Limited scope, workaround exists, or polish

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants