feat(filters+ui): per-element author/publisher filters, playlist toggles, Up Next API, reorder UI, dashboard badges
Phases 4 + 5 of the metadata overhaul (plan §4, §5) plus §3 handler wiring. Filters (§4.1): author_filter/publisher_filter now match per-element against the authors[]/publishers[] arrays — a co-authored book matches any one of its authors — with comma-joined params acting as OR-within-facet multi-select (string_to_array + cross unnest). Legacy single-value params unchanged on the wire; series/genre/language filters stay on their varchar columns; narrator filter already per-element. Collections API (§3.3-3.5): collection detail carries viewer + hide_finished into the listing query and exposes up_next (visible- library-enforced reading-queue head); PUT /api/collections/:id/items/order (owner-only, full-order rewrite); UpdateCollectionRequest gains hide_finished/show_up_next ([] string last-value-wins for the hidden-false-sibling checkbox pattern) merged server-side OVER stored view_settings so imported_from_series provenance survives edits; EditCollectionModal renders the toggles from view_settings. Dashboard (§5.5): sections JSON carries is_playlist/complete (dashboard.ts is the AGENTS-documented JSON-render exception; first paint stays templ). Fully-read playlists render '✓ Playlist complete' instead of an empty rail; imported playlists get a 📖 Playlist badge. Frontend: book detail shows subtitle + full authors + Explicit badge; edit modal gains subtitle, comma-separated authors/publishers (client- split to arrays exactly like narrators), step=any series number, explicit checkbox; collection book cards get playlist move ↑/↓ buttons persisting the full order via the reorder endpoint (templ partial re-render on failure — DOM order is client-local, API order is truth). AGENTS.md gotcha #3 amended per plan §3.7: user collections are dashboard sections by default; the show_on_dashboard premise is retired. Verified: full affected integration sweep green (pins widened for up_next/is_playlist/complete — changelog entries in docs/contract_pins.md); unit suite green; go build + templ + vite green.
This commit is contained in:
1 parent
1dbb0ce406
commit
f94e7472b4
20 files changed
+1711
-1339
No files matched your search
@@ -161,14 +161,19 @@ of a server bug: stop and flag the user.
|
||||
the cache stale until the next API-path write — never "preview"
|
||||
rule changes via psql and expect them applied (2026-10-14: a live
|
||||
curl test flip looked ignored until the API path was used).
|
||||
3. **User collections are not dashboard sections**: nothing sets
|
||||
collection show_on_dashboard for user rows, and GetDashboardSections
|
||||
skips empty user sections. Collection detail (JSON + SSR) must NOT
|
||||
route user rows through the dashboard-section path — a 7ce7321
|
||||
regression did exactly that (static detail without library_id
|
||||
returned zero books until 0a7fbd6). Only real system query types
|
||||
(continue-reading etc.) route there; `query_type='filter'` is the
|
||||
schema DEFAULT on every user row, not a query type.
|
||||
3. **User collections are not dashboard query types** (amended 2026-10-19,
|
||||
A2c): user collections ARE dashboard sections by default now —
|
||||
GetUserCollectionsForDashboard no longer gates on show_on_dashboard
|
||||
(which remains system-section provisioning state; hiding is
|
||||
dashboard-prefs `hidden_collections` territory). GetDashboardSections
|
||||
still skips genuinely empty user sections, but hide_finished
|
||||
collections emit a Complete section instead of vanishing. Collection
|
||||
detail (JSON + SSR) must still NOT route user rows through the
|
||||
dashboard-section path — a 7ce7321 regression did exactly that
|
||||
(static detail without library_id returned zero books until 0a7fbd6).
|
||||
Only real system query types (continue-reading etc.) route there;
|
||||
`query_type='filter'` is the schema DEFAULT on every user row, not a
|
||||
query type.
|
||||
4. **End-of-day arithmetic**: anchor the END bound to the START of the
|
||||
day, never to NOW(). `now.AddDate(0,0,1) − 1ns` carries this
|
||||
instant's clock time into tomorrow — a range "ending today"
|
||||
|
||||
Reference in new issue
Block a user