import type { EntityId } from '@open-mercato/shared/modules/entities' import type { SearchResultPresenter, SearchResultLink, SearchFieldPolicy, } from '@open-mercato/shared/modules/search' import type { EncryptionMapEntry } from '../lib/field-policy' // ============================================================================= // Driver Identifiers // ============================================================================= export type FullTextSearchDriverId = | 'meilisearch' | 'algolia' | 'elasticsearch' | 'typesense' | (string & Record) // ============================================================================= // Document Types (for indexing) // ============================================================================= export type FullTextSearchDocument = { recordId: string entityId: EntityId tenantId: string organizationId?: string | null fields: Record presenter?: SearchResultPresenter url?: string links?: SearchResultLink[] } // ============================================================================= // Query Types // ============================================================================= export type FullTextSearchQuery = { tenantId: string organizationId?: string | null organizationIds?: string[] | null entityTypes?: EntityId[] limit?: number offset?: number } // ============================================================================= // Result Types // ============================================================================= export type FullTextSearchHit = { recordId: string entityId: EntityId score: number organizationId?: string | null presenter?: SearchResultPresenter url?: string links?: SearchResultLink[] metadata?: Record } export type DocumentLookupKey = { entityId: EntityId recordId: string } export type IndexStats = { numberOfDocuments: number isIndexing: boolean fieldDistribution: Record } // ============================================================================= // Driver Configuration // ============================================================================= export type FullTextSearchDriverConfig = { encryptionMapResolver?: (entityId: EntityId) => Promise fieldPolicyResolver?: (entityId: EntityId) => SearchFieldPolicy | undefined defaultLimit?: number } // ============================================================================= // Driver Interface // ============================================================================= export interface FullTextSearchDriver { readonly id: FullTextSearchDriverId // Lifecycle methods (mandatory) ensureReady(): Promise isHealthy(): Promise // Core operations (mandatory) search(query: string, options: FullTextSearchQuery): Promise index(doc: FullTextSearchDocument): Promise delete(recordId: string, tenantId: string): Promise // Batch operations (optional) bulkIndex?(docs: FullTextSearchDocument[]): Promise purge?(entityId: EntityId, tenantId: string, organizationId?: string | null): Promise // Index management (optional) clearIndex?(tenantId: string): Promise recreateIndex?(tenantId: string): Promise // Document retrieval for enrichment (optional) getDocuments?( ids: DocumentLookupKey[], tenantId: string ): Promise> // Stats/admin (optional) getIndexStats?(tenantId: string): Promise getEntityCounts?(tenantId: string): Promise | null> }