Download the PHP package vortos/vortos-search without Composer
On this page you can find all versions of the php package vortos/vortos-search. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download vortos/vortos-search
More information about vortos/vortos-search
Files in vortos/vortos-search
Package vortos-search
Short Description Vortos Search — enterprise-grade, event-fed unified global search. One tenant-scoped, RLS-isolated search_document projection fed from domain events via a discoverable SearchableProjection contract (add a type = add one class). Database-agnostic driver abstraction (portable LIKE default, opt-in Postgres full-text + trigram fuzzy), permission- and owner-aware ranked query, Redis-cached, with backfill/rebuild. The app owns what is searchable and where results deep-link; the framework owns the engine.
License MIT
Informations about the package vortos-search
vortos-search
Enterprise-grade, event-fed global search for Vortos apps. One tenant-scoped, RLS-isolated
search_documents projection, fed from your domain events through a single discoverable
contract. Adding a searchable type is one class; new instances are indexed automatically
because they arrive on the events you already emit.
The framework owns the engine (matching, ranking, scoping, indexing, backfill). The app owns what is searchable and where each result deep-links — the framework never learns what an "application" is.
Why it exists
A hand-maintained search list rots the moment someone adds a feature. This package makes search a read-model off the event bus — the same pattern as the audit spine — so it stays correct by construction, rebuilds from scratch on demand, and scales independently of the write path.
Design at a glance
Scoping — two independent axes
| Axis | Column | Enforcement |
|---|---|---|
| Org | tenant_id |
WHERE tenant_id = … and Postgres row-level security (search:pg:install --rls). An org physically cannot read another org's rows. |
| Member | permission + owner_member_id |
Org-shared rows need the caller's permission (or none); personal rows (owner_member_id set) are visible only to that member. |
A SearchScope (tenant + memberId + permissions, or superuser) is mandatory to read — there
is no unscoped query, and the cache key folds the scope in so it can never become a bypass.
Database-agnostic driver
PortableLikeSearchDriver(default) — case-insensitiveLIKE, any SQL engine, no special index.PostgresFtsSearchDriver— weightedtsvector(titleA,subtitle/keywordsB,bodyC)word_similaritytrigram fuzzy fallback, ranked byts_rank_cd. Enable with->driver(SearchDriver::PostgresFts)and runvortos:search:pg:install.
Scoping, pagination and deep-links are identical across drivers — switching a driver changes
relevance only, never who can see what. Implement SearchIndexDriver (+ writer/reader) to plug
an external engine like OpenSearch/Meilisearch.
App integration (4 steps)
-
Make a type searchable — implement
SearchableProjection; it's auto-discovered: - Feed the bus — one thin Kafka handler calls
$applier->apply($event)on your indexing consumer group (owned by the app, so consumer/topic naming stays in app config). - Serve queries — a controller builds a
SearchScopefrom the authenticated principal and callsSearchQueryService::search(). - Backfill — implement
SearchBackfillSourceInterfaceper type; runvortos:search:rebuild.
Configuration — config/search.php (all optional)
Commands
vortos:search:pg:install [--rls|--no-rls]— Postgres extras (tsvector column + GIN + trigram + optional RLS). Idempotent.vortos:search:rebuild [--type=…] [--tenant=…] [--fresh]— (re)build the index from backfill sources.
Metrics
Spread SearchMetricDefinitions::all() into your metrics registry (e.g. config/metrics.php):
search_index_upsert_total, search_index_delete_total, search_query_total,
search_query_latency_seconds.
All versions of vortos-search with dependencies
psr/clock Version ^1.0
psr/log Version ^3.0
symfony/dependency-injection Version ^7.0 || ^8.0
vortos/vortos-foundation Version ^1.0