package index import ( "fmt" "time" ) // MailDocument is the indexed representation of a stored email. type MailDocument struct { ID string From string To string Subject string Body string AttachNames string HasAttachment bool Date time.Time Size int64 TenantID *int64 // nil = global / superadmin context } // SearchRequest specifies search parameters. type SearchRequest struct { Query string From string To string OwnEmail string DateFrom *time.Time DateTo *time.Time HasAttachment *bool // nil=no filter, true=only with, false=only without LabelID *int64 `json:"label_id,omitempty"` // PROJ-9: post-filter by label Sort string // "relevance", "date_asc", "date_desc" (default: date_desc) PageSize int Page int } // Hit is a single search result. type Hit struct { ID string `json:"id"` Score float64 `json:"score"` } // SearchResult holds paginated search results. type SearchResult struct { Total int Hits []Hit } // Indexer is the interface for full-text email indexing. type Indexer interface { IndexSync(doc MailDocument) error Search(req SearchRequest) (*SearchResult, error) Delete(id string) error Close() error } // TenantIndexer manages per-tenant Indexer instances. // Implemented by ManticoreTenantManager (primary) and TenantIndexManager (legacy Xapian). type TenantIndexer interface { ForTenant(tenantID *int64) Indexer Global() Indexer Close() error } // New creates an Indexer for the specified backend. // Deprecated: use NewManticoreTenantManager instead. func New(dir string, batchSize int, backend string) (Indexer, error) { switch backend { case "xapian": return newXapian(dir) default: return nil, fmt.Errorf("unknown index backend: %q (use manticore via NewManticoreTenantManager)", backend) } }