fix(books): remove redundant Shelf Status facet from filter drawer [shot:filter-drawer] (bookshelf-onx3v) #1215
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "bd-bookshelf-onx3v"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
FacetShelfStatusCountsdelegated toFacetStatusCountsandbuildShelfStatusGroupliterally calledbuildStatusGroup, producing the same SQL predicate. The "Shelf Status" facet was entirely redundant.fshelfstatusURL param,FacetShelfStatuses/ShelfStatusesfields from all structs,FacetShelfStatusCountsfunction,buildShelfStatusGroup, the template section, and all JS references (fshelfstatus,FACET_PARAMSentry,_paramNamemapping).Before: Filter drawer had "Read Status" and "Shelf Status" sections showing identical UNREAD/READING/FINISHED counts.
After: Filter drawer has only "Read Status" — the authoritative per-user read status filter.
Test plan
make testpasses — all unit tests greenmake buildpasses — no compile errorsmake lintpasses — no new lint issues in this worktreeinternal/bookstests: removedFacetShelfStatusCounts,FacetShelfStatuses,ShelfStatuses,fshelfstatustest cases; kept all other facet tests"maps shelfstatus → fshelfstatus"test andfshelfstatus=UNREADfrom the all-params test[shot:filter-drawer]title marker using existing filter drawer journeyCloses bead bookshelf-onx3v on merge.
Filter Drawer screenshot (filter-drawer-genre-expanded)
Books list filter drawer — Genre facet expanded, filter applied.
Filter Drawer screenshot (filter-drawer-cross-facet-series-narrowed)
Books list filter drawer — Genre facet expanded, filter applied.
Filter Drawer screenshot (filter-drawer-fantasy-filtered)
Books list filter drawer — Genre facet expanded, filter applied.
Filter Drawer screenshot (filter-drawer-range-expanded)
Books list filter drawer — Genre facet expanded, filter applied.
Filter Drawer screenshot (filter-drawer-range-filtered)
Books list filter drawer — Genre facet expanded, filter applied.
Filter Drawer screenshot (filter-drawer-value-search)
Books list filter drawer — Genre facet expanded, filter applied.
Filter Drawer screenshot (filter-drawer-chips-combinator)
Books list filter drawer — Genre facet expanded, filter applied.
Filter Drawer screenshot (filter-drawer-chip-removed)
Books list filter drawer — Genre facet expanded, filter applied.
Filter Drawer screenshot (filter-drawer-shelf-open)
Books list filter drawer — Genre facet expanded, filter applied.
Filter Drawer screenshot (filter-drawer-shelf-filtered)
Books list filter drawer — Genre facet expanded, filter applied.
Filter Drawer screenshot (filter-drawer-character-filtered)
Books list filter drawer — Genre facet expanded, filter applied.
Filter Drawer screenshot (filter-drawer-chips-combinator)
Books list filter drawer — Genre facet expanded, filter applied.
Filter Drawer screenshot (filter-drawer-genre-expanded)
Books list filter drawer — Genre facet expanded, filter applied.
Filter Drawer screenshot (filter-drawer-chip-removed)
Books list filter drawer — Genre facet expanded, filter applied.
Filter Drawer screenshot (filter-drawer-fantasy-filtered)
Books list filter drawer — Genre facet expanded, filter applied.
Filter Drawer screenshot (filter-drawer-range-expanded)
Books list filter drawer — Genre facet expanded, filter applied.
Filter Drawer screenshot (filter-drawer-range-filtered)
Books list filter drawer — Genre facet expanded, filter applied.
Filter Drawer screenshot (filter-drawer-shelf-open)
Books list filter drawer — Genre facet expanded, filter applied.
Filter Drawer screenshot (filter-drawer-shelf-filtered)
Books list filter drawer — Genre facet expanded, filter applied.
Filter Drawer screenshot (filter-drawer-character-filtered)
Books list filter drawer — Genre facet expanded, filter applied.
Filter Drawer screenshot (filter-drawer-value-search)
Books list filter drawer — Genre facet expanded, filter applied.
Filter Drawer screenshot (filter-drawer-cross-facet-series-narrowed)
Books list filter drawer — Genre facet expanded, filter applied.
UI Review — bookshelf-onx3v (PR #1215)
Reviewed rendered screenshots (second batch, comments 14922–14934) and the diff against
main.Screenshot observations
filter-drawer-shelf-open — Drawer open with Shelf facet expanded. Panel order reads: Read Status → File Format → Category → Author → Series → Publisher → Language → Tag → Rating → Page Count → Published Year → Metadata Score → Library → Shelf (expanded, MySuperShelf (2)) → Age Rating → Content Rating. No "Shelf Status" panel present. No orphaned heading, empty section, stray divider, or spacing anomaly where the panel used to sit. The Shelf→Age Rating transition is clean.
filter-drawer-genre-expanded — Category expanded. "Shelf Status" remains absent. Panel spacing and typography are visually uniform throughout. Shelf is visible (collapsed) at the foot of the drawer with no gap artifacts.
filter-drawer-chips-combinator — Active fantasy filter chip, Category expanded. Panel structure unchanged and correct. No double Read Status entry.
Source cross-check
Diff removes exactly:
<div class="facet-category" data-facet="shelfstatus">…Shelf Status…</div>block fromtemplates/pages/books_index.html{{range .Filter.FacetShelfStatuses}}&fshelfstatus=…{{end}}from the two URL-building locations (infinite-scroll sentinel + load-more link)params.delete("fshelfstatus"), the"fshelfstatus"entry fromFACET_PARAMS, and thefacet === "shelfstatus"mapping branch infilter_drawer_controller.jsNo inline
style=introduced. No bespoke classes introduced. All retained facet panels continue to use the existing canonicalfacet-category/facet-category-toggle/facet-valuesclasses. No CSS changes in this PR.Findings
None.
REVIEW VERDICT: 0 blocker, 0 major, 0 minor
Review: Remove Duplicate Shelf Status Facet (bookshelf-onx3v)
Verification Results
1. Removal Completeness ✓
FacetShelfStatusesfield removed from Filter struct (books.go:171-176)ShelfStatusesfield removed from ActiveFacets struct (books.go:315)FacetShelfStatusCounts()function completely removed (facet_store.go:397-420)buildShelfStatusGroup()function completely removed (store.go:841-843)fshelfstatusparam validation removed (facet_handler.go:365-367)shelfstatusfacet mapping removed from wire (wire.go:893)fshelfstatusremoved2. Duplicate Verification ✓
Confirmed
buildShelfStatusGroupwas identical tobuildStatusGroup:100% duplicate logic — no user-facing distinction from regular Read Status facet.
3. Backward Compatibility (URL Degradation) ✓
fshelfstatus=...params will degrade gracefullyvalidateFacetParams()only processes explicitly listed param names; unknown params are silently ignored (no 400 error)4. Other Facets Unaffected ✓
FacetShelves(shelf membership filter) remains intact and functionalFacetStatuses(read status facet) unchangedbookFilterNeedsUBP()correctly updated to exclude FacetShelfStatuses check5. Test Updates Correct ✓
Removed (appropriately):
Retained & Passing:
6. Comment Consistency ✓
Stale reference updated in facet_handler.go:356:
Summary
This is a surgical removal of a 100% redundant facet. The logic was identical to the global Read Status facet; the shelf-status-specific wrapper only added shelf-context gating (return empty if no shelf selected). With that gate removed, the facet is just a duplicate UI control for the same predicate. The removal is complete, consistent, correctly tested, and backward-compatible.
REVIEW VERDICT: 0 blocker, 0 major, 0 minor
Security Review — PR #1215 (bd-bookshelf-onx3v)
Scope: removal of the redundant "Shelf Status" facet (
fshelfstatusparam /FacetShelfStatuses/FacetShelfStatusCounts/buildShelfStatusGroup) across Go, template, and JS layers.Multi-user scoping — intact. The removed
FacetShelfStatusCountswas a thin wrapper delegating toFacetStatusCounts(identical per-useruser_id/userLibraryIDsscoping); it added no unique scoping clause. The remaining facets keep their scoping:FacetHandlerstill resolvesuserLibraryIDsviaresolveLibraryIDs(userID, ...)(facet_handler.go:77) fail-closed, and the shelf facet retains its ownership predicatebuildShelfGroup(names, userID)(store.go) plus cross-facetbuildCrossFacetStatusGroup(..., StatusUserID)/buildShelfGroup(..., ShelvesUserID). The removal drops only the duplicate status predicate, not any scoping clause.Leftover
fshelfstatusparam — safe.validateFacetParamsno longer readsq["fshelfstatus"], so on/booksthe param is now silently ignored (standard Go — unread query params never trigger a query or error). On/books/facets, an unknown?facet=shelfstatushits the guard at facet_handler.go:72 (facet != "status" && rangeCounts[facet]==nil && userRangeCounts[facet]==nil) → returnsErrValidation(400). No unscoped query, no existence/error leak.Injection surface — unchanged. Remaining param parsing/validation (allowlist for
fstatus/fformat, max-count/max-length caps for free-text facets,validateValueSearch) is untouched. No new dynamic SQL.Ownership / shelf-visibility — no check removed.
FacetShelfCounts(with itsshelf.user_id = userIDjoin) remains wired (wire.go). Only the read-status duplicate was removed.Removal is symmetric and complete across all layers (Filter, ActiveFacets, params structs, validation, cross-facet builder, predicate builder, wire map, JS controller, template, tests);
git grepfinds no danglingshelfstatus/FacetShelfStatusesreferences in production code.REVIEW VERDICT: 0 blocker, 0 major, 0 minor
e49bcefe28168f8a0d86Filter Drawer screenshot (filter-drawer-shelf-open)
Books list filter drawer — Genre facet expanded, filter applied.
Filter Drawer screenshot (filter-drawer-genre-expanded)
Books list filter drawer — Genre facet expanded, filter applied.
Filter Drawer screenshot (filter-drawer-shelf-filtered)
Books list filter drawer — Genre facet expanded, filter applied.
Filter Drawer screenshot (filter-drawer-fantasy-filtered)
Books list filter drawer — Genre facet expanded, filter applied.
Filter Drawer screenshot (filter-drawer-character-filtered)
Books list filter drawer — Genre facet expanded, filter applied.
Filter Drawer screenshot (filter-drawer-range-expanded)
Books list filter drawer — Genre facet expanded, filter applied.
Filter Drawer screenshot (filter-drawer-range-filtered)
Books list filter drawer — Genre facet expanded, filter applied.
Filter Drawer screenshot (filter-drawer-chips-combinator)
Books list filter drawer — Genre facet expanded, filter applied.
Filter Drawer screenshot (filter-drawer-chip-removed)
Books list filter drawer — Genre facet expanded, filter applied.
Filter Drawer screenshot (filter-drawer-cross-facet-series-narrowed)
Books list filter drawer — Genre facet expanded, filter applied.
Filter Drawer screenshot (filter-drawer-value-search)
Books list filter drawer — Genre facet expanded, filter applied.