fix(support): problem reports arrived with a blank Library line (PP-5078) - #1454
fix(support): problem reports arrived with a blank Library line (PP-5078)#1454mauricecarrier7 wants to merge 1 commit into
Conversation
…078)
`generateBody` rendered `Library: \(accountsManager.currentAccount?.name ?? "")`.
`currentAccount` resolves through the library registry and is nil until that
registry has loaded the selected account, so a patron who reports a problem
before it settles sends a report whose Library line is empty — while the patron
ID, a separate per-library lookup, resolves normally.
Real ticket 18864 (1 Sep 2026, app 3.2.3) reached support as:
Palace Version: 3.2.3
Library:
Patron ID: 21467001510417
The agent triaging it recorded the summary as "Sign in prompt - no library?" —
the blank actively implied the patron had no library configured. The patron had
written that they were a member of Park Ridge Public Library.
The line is now produced by `libraryFieldValue(name:uuid:)`, which yields three
outcomes a reader can tell apart:
* a real name — the common case, passed through verbatim
* the identifier — the app knows WHICH library but cannot name it yet;
support can resolve a UUID, and cannot resolve a blank
* "(none selected)" — the app genuinely has no library
A blank could equally have meant the line was lost in mail transit. None of
these can. Whitespace-only names fall back too, since a space renders in the
email exactly like nothing at all.
Intermittent, not universal: of the recent problem reports sampled in HelpSpot,
most carried a library name and a minority did not, which is why this has been
easy to miss.
**Scope:** the Library line in the problem-report body, plus its tests. The
patron-ID resolution, the report's other fields, and registry loading are all
untouched.
**Not done — the XCTest suite was NOT run.** It could not be: on this branch
`xcodebuild` refuses with "an out-of-date resolved file was detected at
Package.resolved", a pre-existing condition of main's committed lockfile rather
than anything this change introduces, and forcing resolution instead pulls a
newer swift-toolkit that conflicts on sqlite.swift. CI runs on a clean
environment and is the verification of record here. What WAS verified locally is
the decision itself, executed standalone against all four cells: the old
expression returns an empty string for a nil name (the shipped defect,
reproduced), and each new cell returns what it should. That proves the logic,
not the wiring into `generateBody`.
**Not done:** no build-number bump. This is deliberate — bumping now would
presume this ships alone, and un-bumping after a merge is worse than adding it.
Bump `CURRENT_PROJECT_VERSION` (492 on main today) before cutting the build.
**Deferred:** develop has since extracted this into
`AccountsManager+ProblemReportContext`, where the name still comes from
`currentAccount?.name` while the patron ID comes from the requested library — so
develop additionally mislabels a report filed about library A while B is
selected. The forward-port needs to carry the fallback into that extraction
rather than apply this diff verbatim; the file's own header comment records the
current behaviour as an intentional replication of the pre-extraction code.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
🏗️ CodeAtlas Ledger Analysis✅ All Checks Passed♿ Accessibility (via AccessLint)
✅ No accessibility issues detected 🧪 Test Coverage (via QAAtlas)
🏛️ Architecture Analysis
🔍 Reachability Analysis
✅ No dead code detected 📊 0 files analyzed | 📦 Download Full Report Powered by CodeAtlas Ledger |
🧪 Unit Test Results📊 View Full Interactive Report ❌ 3 TESTS FAILED7425 tests | 7308 passed | 3 failed | 114 skipped | ⏱️ 18m 35s | 📊 98.4% | 📈 49.1% coverage Tests by Class — 838 classes, 3 with failures
Failed Tests (click to expand)📊 Testing Coverage BreakdownUnit Test Line Coverage (testable surfaces): 49.1% Total coverage incl. UI/lifecycle: 47.2% (18 files excluded from testable denominator — see
🔗 Interactive HTML Report | CI Run Details 📦 Downloadable Artifacts
|
|
Superseded by #1455, which carries this exact commit — Retargeted from 3.2.3 to 3.2.4 because the hotfix grew to two fixes, and build 493 turned out not to be free ( Nothing is lost by closing this: the PP-5078 fix, its producer test, and the mutation verification all live in #1455 unchanged. This branch's Closing to keep one hotfix in flight rather than two against |
Fixes PP-5078. Cut from
main(3.2.3, build 492).What
generateBodyrenderedLibrary: \(accountsManager.currentAccount?.name ?? "").currentAccountresolves through the library registry and is nil until that registry has loaded the selected account — so a patron reporting a problem before it settles sends a report with an empty Library line, while the patron ID (a separate per-library lookup) resolves normally.Real ticket 18864 (1 Sep 2026, app 3.2.3) reached support as:
The agent triaging it recorded the summary as "Sign in prompt - no library?" — the blank actively implied the patron had no library configured. The patron had written that they were a member of Park Ridge Public Library.
Fix
libraryFieldValue(name:uuid:)yields three outcomes a reader can tell apart:(name unavailable — urn:uuid:…)(none selected)A blank could equally have meant the line was lost in mail transit. None of these can. Whitespace-only names fall back too, since a space renders identically to nothing.
Intermittent, not universal — of the recent problem reports sampled in HelpSpot, most carried a name and a minority did not, which is why it has been easy to miss.
The XCTest suite could not be run on this branch.
xcodebuildfails before compiling:This is F-INFRA-006, already recorded as high-severity and verified during the 3.3.0 regression: the shipped 3.2.3 tag no longer builds from a clean checkout.
mainpins swift-toolkit atexactVersion 3.9.0, so the fork's dependencies appear to have changed under a fixed tag.That is a blocker for shipping any 3.2.3 hotfix, this one included. It is not caused by this change and this change cannot fix it.
What was verified locally: the decision itself, executed standalone across all four cells — the old expression returns an empty string for a nil name (the shipped defect, reproduced), and each new cell returns what it should. That proves the logic, not its wiring into
generateBody. Four XCTest cases are included and will run once the build is unblocked.Also
CURRENT_PROJECT_VERSION(492 today) before cutting.AccountsManager+ProblemReportContext, where the name still comes fromcurrentAccount?.namewhile the patron ID comes from the requested library — so develop additionally mislabels a report filed about library A while B is selected.🤖 Generated with Claude Code