Settings split: land passes 3 and 4 (they merged into their stack bases, not main) - #150
Merged
Merged
Conversation
…tions Third extraction pass, stacked on the pass-2 branch so it can proceed while that one is in review. Retarget to main once #146 lands. Two small improvements over a straight lift-and-shift: - RegionSection imports COUNTRY_OPTIONS and normalizeCountry straight from lib/region instead of taking them as props. Extraction is a chance to shrink the prop surface, not just relocate it — anything a section can reach on its own should not travel through the parent. - PrivacyPoliciesBulkSection derives a single `busy` from the running phase, which makes explicit why both buttons disable together: the two runs contend for one server-side mutex, so starting either mid-run would just 409. Both sections auto-save on change, which is now the third distinct save shape in this directory (click, blur, change) — worth keeping straight rather than flattening as the remaining sections move. Verified DOM byte-identical before vs after (3,855 bytes), same method as passes 1 and 2. A note on that method, since it bit twice here: capturing the baseline requires stashing with `-u`. `git stash push <paths>` silently skips UNTRACKED files, so the new section components stayed on disk importing types that had just been stashed away, and the baseline build failed its typecheck — surfacing later as a confusing ECONNREFUSED from the capture script rather than as a build error. The build output is no longer discarded, so a failure now reports itself. Full suite 45 passed, 441 unit tests, lint/typecheck/i18n clean. SettingsView 11,460 -> 11,328 lines; 6 sections extracted, 13 to go. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…r 11k
Fourth extraction pass, stacked on pass 3.
Intended to take import-history (1,342 lines, the largest section) but
the analysis said not to, and that finding is the more useful half of
this pass. Only FIVE of its identifiers leak into other rendered
sections — but its state, effects and handlers are spread across 32
declaration sites spanning ~3,000 lines, interleaved with other
sections' logic. Passing ~35 props would be wrong, and moving state and
JSX together would be an enormous, hard-to-review diff. It wants two
stages instead:
1. consolidate its scattered logic into a useImportHistory() hook
IN PLACE — JSX untouched, so the DOM diff verifies it trivially
2. move the JSX into a component consuming that hook
So this pass took deployment-diagnostics (326 lines), which fits the
established pattern.
Two shared helpers fell out, which is a good sign the boundaries are
real rather than arbitrary:
- fmtBytes moved to a new settings/format.ts because Deployment
Diagnostics and Backup both use it. Duplicating a formatter is how
two surfaces quietly start disagreeing about what "1.5 MB" means.
- DeploymentDiagnostics + DeploymentDiagnosticCheck +
DeploymentCheckStatus moved to settings/types.ts.
The card is mostly read-only but doubles as the admin-token unlock
surface — the diagnostics endpoint is token-gated, so a locked session
renders the unlock field instead of data. That is why the token props
live on this component rather than in a section of their own; the
comment says so, since the grouping looks arbitrary otherwise.
Method note: for a block this size the JSX was moved VERBATIM rather
than retyped, and when a regex edit damaged the file mid-way it was
regenerated from the committed version rather than patched by hand.
Retyping 326 lines of dense JSX is exactly how a "pure refactor"
acquires a silent diff.
Verified DOM byte-identical before vs after (4,677 bytes).
Full suite 45 passed, 441 unit tests, lint/typecheck/i18n clean.
SettingsView 11,328 -> 10,951 lines — under 11k for the first time.
7 sections extracted, 12 to go.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This was referenced Aug 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Passes 3 and 4 never reached
mainBoth #147 and #149 show as MERGED, but their code is not in
main— andmainis still at the pass-2 state (11,460 lines). This PR lands them.What happened
They were stacked PRs, and each merged into its base branch rather than into
main:refactor/settings-sections-2mainrefactor/settings-sections-3main#146merged tomainbefore #147 was merged into its base, somainpicked up pass 2 only. The later merges landed in intermediate branches that were never themselves merged onward. GitHub reports all three as merged, which is exactly what makes this easy to miss — the PR list looks clean while two passes of work sit off to one side.My fault for stacking without flagging the merge-order requirement more loudly than a one-line note.
What this contains
The two missing commits, cherry-picked onto current
main(linear, no merge noise):refactor(settings): extract App Store Region and Privacy Policies sections(pass 3)refactor(settings): extract Deployment Diagnostics; SettingsView under 11k(pass 4)Cherry-picked rather than merged because
mainhas since gained #148 (the fast-uri Dependabot fix), so the stack branch is no longer a descendant. Both applied cleanly with no conflicts.SettingsView.tsx11,460 → 10,951 lines; thesettings/directory reaches its full 10 files (8 sections +types.ts+format.ts).Verification — re-run against current
main, not inheritedpnpm typecheck,pnpm lint, 441 unit tests — all cleanAvoiding the repeat
Future passes go straight to
mainone at a time. Stacking bought very little here and cost two passes' worth of confusion.🤖 Generated with Claude Code