SettingsView v2 — 1170 → 294 Lines via Phased Decomposition
- Version
- v5.0
- Date
- 2026-04-19
- Tier
- light
Closing audit finding UI-002: SettingsView.swift dropped 1170 → 294 lines (~75%) across 4 PRs (#122-#125) in a ~2-hour single-session decomposition. Pure structural refactor — zero new code, zero behaviour change, 9 visibility bumps, 8 new files. Second feature to ship concurrent case-study tracking from inception (after M-3).
- •No manual visual QA across the 5 detail screens. Behaviour preservation verified at the type level (same
*SettingsScreentypes, same coordinator wiring) but a tap-through pass would catch subtle SwiftUI rendering regressions if any. - •Pre-existing EncryptionService + KeychainHelper test failures (9 tests) reproduce on clean main. Not introduced by M-1; same simulator-keychain environment friction as M-3.
- •CI billing block in effect during M-1 — PRs #122/#123/#124 hit the GitHub Actions account spending limit; admin-overridden the merges. Same infrastructure friction since Sprint K.
- •The 294-line coordinator still embeds
summaryBadges()helpers (~50 lines) and deep-link routing destinations. UI-002 is closed at the file-size layer; finer extraction (M-1e) would be taste, not audit. - •M-1c was a judgment call: SettingsView.swift was 401 lines after M-1b (one over the 400 target). The right call was a clean coordinator at 294 lines, not "fail the threshold by one line". Audited as decision D-3 in the source case study.
How to read this case studyT1/T2/T3 · ledger · kill criterion▾
- T1Instrumented
- Numbers come from a machine-generated ledger or commit. Reproducible. Highest reader trust.
- T2Declared
- Numbers stated by a structured declaration (PRD, plan, frontmatter) but not directly measured.
- T3Narrative
- Estimates and observations from session memory. Useful for context; not citable as evidence.
- Ledger
- Where to verify the claim — a file path, GitHub issue, or backlog entry. Anything labelled
ledger:is the audit trail. - Kill criterion
- The pre-registered threshold under which this work would have been killed mid-flight. Not fired = work shipped without hitting the threshold.
- Deferred
- Items intentionally not closed in this version. Each cites the ledger that tracks remaining work.
SettingsView v2 — 1170 → 294 Lines via Phased Decomposition
M-1 closed audit finding UI-002 ("SettingsView.swift, 1170 lines, too many responsibilities"). The 1170-line file was already well-structured internally — five
private struct *SettingsScreen: Viewblocks called from anavigationDestinationswitch — so the work was mechanical-but-careful: extract each block to its own file, bumpprivate→ internal so the coordinator can still reach them, add aScreensPBXGroup toproject.pbxproj. Same again for shared scaffolds + form components in M-1b, and home-view sub-components in M-1c. Pure structural refactor; zero behaviour change.
What shipped
| PR | Phase | What | Lines moved |
|---|---|---|---|
| #122 | M-1a | 5 detail screens → Settings/v2/Screens/ | 521 |
| #123 | M-1b | Scaffolds + form components → Settings/v2/Components/ | 248 |
| #124 | M-1c | Home-view sub-components → Settings/v2/Components/SettingsHomeViews.swift | 107 |
| #125 | M-1d | Case study + monitoring entry + UI-002 closure | — |
Each PR was a single-direction structural change. Could revert any one without losing the others. Build + (Settings-related) tests green at every PR.
Numbers — before and after
| Metric | Before M-1 | After M-1a | After M-1b | After M-1c |
|---|---|---|---|---|
| SettingsView.swift lines | 1170 | 649 | 401 | 294 |
Files in Settings/v2/ | 1 | 6 | 8 | 9 |
| New PBXGroups | 0 | 1 (Screens) | 2 (+Components) | 2 |
What worked
- Plan doc with line-level inventory before starting.
docs/superpowers/plans/2026-04-19-m1-settings-v3-decomposition.mdmapped every section of the 1170-line file to either "Stay" or "Extract → file". Each of the 4 phases shipped within ±50% of estimate. - The original file was already well-structured. The 5 detail screens were 54-155 line
private structblocks with@EnvironmentObjectdeps. No interfaces had to be redesigned. - Sequential phases isolate risk. Each PR was a single-direction structural change; rollback is surgery, not amputation.
- Visibility bump is a one-line cost per dependency. 9 visibility bumps across 3 PRs. Each was a 1-character delete (
private); no fan-out. - Case study tracking concurrent with feature (second time). M-1d ships in the same session as M-1a/b/c. M-3 was the first feature to do this; M-1 confirms the pattern is reproducible.
What broke down
- Pre-existing test infrastructure failures (EncryptionService + KeychainHelper) on the simulator's keychain — verified pre-existing via
git stash+ re-run. Same environmental friction as M-3. - No manual visual QA across all 5 detail screens. Type-level behaviour preservation only.
- CI billing block continues — admin-overridden merges. Not an M-1 issue.
Lessons
- Mechanical extraction is fast when the source already has clear seams. The 5 detail screens already lived as
private structs with@EnvironmentObjectdeps. The work was moving files + visibility bumps + pbxproj edits — no interface redesign. 0.5 audit findings/hour vs. 1.2/hour for M-3 (which was content-additive); pure structural work pays a project.pbxproj tax that content-additive work skips. - One-line judgment calls don't deserve over-decomposition. M-1c was 1 line over the 400-line threshold after M-1b. A 100-line extraction "for the sake of 1 line" would have been overkill if the resulting coordinator wasn't the right size. Decision: extract the home views as a single file (conceptually a unit) and land at 294 lines. Right call documented; not a process violation.
- Concurrent case-study tracking is now reproducible. M-3 was the first feature to ship a case study in the same session as the feature itself. M-1 is the second. Going from "1 of 1 tries succeeded" to "2 of 2" elevates the pattern from anecdote to default.
Links
- Full upstream case study:
docs/case-studies/m-1-settings-decomposition-case-study.md - M-1 plan:
docs/superpowers/plans/2026-04-19-m1-settings-v3-decomposition.md - Predecessor: M-3 Design System Completion (closes DS-004 + DS-009 + DS-010)
- PRs: #122 · #123 · #124 · #125