feat(filter): label endpoint names id values for client-held trees
The SSR embed (65f257f3) covers trees the server renders; one path
still fell through to the flawed fallback — applying a SAVED filter
from a cold bookshelf. That page was rendered before any filter
existed (nothing embedded), and the fallback reused the suggest facet,
whose rows are MEDIA-CONSTRAINED: "feed in [A,B,C] AND title contains
Chapter" labeled only the feeds with a matching episode (the exact
live repro from the original bug report).
- GET /api/filter/labels?field=X&ids=a,b,c resolves names straight
from the entity tables via the shared ResolveFieldLabels core
(extracted from FilterTreeLabels): no media join, no tree
constraint. RLS/visibility ride the request identity — a
zero-episode subscribed feed resolves its title (pinned; the facet
path structurally could not), an unsubscribed feed id stays unnamed
(pinned), non-id fields are 400 (pinned), ids cap at 100.
- Client: resolveIdLabels/resolveLabelsAsync use ONLY the endpoint;
the quiet suggest-fetch mode is deleted (its only caller was the
flawed fallback). The saved-filter apply flow resolves through the
endpoint and rebuilds the chips bar when labels land — chips render
raw ids only while the round trip is in flight, never stuck.
- 188 web tests green; Go endpoint pins + filter/episode slices green;
contract_pins documents the endpoint and the fallback removal.
This commit is contained in:
1 parent
a20741ccc9
commit
96a40f7d88
8 files changed
+274
-78
No files matched your search
@@ -287,6 +287,15 @@ Alpine.data("bookshelf", () => ({
|
||||
// Rehydrate the rule-builder tree from the refilled form
|
||||
builderData()?.hydrateFromForm();
|
||||
|
||||
// Cold-cache labels (2026-11-01): this page was rendered BEFORE
|
||||
// the filter existed, so the SSR embed has no names for the saved
|
||||
// filter's ids — resolve through the label endpoint, then rebuild
|
||||
// the chips (without the refresh they'd show raw ids until the
|
||||
// next grid event).
|
||||
void builderData()
|
||||
?.resolveLabelsAsync()
|
||||
.then(() => refreshFilterChips());
|
||||
|
||||
// Trigger HTMX to apply the filter by submitting the form
|
||||
window.htmx.trigger(filterForm, "submit");
|
||||
|
||||
|
||||
Reference in new issue
Block a user