The term/authority picker (#27, merged de035bd) is a searchable combobox that filters the full option list client-side (useTerms/useAuthorities load everything, cached 5 min). That's fine for the current small vocabularies, but degrades once a vocabulary has hundreds/thousands of terms (large payload, no server filtering). This was explicitly deferred from #27.
What to do
Backend: add debounced server-side search endpoints, e.g. GET /api/admin/vocabularies/{id}/terms?q=<text>&limit=<n> (search term_label.label, any lang, scoped to the vocabulary; ILIKE/trigram; return top-N) and extend GET /api/admin/authorities?kind=&q=<text>&limit=<n>. Empty q → first N. ViewInternal.
Frontend: have OptionsCombobox (or a server-backed variant) query the endpoint (debounced) via inputValue/onInputValueChange instead of loading the full list, for large vocabularies. Decide the client-vs-server threshold (or always-server).
Selected id → label resolution (the tricky part): when editing an object whose stored term/authority id isn't in the current (filtered/server) result set, the combobox still needs to display its label. Add a by-id lookup (GET .../terms/{term_id}, authorities/{id}) or include the selected id in results.
Keep the value = id contract + active-locale labels. Mind the bundle (object-form chunk).
Design note: docs/superpowers/specs/2026-06-06-searchable-term-authority-picker-design.md ("Out of scope → follow-up issue").
Deferred from #27 (client-side filtering shipped first; server-side search when a vocabulary genuinely grows large).
## Context
The term/authority picker (#27, merged `de035bd`) is a searchable combobox that filters the **full** option list **client-side** (`useTerms`/`useAuthorities` load everything, cached 5 min). That's fine for the current small vocabularies, but degrades once a vocabulary has hundreds/thousands of terms (large payload, no server filtering). This was explicitly deferred from #27.
## What to do
- **Backend:** add debounced server-side search endpoints, e.g. `GET /api/admin/vocabularies/{id}/terms?q=<text>&limit=<n>` (search `term_label.label`, any lang, scoped to the vocabulary; ILIKE/trigram; return top-N) and extend `GET /api/admin/authorities?kind=&q=<text>&limit=<n>`. Empty `q` → first N. `ViewInternal`.
- **Frontend:** have `OptionsCombobox` (or a server-backed variant) query the endpoint (debounced) via `inputValue`/`onInputValueChange` instead of loading the full list, for large vocabularies. Decide the client-vs-server threshold (or always-server).
- **Selected id → label resolution (the tricky part):** when editing an object whose stored term/authority id isn't in the current (filtered/server) result set, the combobox still needs to display its label. Add a by-id lookup (`GET .../terms/{term_id}`, `authorities/{id}`) or include the selected id in results.
- Keep the `value = id` contract + active-locale labels. Mind the bundle (object-form chunk).
## References
- `web/src/objects/options-combobox.tsx`, `web/src/objects/field-input.tsx`
- `web/src/api/queries.ts` (`useTerms`, `useAuthorities`)
- `crates/api/src/admin_vocab.rs` (`list_terms`), `crates/api/src/admin_authorities.rs` (`list_authorities`)
- Design note: `docs/superpowers/specs/2026-06-06-searchable-term-authority-picker-design.md` ("Out of scope → follow-up issue").
_Deferred from #27 (client-side filtering shipped first; server-side search when a vocabulary genuinely grows large)._
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Context
The term/authority picker (#27, merged
de035bd) is a searchable combobox that filters the full option list client-side (useTerms/useAuthoritiesload everything, cached 5 min). That's fine for the current small vocabularies, but degrades once a vocabulary has hundreds/thousands of terms (large payload, no server filtering). This was explicitly deferred from #27.What to do
GET /api/admin/vocabularies/{id}/terms?q=<text>&limit=<n>(searchterm_label.label, any lang, scoped to the vocabulary; ILIKE/trigram; return top-N) and extendGET /api/admin/authorities?kind=&q=<text>&limit=<n>. Emptyq→ first N.ViewInternal.OptionsCombobox(or a server-backed variant) query the endpoint (debounced) viainputValue/onInputValueChangeinstead of loading the full list, for large vocabularies. Decide the client-vs-server threshold (or always-server).GET .../terms/{term_id},authorities/{id}) or include the selected id in results.value = idcontract + active-locale labels. Mind the bundle (object-form chunk).References
web/src/objects/options-combobox.tsx,web/src/objects/field-input.tsxweb/src/api/queries.ts(useTerms,useAuthorities)crates/api/src/admin_vocab.rs(list_terms),crates/api/src/admin_authorities.rs(list_authorities)docs/superpowers/specs/2026-06-06-searchable-term-authority-picker-design.md("Out of scope → follow-up issue").Deferred from #27 (client-side filtering shipped first; server-side search when a vocabulary genuinely grows large).