app.services.search¶
Read-only catalog search.
Takes a CatalogStore (already inside a unit
of work opened by the caller) plus plain values, and returns plain
dataclasses; nothing here imports FastAPI or a source adapter. Routers
convert the results with SomeSchema.model_validate(value) (the
schemas declare from_attributes=True).
Derived status on search results. Search list items do not carry
the relationship-derived display status: computing it would require
building the full relationship index
(app.services.record_relationships) on every search request. It
is only available on the detail endpoint. Documented as an open item
for the frontend and for phase 09.
Record type. RecordTypeFilter selects decisions (the
default), errata, or both; it is pushed into SQL like every other
filter and combines with them (including needs_approval).
Sort order. resolve_sort() owns the default: relevance
when a non-blank query is set, otherwise title; an explicit
relevance without a query falls back to title (there is no
rank to order by). recent orders by record.updated_at, which
moves only when the content digest changes (last_seen_at is the
poll heartbeat), newest first. Every order ends with title and id, so
pages are stable.
Erratum target titles. An erratum hit carries the title of the
decision it corrects (erratum_for_title). The targets of all
erratum hits of the page are read with one query
(list_published_by_uuid()) and
resolved with the same rules as the detail page’s erratum_for
(RelationshipIndex: published rows,
same project first, ambiguous -> no title). The lookup is total: the
corrects link is selected by type, an unresolved or self-targeting
link simply yields no title. Targets are not restricted to decisions,
so an erratum of an erratum shows the corrected erratum’s title, as
its detail page does (where erratum_target_is_erratum flags it).
Public API: RecordTypeFilter, IssueCounts,
CatalogSearchItem, CatalogSearchPage,
resolve_sort(), search_records().
- class app.services.search.CatalogSearchItem(*, id, title, source_id, project, path, ref, kind, record_kind, approval_state, approvable, issue_counts, erratum_for_title)¶
Bases:
objectOne search result row.
- Parameters:
id (
UUID) – Record id.title (
str) – Display title.source_id (
str) – Registration id.project (
str) – Project path.path (
str) – File path inside the project.ref (
str) – Branch/ref of the content.kind (
RecordState) – Published or candidate.record_kind (
RecordKind) – Decision or erratum.approval_state (
ApprovalStateCode) – Approval state of the current digest.approvable (
bool) – Whether the content can be decided at all (same rule as the record detail,app.services.approval_view.is_approvable()).issue_counts (
IssueCounts) – Stored validation issue counts.erratum_for_title (
str|None) – For an erratum, the title of the decision it corrects, when that resolves.
- kind: RecordState¶
- record_kind: RecordKind¶
- approval_state: ApprovalStateCode¶
- issue_counts: IssueCounts¶
- class app.services.search.CatalogSearchPage(*, items, total, page, page_size)¶
Bases:
objectOne page of search results.
- Parameters:
- items: tuple[CatalogSearchItem, ...]¶
- class app.services.search.IssueCounts(*, error, warning)¶
Bases:
objectStored-issue counts of one record, by severity.
- Parameters:
- class app.services.search.RecordTypeFilter(*values)¶
Bases:
StrEnumWhich record kinds a search returns.
- DECISION = 'decision'¶
- ERRATUM = 'erratum'¶
- ALL = 'all'¶
- app.services.search.resolve_sort(sort, query)¶
Apply the default sort and the no-query fallback.
- Parameters:
sort (
SearchSort|None) – Requested order, orNonefor the default.
- Return type:
- Returns:
relevanceortitleby default (with / without a non-blank query);titleforrelevancewithout a query; otherwise sort itself.
- app.services.search.search_records(store, *, query, source_id, project, kind, page, page_size, policy, needs_approval=False, record_type=RecordTypeFilter.DECISION, sort=None)¶
Search the catalog with the Phase 1 filters.
- Parameters:
store (
CatalogStore) – Store of the caller’s unit of work.query (
str|None) – Free text, orNone/blank for all records.source_id (
str|None) – Restrict to one registration, orNone.kind (
RecordState|None) – Restrict to published or candidate, orNone.page (
int) – 1-based page number.page_size (
int) – Page size, 1 toMAX_PAGE_SIZE.needs_approval (
bool) – Only records whose current content does not satisfy the policy (pending, rejected, changed since acceptance, policy missing); evaluated in SQL by the store.record_type (
RecordTypeFilter) – Decisions (default), errata, or both.sort (
SearchSort|None) – Result order, orNonefor the default (seeresolve_sort()).
- Return type:
- Returns:
The page.
- Raises:
ValueError – If page or page_size is out of bounds.