Files
bookhoard/web/src/main.ts
T
John O'Keefe 4ee24e7152 feat(filters): the rule builder — composed engines over the field registry (faceted plan Phase 9)
- Field registry (services/filter_registry.go): ~55 typed fields —
  every book column, file/lifecycle facts, the three HOLDING
  STRUCTURES (library, collections with excluded-aware membership,
  series with FULL primary+alternate_info membership), and the whole
  user-relative class (status, progress, last read, my rating, review,
  notes/highlights presence, note/highlight text, time spent, pages
  read, collections, added by) reading the VIEWER's rows. Operators
  are typed constants; negation is an operator.
- Composed engines (services/filter_query.go): one Go clause builder
  over raw pgx feeds the search (identical SearchMediaItemsUnifiedRow
  shape), the field-aware suggestions, and a true-COUNT live count.
  Mandatory WHERE head everywhere (family lens + integrity facts).
  Values are always bound parameters — no user string reaches a
  field/operator position, ever.
- Wire: the qf JSON param (validated strictly — unknown
  fields/operators/malformed values are 400); qf wins over flat params
  on hand-crafted URLs; flat deep links keep working unchanged.
- Endpoints: GET /api/media-items/filter-count (live count);
  field-values autocomplete upgraded in place — any registry field
  key, qf binds the OTHER rules (symmetric under-filter suggestions,
  zero-match values never offered); classic six without a tree keep
  their static pinned contract.
- UI: the drawer becomes the rule builder — the ONLY filter UI (templ
  markup, Alpine tree state, sanctioned island; grouped field menus,
  operator menus with red negations, field-aware value menus, live
  count, chips per rule with red negations, URL rehydration, smart
  serialization flat-when-simple else qf).
- Tests: composed semantics (AND/OR/negation/nesting/enums/bools/
  numbers/dates/empty), every user-relative field class with the
  my-data weld (two readers, different worlds), note-text substring
  pin (catharsis ≠ Carthage), family lens (hidden libraries nowhere,
  403s), suggestion-under-rules exactness, qf validation + precedence,
  flat-vs-tree equivalence; registry completeness unit test.
2026-10-20 14:49:50 -04:00

45 lines
942 B
TypeScript

import "./alpine";
import { Alpine } from "./alpine";
import "./admin";
import "./audio";
import "./api";
import "./api-explorer";
import "./api-explorer-docs";
import "./bookPicker";
import "./bookshelf";
import "./filter_builder";
import "./book-detail";
import "./collection-rules";
import "./collections";
import "./conflicts";
import "./custom-section-builder";
import "./dashboard";
import "./device-management";
import "./docs";
import "./dom";
import "./events";
import "./header";
import "./index";
import "./library-switcher";
import "./linking";
import "./login";
import "./password_validation";
import "./profile";
import "./profile-modal";
import "./queue";
import "./register";
import "./search";
import "./series";
import "./setup";
import "./stats";
import "./storage";
import "./theme";
import "./toast";
import "./toast-error";
import "./unlinked_books";
import "./websocket";
import "./woodPanelingInit";
Alpine.start();