domain

package
v0.2.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 19, 2026 License: Apache-2.0 Imports: 7 Imported by: 0

Documentation

Index

Constants

View Source
const (
	ScopeMCPSearch      = "mcp:search"
	ScopeMCPDocRead     = "mcp:documents:read"
	ScopeMCPSourcesList = "mcp:sources:list"
)

MCP Scope constants

View Source
const (
	AccessTokenTTL       = 15 * time.Minute
	RefreshTokenTTL      = 30 * 24 * time.Hour // 30 days
	AuthorizationCodeTTL = 10 * time.Minute
)

Token configuration constants

Variables

View Source
var (
	// ErrNotFound indicates the requested resource was not found
	ErrNotFound = errors.New("not found")

	// ErrAlreadyExists indicates the resource already exists
	ErrAlreadyExists = errors.New("already exists")

	// ErrInvalidInput indicates the input is invalid
	ErrInvalidInput = errors.New("invalid input")

	// ErrUnauthorized indicates authentication failed or missing
	ErrUnauthorized = errors.New("unauthorized")

	// ErrForbidden indicates the user lacks permission for this action
	ErrForbidden = errors.New("forbidden")

	// ErrSyncInProgress indicates a sync is already running
	ErrSyncInProgress = errors.New("sync already in progress")

	// ErrConnectorNotFound indicates the connector type is not registered
	ErrConnectorNotFound = errors.New("connector not found")

	// ErrTokenExpired indicates the auth token has expired
	ErrTokenExpired = errors.New("token expired")

	// ErrTokenInvalid indicates the auth token is malformed or invalid
	ErrTokenInvalid = errors.New("token invalid")

	// ErrSessionNotFound indicates the session does not exist
	ErrSessionNotFound = errors.New("session not found")

	// ErrInvalidCredentials indicates wrong email/password combination
	ErrInvalidCredentials = errors.New("invalid credentials")

	// ErrInvalidProvider indicates an unknown AI provider was specified
	ErrInvalidProvider = errors.New("invalid provider")

	// ErrServiceUnavailable indicates the AI service could not be reached
	ErrServiceUnavailable = errors.New("service unavailable")

	// ErrUnsupportedProvider indicates the connector provider type is not supported
	ErrUnsupportedProvider = errors.New("unsupported provider")

	// ErrUnsupportedAuthMethod indicates the authentication method is not supported
	ErrUnsupportedAuthMethod = errors.New("unsupported auth method")

	// ErrConnectionNotFound indicates the connector connection was not found
	ErrConnectionNotFound = errors.New("connection not found")

	// ErrInUse indicates the resource is in use and cannot be deleted
	ErrInUse = errors.New("resource in use")

	// ErrInvalidClient indicates the client authentication failed
	ErrInvalidClient = errors.New("invalid client")

	// ErrInvalidGrant indicates the authorization grant is invalid, expired, or revoked
	ErrInvalidGrant = errors.New("invalid grant")

	// ErrInvalidScope indicates the requested scope is invalid or unauthorized
	ErrInvalidScope = errors.New("invalid scope")

	// ErrExpiredCode indicates the authorization code has expired
	ErrExpiredCode = errors.New("authorization code expired")

	// ErrCodeAlreadyUsed indicates the authorization code has already been used
	ErrCodeAlreadyUsed = errors.New("authorization code already used")

	// ErrInvalidRedirectURI indicates the redirect URI does not match registered URIs
	ErrInvalidRedirectURI = errors.New("invalid redirect uri")

	// ErrUnsupportedGrantType indicates the grant type is not supported
	ErrUnsupportedGrantType = errors.New("unsupported grant type")

	// ErrUnsupportedResponseType indicates the response type is not supported
	ErrUnsupportedResponseType = errors.New("unsupported response type")

	// ErrInvalidCodeChallenge indicates the PKCE code challenge is invalid
	ErrInvalidCodeChallenge = errors.New("invalid code challenge")

	// ErrTokenRevoked indicates the token has been revoked
	ErrTokenRevoked = errors.New("token revoked")

	// ErrRateLimitExceeded indicates the LLM service rate limit was exceeded
	ErrRateLimitExceeded = errors.New("rate limit exceeded")

	// ErrContextLengthExceeded indicates the input exceeds the LLM's context window
	ErrContextLengthExceeded = errors.New("context length exceeded")

	// ErrInvalidModel indicates the specified model is not available or supported
	ErrInvalidModel = errors.New("invalid model")
)

Domain errors - used across all layers

DefaultMCPScopes contains the default scopes for MCP clients

Functions

func GenerateID

func GenerateID() string

GenerateID creates a unique random ID.

func MatchesMimePattern added in v0.2.1

func MatchesMimePattern(mimeType string, pattern string) bool

MatchesMimePattern checks if a MIME type matches a pattern. Supports both exact matches (e.g., "image/png") and wildcard matches (e.g., "image/*"). The pattern is case-insensitive.

Examples:

  • MatchesMimePattern("image/png", "image/*") returns true
  • MatchesMimePattern("image/png", "image/png") returns true
  • MatchesMimePattern("image/png", "text/*") returns false
  • MatchesMimePattern("text/plain", "text/plain") returns true
  • MatchesMimePattern("application/json", "application/*") returns true

func PlatformDisplayName added in v0.2.1

func PlatformDisplayName(platform PlatformType) string

func ShouldExcludeMimeType added in v0.2.1

func ShouldExcludeMimeType(mimeType string, exclusionPatterns []string) bool

ShouldExcludeMimeType checks if a MIME type should be excluded based on a list of patterns. Returns true if the MIME type matches any of the exclusion patterns.

Types

type AIModelInfo

type AIModelInfo struct {
	ID         string `json:"id"`                   // Model identifier (e.g., "text-embedding-3-small")
	Name       string `json:"name"`                 // Display name
	Dimensions int    `json:"dimensions,omitempty"` // For embedding models only
}

AIModelInfo describes a specific model offered by a provider

type AIProvider

type AIProvider string

AIProvider identifies the AI/embedding provider

const (
	AIProviderOpenAI    AIProvider = "openai"
	AIProviderAnthropic AIProvider = "anthropic"
	AIProviderOllama    AIProvider = "ollama"
	AIProviderCohere    AIProvider = "cohere"
	AIProviderVoyage    AIProvider = "voyage"
)

func (AIProvider) IsValid

func (p AIProvider) IsValid() bool

IsValid returns true if this is a known provider

func (AIProvider) RequiresAPIKey

func (p AIProvider) RequiresAPIKey() bool

RequiresAPIKey returns true if this provider requires an API key

type AIProviderInfo

type AIProviderInfo struct {
	ID              string        `json:"id"`                    // Provider identifier (matches AIProvider)
	Name            string        `json:"name"`                  // Display name
	Models          []AIModelInfo `json:"models"`                // Available models
	RequiresAPIKey  bool          `json:"requires_api_key"`      // Whether API key is needed
	RequiresBaseURL bool          `json:"requires_base_url"`     // Whether base URL is needed (e.g., Ollama)
	APIKeyURL       string        `json:"api_key_url,omitempty"` // URL to get API key
}

AIProviderInfo provides metadata about an AI provider

type AISettings

type AISettings struct {
	TeamID    string            `json:"team_id"`
	Embedding EmbeddingSettings `json:"embedding"`
	LLM       LLMSettings       `json:"llm"`
	UpdatedAt time.Time         `json:"updated_at"`
}

AISettings holds AI service configuration (embedding and LLM) This can be updated at runtime via API

func (*AISettings) Validate

func (s *AISettings) Validate() error

Validate checks if AISettings are valid

type AnalyticsPeriod

type AnalyticsPeriod struct {
	Start time.Time `json:"start"`
	End   time.Time `json:"end"`
}

AnalyticsPeriod represents the time range for analytics

func Last7Days

func Last7Days() AnalyticsPeriod

Last7Days creates a period for the last 7 days

func Last24Hours

func Last24Hours() AnalyticsPeriod

Last24Hours creates a period for the last 24 hours

func Last30Days

func Last30Days() AnalyticsPeriod

Last30Days creates a period for the last 30 days

func NewAnalyticsPeriod

func NewAnalyticsPeriod(start, end time.Time) AnalyticsPeriod

NewAnalyticsPeriod creates a new analytics period

type AuthContext

type AuthContext struct {
	UserID    string `json:"user_id"`
	Email     string `json:"email"`
	Name      string `json:"name"`
	Role      Role   `json:"role"`
	TeamID    string `json:"team_id"`
	SessionID string `json:"session_id"`
}

AuthContext contains authenticated user info for request context

func (*AuthContext) IsAdmin

func (a *AuthContext) IsAdmin() bool

IsAdmin checks if the authenticated user is an admin

type AuthMethod

type AuthMethod string

AuthMethod defines how to authenticate with a provider

const (
	AuthMethodOAuth2         AuthMethod = "oauth2"
	AuthMethodAPIKey         AuthMethod = "api_key"
	AuthMethodBasic          AuthMethod = "basic"
	AuthMethodServiceAccount AuthMethod = "service_account"
	AuthMethodPAT            AuthMethod = "pat" // Personal Access Token
)

type AuthProvider

type AuthProvider struct {
	Type         ProviderType `json:"type"`
	Name         string       `json:"name"`         // Display name
	AuthURL      string       `json:"auth_url"`     // OAuth authorization URL
	TokenURL     string       `json:"token_url"`    // OAuth token URL
	Scopes       []string     `json:"scopes"`       // Required OAuth scopes
	ClientID     string       `json:"client_id"`    // OAuth client ID (public)
	ClientSecret string       `json:"-"`            // OAuth client secret (never serialize)
	RedirectURL  string       `json:"redirect_url"` // OAuth callback URL
}

AuthProvider holds OAuth configuration for a provider

type AuthorizationCode added in v0.2.1

type AuthorizationCode struct {
	Code          string    `json:"code"`
	ClientID      string    `json:"client_id"`
	UserID        string    `json:"user_id"`
	RedirectURI   string    `json:"redirect_uri"`
	Scopes        []string  `json:"scopes"`
	CodeChallenge string    `json:"code_challenge"` // PKCE S256 challenge
	Resource      string    `json:"resource"`       // RFC 8707 resource indicator (audience)
	ExpiresAt     time.Time `json:"expires_at"`     // 10 minutes
	Used          bool      `json:"used"`           // single-use flag
	CreatedAt     time.Time `json:"created_at"`
}

AuthorizationCode represents a short-lived authorization code for the auth code flow

func (*AuthorizationCode) IsExpired added in v0.2.1

func (a *AuthorizationCode) IsExpired() bool

IsExpired checks if the authorization code has expired

func (*AuthorizationCode) IsUsable added in v0.2.1

func (a *AuthorizationCode) IsUsable() bool

IsUsable checks if the authorization code can be used (not expired and not already used)

type AuthorizeRequest added in v0.2.1

type AuthorizeRequest struct {
	ResponseType        string `json:"response_type"` // "code"
	ClientID            string `json:"client_id"`
	RedirectURI         string `json:"redirect_uri"`
	Scope               string `json:"scope"`                 // Space-delimited scopes
	State               string `json:"state,omitempty"`       // CSRF token
	CodeChallenge       string `json:"code_challenge"`        // PKCE challenge
	CodeChallengeMethod string `json:"code_challenge_method"` // "S256"
	Resource            string `json:"resource,omitempty"`    // RFC 8707 resource indicator
}

AuthorizeRequest represents an OAuth 2.0 authorization request

func (*AuthorizeRequest) ParseScopes added in v0.2.1

func (r *AuthorizeRequest) ParseScopes() []string

ParseScopes converts space-delimited scope string to array

type Capability

type Capability struct {
	// ID is a unique identifier for this capability instance
	ID string `json:"id"`

	// Type identifies which capability this is
	Type CapabilityType `json:"type"`

	// Phase indicates whether this is an indexing or search capability
	Phase PipelinePhase `json:"phase"`

	// BackendID identifies which backend provides this capability (e.g., "opensearch", "pgvector")
	// Empty for capabilities that don't require a specific backend
	BackendID string `json:"backend_id,omitempty"`

	// Available indicates if this capability is available based on environment and health checks
	// False means the backend is not configured or not healthy
	Available bool `json:"available"`

	// Enabled indicates if the user has enabled this capability
	// User can disable available capabilities
	Enabled bool `json:"enabled"`

	// Grants lists capabilities that this capability enables
	// Example: text_indexing grants bm25_search
	Grants []CapabilityType `json:"grants,omitempty"`

	// DependsOn lists capabilities that must be enabled for this to work
	// Example: bm25_search depends on text_indexing
	DependsOn []CapabilityType `json:"depends_on,omitempty"`
}

Capability represents a specific capability in the search pipeline. It defines what the system can do (indexing or search) and its current state.

func NewBM25SearchCapability

func NewBM25SearchCapability(backendID string, available bool) *Capability

NewBM25SearchCapability creates a BM25 search capability with defaults.

func NewEmbeddingIndexingCapability

func NewEmbeddingIndexingCapability(backendID string, available bool) *Capability

NewEmbeddingIndexingCapability creates an embedding indexing capability with defaults.

func NewQueryExpansionCapability added in v0.2.2

func NewQueryExpansionCapability(available bool) *Capability

NewQueryExpansionCapability creates a query expansion capability with defaults.

func NewQueryRewritingCapability added in v0.2.2

func NewQueryRewritingCapability(available bool) *Capability

NewQueryRewritingCapability creates a query rewriting capability with defaults.

func NewSummarizationCapability added in v0.2.2

func NewSummarizationCapability(available bool) *Capability

NewSummarizationCapability creates a summarization capability with defaults.

func NewTextIndexingCapability

func NewTextIndexingCapability(backendID string, available bool) *Capability

NewTextIndexingCapability creates a text indexing capability with defaults.

func NewVectorSearchCapability

func NewVectorSearchCapability(backendID string, available bool) *Capability

NewVectorSearchCapability creates a vector search capability with defaults.

func ResolveCapabilities

func ResolveCapabilities(prefs *CapabilityPreferences, available map[CapabilityType]bool) []*Capability

ResolveCapabilities builds runtime capability state by combining backend availability with user preferences. The available map uses domain CapabilityType keys.

Availability mapping: - CapabilityTextIndexing: whether OpenSearch is available - CapabilityEmbeddingIndexing: whether embeddings + vector store are available - CapabilityBM25Search: same as text_indexing (derived) - CapabilityVectorSearch: same as embedding_indexing (derived) - CapabilityQueryExpansion: whether LLM is available - CapabilityQueryRewriting: whether LLM is available - CapabilitySummarization: whether LLM is available

Dependency rules are enforced: if a dependency is not enabled, the dependent capability is also not enabled (e.g., bm25_search requires text_indexing).

func (*Capability) CanBeEnabled

func (c *Capability) CanBeEnabled() bool

CanBeEnabled returns true if the capability is available (can be enabled by user).

func (*Capability) HasBackend

func (c *Capability) HasBackend() bool

HasBackend returns true if this capability requires a specific backend.

func (*Capability) IsActive

func (c *Capability) IsActive() bool

IsActive returns true if the capability is both available and enabled. This is the primary indicator that a capability can be used.

func (*Capability) IsIndexingCapability

func (c *Capability) IsIndexingCapability() bool

IsIndexingCapability returns true if this is an indexing phase capability.

func (*Capability) IsSearchCapability

func (c *Capability) IsSearchCapability() bool

IsSearchCapability returns true if this is a search phase capability.

type CapabilityPreferences

type CapabilityPreferences struct {
	// TeamID is the team these preferences belong to
	TeamID string `json:"team_id"`

	// Indexing preferences (explicitly controlled by user)
	TextIndexingEnabled      bool `json:"text_indexing_enabled"`      // Enable BM25 indexing
	EmbeddingIndexingEnabled bool `json:"embedding_indexing_enabled"` // Enable vector indexing

	// Search preferences (can toggle down, but requires indexing to be enabled)
	BM25SearchEnabled   bool `json:"bm25_search_enabled"`   // Enable BM25 search (if text indexing enabled)
	VectorSearchEnabled bool `json:"vector_search_enabled"` // Enable vector search (if embedding indexing enabled)

	// LLM-powered search enhancements (requires LLM provider)
	QueryExpansionEnabled bool `json:"query_expansion_enabled"` // Enable query expansion
	QueryRewritingEnabled bool `json:"query_rewriting_enabled"` // Enable query rewriting
	SummarizationEnabled  bool `json:"summarization_enabled"`   // Enable result summarization

	// UpdatedAt tracks when preferences were last modified
	UpdatedAt time.Time `json:"updated_at"`
}

CapabilityPreferences stores per-team capability preferences. This is the persisted state that users control through the admin UI.

func DefaultCapabilityPreferences

func DefaultCapabilityPreferences(teamID string) *CapabilityPreferences

DefaultCapabilityPreferences returns default preferences for a team.

func (*CapabilityPreferences) CanUseBM25Search

func (p *CapabilityPreferences) CanUseBM25Search() bool

CanUseBM25Search returns true if BM25 search can be used. Requires both text indexing and BM25 search to be enabled.

func (*CapabilityPreferences) CanUseVectorSearch

func (p *CapabilityPreferences) CanUseVectorSearch() bool

CanUseVectorSearch returns true if vector search can be used. Requires both embedding indexing and vector search to be enabled.

func (*CapabilityPreferences) DisableEmbeddingIndexing

func (p *CapabilityPreferences) DisableEmbeddingIndexing()

DisableEmbeddingIndexing disables embedding indexing and vector search.

func (*CapabilityPreferences) DisableTextIndexing

func (p *CapabilityPreferences) DisableTextIndexing()

DisableTextIndexing disables text indexing and BM25 search.

func (*CapabilityPreferences) EnableEmbeddingIndexing

func (p *CapabilityPreferences) EnableEmbeddingIndexing()

EnableEmbeddingIndexing enables embedding indexing and vector search.

func (*CapabilityPreferences) EnableTextIndexing

func (p *CapabilityPreferences) EnableTextIndexing()

EnableTextIndexing enables text indexing and BM25 search.

func (*CapabilityPreferences) HasEmbeddingIndexing

func (p *CapabilityPreferences) HasEmbeddingIndexing() bool

HasEmbeddingIndexing returns true if embedding indexing is enabled.

func (*CapabilityPreferences) HasTextIndexing

func (p *CapabilityPreferences) HasTextIndexing() bool

HasTextIndexing returns true if text indexing is enabled.

type CapabilityType

type CapabilityType string

CapabilityType represents a specific capability in the pipeline

const (
	// Indexing capabilities (user controls)
	CapabilityTextIndexing      CapabilityType = "text_indexing"      // Enables BM25 search
	CapabilityEmbeddingIndexing CapabilityType = "embedding_indexing" // Enables vector search

	// Search capabilities (derived from indexing, toggleable)
	CapabilityBM25Search   CapabilityType = "bm25_search"   // Keyword search
	CapabilityVectorSearch CapabilityType = "vector_search" // Semantic search

	// LLM-powered search enhancements (requires LLM provider)
	CapabilityQueryExpansion CapabilityType = "query_expansion" // Expands queries with related terms
	CapabilityQueryRewriting CapabilityType = "query_rewriting" // Reformulates queries for better matching
	CapabilitySummarization  CapabilityType = "summarization"   // Generates result snippets
)

type Change

type Change struct {
	Type       ChangeType `json:"type"`
	Document   *Document  `json:"document,omitempty"`   // For added/modified
	Content    string     `json:"content,omitempty"`    // Raw content for added/modified
	DeletedID  string     `json:"deleted_id,omitempty"` // For deleted
	ExternalID string     `json:"external_id"`          // ID from source system
}

Change represents a document change from a connector

type ChangePasswordRequest

type ChangePasswordRequest struct {
	CurrentPassword string `json:"current_password"`
	NewPassword     string `json:"new_password"`
}

ChangePasswordRequest represents a password change by authenticated user

type ChangeType

type ChangeType string

ChangeType indicates what happened to a document

const (
	ChangeTypeAdded    ChangeType = "added"
	ChangeTypeModified ChangeType = "modified"
	ChangeTypeDeleted  ChangeType = "deleted"
)

type Chunk

type Chunk struct {
	ID         string    `json:"id"`
	DocumentID string    `json:"document_id"`
	SourceID   string    `json:"source_id"`
	Content    string    `json:"content"`
	Embedding  []float32 `json:"embedding,omitempty"`
	Position   int       `json:"position"` // Chunk position within document
	StartChar  int       `json:"start_char"`
	EndChar    int       `json:"end_char"`
	CreatedAt  time.Time `json:"created_at"`
}

Chunk represents a searchable chunk of a document

type ClientRegistrationRequest added in v0.2.1

type ClientRegistrationRequest struct {
	Name                    string           `json:"client_name"`
	RedirectURIs            []string         `json:"redirect_uris"`
	GrantTypes              []OAuthGrantType `json:"grant_types,omitempty"`
	ResponseTypes           []string         `json:"response_types,omitempty"`
	Scopes                  ScopeList        `json:"scope,omitempty"` // Space-delimited string or array
	ApplicationType         string           `json:"application_type,omitempty"`
	TokenEndpointAuthMethod string           `json:"token_endpoint_auth_method,omitempty"`
}

ClientRegistrationRequest represents a dynamic client registration request (RFC 7591)

type ClientRegistrationResponse added in v0.2.1

type ClientRegistrationResponse struct {
	ClientID                string           `json:"client_id"`
	ClientSecret            string           `json:"client_secret,omitempty"` // Only returned once for confidential clients
	Name                    string           `json:"client_name"`
	RedirectURIs            []string         `json:"redirect_uris"`
	GrantTypes              []OAuthGrantType `json:"grant_types"`
	ResponseTypes           []string         `json:"response_types"`
	Scopes                  ScopeList        `json:"scope"`
	ApplicationType         string           `json:"application_type"`
	TokenEndpointAuthMethod string           `json:"token_endpoint_auth_method"`
	ClientIDIssuedAt        int64            `json:"client_id_issued_at"` // Unix timestamp
}

ClientRegistrationResponse represents the response from dynamic client registration

type CompletionRequest added in v0.2.2

type CompletionRequest struct {
	// SystemPrompt sets the system-level instructions for the LLM
	SystemPrompt string `json:"system_prompt"`

	// UserPrompt is the user's input or query to the LLM
	UserPrompt string `json:"user_prompt"`

	// MaxTokens limits the length of the generated response
	// If 0, the LLM provider's default is used
	MaxTokens int `json:"max_tokens,omitempty"`

	// Temperature controls randomness in the response (0.0 to 2.0)
	// Lower values make output more focused and deterministic
	// Higher values make output more creative and random
	Temperature float64 `json:"temperature,omitempty"`

	// ResponseSchema is an optional JSON Schema that constrains the LLM output
	// to a specific structure. Used for structured data extraction.
	// The actual schema format depends on the LLM provider.
	ResponseSchema any `json:"response_schema,omitempty"`
}

CompletionRequest represents a request to an LLM for text completion. This is a pure domain type with no external dependencies.

func NewCompletionRequest added in v0.2.2

func NewCompletionRequest(systemPrompt, userPrompt string) CompletionRequest

NewCompletionRequest creates a simple completion request with just prompts. Use the struct directly for more control over optional parameters.

func (CompletionRequest) Validate added in v0.2.2

func (r CompletionRequest) Validate() error

Validate checks if the completion request is valid.

func (CompletionRequest) WithMaxTokens added in v0.2.2

func (r CompletionRequest) WithMaxTokens(maxTokens int) CompletionRequest

WithMaxTokens returns a new request with MaxTokens set.

func (CompletionRequest) WithResponseSchema added in v0.2.2

func (r CompletionRequest) WithResponseSchema(schema any) CompletionRequest

WithResponseSchema returns a new request with a JSON Schema for structured output.

func (CompletionRequest) WithTemperature added in v0.2.2

func (r CompletionRequest) WithTemperature(temperature float64) CompletionRequest

WithTemperature returns a new request with Temperature set.

type CompletionResponse added in v0.2.2

type CompletionResponse struct {
	// Content is the generated text from the LLM
	Content string `json:"content"`

	// Usage tracks token consumption for this request
	Usage TokenUsage `json:"usage"`
}

CompletionResponse represents the LLM's response to a completion request.

func (CompletionResponse) HasUsage added in v0.2.2

func (r CompletionResponse) HasUsage() bool

HasUsage returns true if token usage information is available.

func (CompletionResponse) IsEmpty added in v0.2.2

func (r CompletionResponse) IsEmpty() bool

IsEmpty returns true if the response has no content.

type Connection

type Connection struct {
	ID           string       `json:"id"`
	Name         string       `json:"name"`
	Platform     PlatformType `json:"platform"`      // NEW: authentication boundary
	ProviderType ProviderType `json:"provider_type"` // kept for backward compat
	AuthMethod   AuthMethod   `json:"auth_method"`

	// Secrets contains decrypted secret values (never persisted as-is)
	// This is populated when fetching from store, nil when listing
	Secrets *ConnectionSecrets `json:"-"`

	// OAuth metadata (non-secret, safe to expose)
	OAuthTokenType string     `json:"oauth_token_type,omitempty"`
	OAuthExpiry    *time.Time `json:"oauth_expiry,omitempty"`
	OAuthScopes    []string   `json:"oauth_scopes,omitempty"`

	// AccountID is the provider account identifier (email, username)
	// Used for display and uniqueness constraint
	AccountID string `json:"account_id,omitempty"`

	CreatedAt  time.Time  `json:"created_at"`
	UpdatedAt  time.Time  `json:"updated_at"`
	LastUsedAt *time.Time `json:"last_used_at,omitempty"`
}

Connection represents a connector connection with stored credentials. A connection is the authenticated link to a provider (GitHub, Google, etc.) Sources reference connections to get their authentication context.

func (*Connection) GetAccessToken

func (c *Connection) GetAccessToken() string

GetAccessToken returns the access token if available. For OAuth2: returns the access token For API Key/PAT: returns the API key

func (*Connection) HasScope added in v0.2.1

func (c *Connection) HasScope(scope string) bool

HasScope checks if the connection has a specific OAuth scope

func (*Connection) HasSecrets

func (c *Connection) HasSecrets() bool

HasSecrets returns true if the connection has secrets loaded.

func (*Connection) IsExpired

func (c *Connection) IsExpired() bool

IsExpired returns true if OAuth tokens have expired.

func (*Connection) MissingScopes added in v0.2.1

func (c *Connection) MissingScopes(required []string) []string

MissingScopes returns scopes from required that are not in OAuthScopes

func (*Connection) NeedsRefresh

func (c *Connection) NeedsRefresh() bool

NeedsRefresh returns true if OAuth tokens should be refreshed. Returns true if within 5 minutes of expiry.

func (*Connection) ToSummary

func (c *Connection) ToSummary() *ConnectionSummary

ToSummary converts Connection to ConnectionSummary.

type ConnectionSecrets

type ConnectionSecrets struct {
	// OAuth2 tokens
	AccessToken  string `json:"access_token,omitempty"`
	RefreshToken string `json:"refresh_token,omitempty"`

	// API Key (for api_key auth method)
	APIKey string `json:"api_key,omitempty"`

	// Service Account JSON (for service_account auth method, e.g., Google)
	ServiceAccountJSON string `json:"service_account_json,omitempty"`
}

ConnectionSecrets contains decrypted secret values. These are encrypted before storage and decrypted on retrieval.

type ConnectionSummary

type ConnectionSummary struct {
	ID           string       `json:"id"`
	Name         string       `json:"name"`
	Platform     PlatformType `json:"platform"` // NEW
	ProviderType ProviderType `json:"provider_type"`
	AuthMethod   AuthMethod   `json:"auth_method"`
	AccountID    string       `json:"account_id,omitempty"`
	OAuthExpiry  *time.Time   `json:"oauth_expiry,omitempty"`
	CreatedAt    time.Time    `json:"created_at"`
	LastUsedAt   *time.Time   `json:"last_used_at,omitempty"`
}

ConnectionSummary is a safe view without secrets for listing.

type Container

type Container struct {
	ID       string            `json:"id"`
	Name     string            `json:"name"`
	Type     string            `json:"type,omitempty"`
	Metadata map[string]string `json:"metadata,omitempty"`
}

Container represents a selectable unit within a connection. Examples: a repository, a Slack channel, a Drive folder, a Notion database.

type CredentialSummary

type CredentialSummary struct {
	ID           string       `json:"id"`
	ProviderType ProviderType `json:"provider_type"`
	AuthMethod   AuthMethod   `json:"auth_method"`
	Name         string       `json:"name"`
	HasToken     bool         `json:"has_token"`
	TokenExpiry  *time.Time   `json:"token_expiry,omitempty"`
	CreatedAt    time.Time    `json:"created_at"`
}

CredentialSummary provides a safe view without sensitive data

type Credentials

type Credentials struct {
	ID           string       `json:"id"`
	ProviderType ProviderType `json:"provider_type"`
	AuthMethod   AuthMethod   `json:"auth_method"`
	Name         string       `json:"name"` // User-friendly name

	// OAuth2 fields
	AccessToken  string     `json:"-"` // Never serialize
	RefreshToken string     `json:"-"` // Never serialize
	TokenExpiry  *time.Time `json:"token_expiry,omitempty"`
	Scopes       []string   `json:"scopes,omitempty"`

	// API Key / PAT
	APIKey string `json:"-"` // Never serialize

	// Basic Auth
	Username string `json:"-"` // Never serialize
	Password string `json:"-"` // Never serialize

	// Service Account (e.g., Google)
	ServiceAccountJSON string `json:"-"` // Never serialize

	// Metadata
	CreatedAt time.Time `json:"created_at"`
	UpdatedAt time.Time `json:"updated_at"`
	CreatedBy string    `json:"created_by"` // User ID
}

Credentials stores authentication credentials for a source connector

func (*Credentials) IsExpired

func (c *Credentials) IsExpired() bool

IsExpired checks if OAuth tokens have expired

func (*Credentials) NeedsRefresh

func (c *Credentials) NeedsRefresh() bool

NeedsRefresh checks if tokens should be refreshed (within 5 min of expiry)

func (*Credentials) ToSummary

func (c *Credentials) ToSummary() *CredentialSummary

ToSummary converts Credentials to CredentialSummary

type Document

type Document struct {
	ID         string            `json:"id"`
	SourceID   string            `json:"source_id"`
	ExternalID string            `json:"external_id"` // ID from the source system
	Path       string            `json:"path"`        // Path or URL in source
	Title      string            `json:"title"`
	MimeType   string            `json:"mime_type"`
	Metadata   map[string]string `json:"metadata"`
	CreatedAt  time.Time         `json:"created_at"`
	UpdatedAt  time.Time         `json:"updated_at"`
	IndexedAt  time.Time         `json:"indexed_at"`
}

Document represents an indexed document from a source

type DocumentContent

type DocumentContent struct {
	DocumentID string            `json:"document_id"`
	SourceID   string            `json:"source_id"`
	Title      string            `json:"title"`
	Body       string            `json:"body"`
	Path       string            `json:"path"`
	MimeType   string            `json:"mime_type"`
	Metadata   map[string]string `json:"metadata"`
}

DocumentContent holds the full content of a document for indexing.

type DocumentWithChunks

type DocumentWithChunks struct {
	Document *Document `json:"document"`
	Chunks   []*Chunk  `json:"chunks"`
}

DocumentWithChunks combines a document with its chunks

type EmbeddingConfig

type EmbeddingConfig struct {
	Provider   AIProvider `json:"provider"`
	Model      string     `json:"model"`
	Dimensions int        `json:"dimensions"`
	BatchSize  int        `json:"batch_size"`
}

EmbeddingConfig holds embedding model configuration

func DefaultEmbeddingConfig

func DefaultEmbeddingConfig() *EmbeddingConfig

DefaultEmbeddingConfig returns default embedding configuration

type EmbeddingSettings

type EmbeddingSettings struct {
	Provider AIProvider `json:"provider"`
	Model    string     `json:"model"`
}

EmbeddingSettings configures the embedding service API keys and base URLs come from environment variables, not stored here

func (*EmbeddingSettings) IsConfigured

func (e *EmbeddingSettings) IsConfigured() bool

IsConfigured returns true if embedding settings are properly configured Note: API key availability is checked at the infrastructure layer (config package)

type Filters

type Filters struct {
	MimeTypes  []string   `json:"mime_types,omitempty"`
	DateAfter  *time.Time `json:"date_after,omitempty"`
	DateBefore *time.Time `json:"date_before,omitempty"`
}

Filters provides additional search filters

type JobDetail

type JobDetail struct {
	// Task is the main task information
	Task *Task `json:"task"`

	// SourceName is the name of the source (if applicable)
	SourceName string `json:"source_name,omitempty"`

	// ExecutionLogs contains log entries for this job (future enhancement)
	ExecutionLogs []string `json:"execution_logs,omitempty"`

	// RetryHistory shows previous retry attempts
	RetryHistory []*RetryAttempt `json:"retry_history,omitempty"`
}

JobDetail represents detailed information about a specific job This is a value object that combines task information with execution context

func NewJobDetail

func NewJobDetail(task *Task) *JobDetail

NewJobDetail creates a new job detail value object

func (*JobDetail) WithExecutionLogs

func (jd *JobDetail) WithExecutionLogs(logs []string) *JobDetail

WithExecutionLogs adds execution logs to the job detail

func (*JobDetail) WithRetryHistory

func (jd *JobDetail) WithRetryHistory(history []*RetryAttempt) *JobDetail

WithRetryHistory adds retry history to the job detail

func (*JobDetail) WithSourceName

func (jd *JobDetail) WithSourceName(sourceName string) *JobDetail

WithSourceName adds the source name to the job detail

type JobHistory

type JobHistory struct {
	// Jobs is the list of historical job executions
	Jobs []*Task `json:"jobs"`

	// TotalCount is the total number of jobs matching the query
	TotalCount int64 `json:"total_count"`

	// HasMore indicates if there are more jobs beyond the current page
	HasMore bool `json:"has_more"`
}

JobHistory represents a summarized view of job execution history This is a value object used for the job history endpoint

func NewJobHistory

func NewJobHistory(jobs []*Task, totalCount int64, limit int) *JobHistory

NewJobHistory creates a new job history value object

type JobStats

type JobStats struct {
	// Total jobs across all statuses
	TotalJobs int64 `json:"total_jobs"`

	// PendingJobs is the number of jobs waiting to be processed
	PendingJobs int64 `json:"pending_jobs"`

	// ProcessingJobs is the number of jobs currently being processed
	ProcessingJobs int64 `json:"processing_jobs"`

	// CompletedJobs is the number of successfully completed jobs
	CompletedJobs int64 `json:"completed_jobs"`

	// FailedJobs is the number of failed jobs
	FailedJobs int64 `json:"failed_jobs"`

	// SuccessRate is the percentage of successful jobs (0-100)
	SuccessRate float64 `json:"success_rate"`

	// AverageDuration is the average job duration in milliseconds
	AverageDuration float64 `json:"average_duration_ms"`

	// TotalRetries is the total number of retry attempts
	TotalRetries int64 `json:"total_retries"`

	// JobsByType shows the breakdown by task type
	JobsByType map[TaskType]int64 `json:"jobs_by_type"`

	// Period is the time range for these statistics
	Period AnalyticsPeriod `json:"period"`
}

JobStats represents aggregated job statistics This is a value object (no identity) representing computed statistics

func NewJobStats

func NewJobStats(period AnalyticsPeriod) *JobStats

NewJobStats creates a new job statistics value object

func (*JobStats) CalculateSuccessRate

func (js *JobStats) CalculateSuccessRate()

CalculateSuccessRate computes the success rate percentage

type LLMSettings

type LLMSettings struct {
	Provider AIProvider `json:"provider"`
	Model    string     `json:"model"`
}

LLMSettings configures the LLM service API keys and base URLs come from environment variables, not stored here

func (*LLMSettings) IsConfigured

func (l *LLMSettings) IsConfigured() bool

IsConfigured returns true if LLM settings are properly configured Note: API key availability is checked at the infrastructure layer (config package)

type LoginRequest

type LoginRequest struct {
	Email    string `json:"email"`
	Password string `json:"password"`
}

LoginRequest represents a login attempt

type LoginResponse

type LoginResponse struct {
	Token        string       `json:"token"`
	RefreshToken string       `json:"refresh_token,omitempty"`
	ExpiresAt    time.Time    `json:"expires_at"`
	User         *UserSummary `json:"user"`
}

LoginResponse is returned after successful authentication

type OAuthAccessToken added in v0.2.1

type OAuthAccessToken struct {
	ID        string    `json:"id"` // jti claim
	ClientID  string    `json:"client_id"`
	UserID    string    `json:"user_id"`
	Scopes    []string  `json:"scopes"`
	Audience  string    `json:"audience"`   // Resource indicator (MCP server URL)
	ExpiresAt time.Time `json:"expires_at"` // Short-lived (15 min default)
	CreatedAt time.Time `json:"created_at"`
	Revoked   bool      `json:"revoked"`
}

OAuthAccessToken represents an OAuth 2.0 access token

func (*OAuthAccessToken) IsExpired added in v0.2.1

func (t *OAuthAccessToken) IsExpired() bool

IsExpired checks if the access token has expired

func (*OAuthAccessToken) IsValid added in v0.2.1

func (t *OAuthAccessToken) IsValid() bool

IsValid checks if the access token is valid (not expired and not revoked)

type OAuthClient added in v0.2.1

type OAuthClient struct {
	ID                      string           `json:"id"`                         // client_id (UUID)
	SecretHash              string           `json:"-"`                          // bcrypt hash of client_secret (empty for public clients)
	Name                    string           `json:"name"`                       // Human-readable name
	RedirectURIs            []string         `json:"redirect_uris"`              // Registered redirect URIs
	GrantTypes              []OAuthGrantType `json:"grant_types"`                // Allowed grant types
	ResponseTypes           []string         `json:"response_types"`             // Allowed response types (e.g., "code")
	Scopes                  []string         `json:"scopes"`                     // Allowed scopes
	ApplicationType         string           `json:"application_type"`           // "native" or "web"
	TokenEndpointAuthMethod string           `json:"token_endpoint_auth_method"` // "client_secret_post" or "none" (public)
	Active                  bool             `json:"active"`                     // Whether the client is active
	CreatedAt               time.Time        `json:"created_at"`
	UpdatedAt               time.Time        `json:"updated_at"`
}

OAuthClient represents a registered third-party OAuth 2.0 client application

func (*OAuthClient) HasGrantType added in v0.2.1

func (c *OAuthClient) HasGrantType(gt OAuthGrantType) bool

HasGrantType checks if the client is allowed to use the given grant type

func (*OAuthClient) HasRedirectURI added in v0.2.1

func (c *OAuthClient) HasRedirectURI(uri string) bool

HasRedirectURI validates if the given URI is in the client's registered redirect URIs

func (*OAuthClient) HasScope added in v0.2.1

func (c *OAuthClient) HasScope(scope string) bool

HasScope checks if the client is allowed to request the given scope

func (*OAuthClient) IsPublic added in v0.2.1

func (c *OAuthClient) IsPublic() bool

IsPublic returns true if the client is a public client (no client secret required)

func (*OAuthClient) ValidateScopes added in v0.2.1

func (c *OAuthClient) ValidateScopes(requested []string) []string

ValidateScopes returns a list of invalid scopes from the requested list

type OAuthGrantType added in v0.2.1

type OAuthGrantType string

OAuthGrantType represents the OAuth 2.0 grant type

const (
	GrantTypeAuthorizationCode OAuthGrantType = "authorization_code"
	GrantTypeRefreshToken      OAuthGrantType = "refresh_token"
)

type OAuthRefreshToken added in v0.2.1

type OAuthRefreshToken struct {
	ID            string    `json:"id"`
	AccessTokenID string    `json:"access_token_id"` // Associated access token
	ClientID      string    `json:"client_id"`
	UserID        string    `json:"user_id"`
	Scopes        []string  `json:"scopes"`
	Audience      string    `json:"audience"`
	ExpiresAt     time.Time `json:"expires_at"` // 30 days
	CreatedAt     time.Time `json:"created_at"`
	Revoked       bool      `json:"revoked"`
	RotatedTo     string    `json:"rotated_to"` // New token ID after rotation (empty if current)
}

OAuthRefreshToken represents an OAuth 2.0 refresh token with rotation support

func (*OAuthRefreshToken) IsExpired added in v0.2.1

func (t *OAuthRefreshToken) IsExpired() bool

IsExpired checks if the refresh token has expired

func (*OAuthRefreshToken) IsRotated added in v0.2.1

func (t *OAuthRefreshToken) IsRotated() bool

IsRotated checks if the refresh token has been rotated to a new token

func (*OAuthRefreshToken) IsValid added in v0.2.1

func (t *OAuthRefreshToken) IsValid() bool

IsValid checks if the refresh token is valid (not expired, not revoked, and not rotated)

type PasswordResetConfirm

type PasswordResetConfirm struct {
	Token       string `json:"token"`
	NewPassword string `json:"new_password"`
}

PasswordResetConfirm represents a password reset confirmation

type PasswordResetRequest

type PasswordResetRequest struct {
	Email string `json:"email"`
}

PasswordResetRequest represents a password reset request

type PipelinePhase

type PipelinePhase string

PipelinePhase represents which phase of the pipeline a capability belongs to

const (
	PipelinePhaseIndexing PipelinePhase = "indexing" // Document ingestion and processing
	PipelinePhaseSearch   PipelinePhase = "search"   // Query execution
)

type PlatformType added in v0.2.1

type PlatformType string

PlatformType identifies an authentication boundary (OAuth client) Multiple services can share a platform (e.g., google_drive and google_docs both use google)

const (
	// Only implemented platforms (1:1 with providers for now)
	PlatformGitHub    PlatformType = "github"
	PlatformLocalFS   PlatformType = "localfs"
	PlatformNotion    PlatformType = "notion"
	PlatformMicrosoft PlatformType = "microsoft"
)

func PlatformFor added in v0.2.1

func PlatformFor(provider ProviderType) PlatformType

PlatformFor returns the platform that owns a given service/provider. For 1:1 connectors (all current ones), platform == provider. Multi-service platforms (Google, Microsoft, Atlassian) will map multiple ProviderTypes to one PlatformType when implemented.

type ProviderConfig

type ProviderConfig struct {
	ProviderType ProviderType

	// Decrypted secrets (never persisted as-is)
	Secrets *ProviderSecrets

	// Non-secret configuration (can override defaults)
	AuthURL     string   // OAuth authorization URL
	TokenURL    string   // OAuth token URL
	Scopes      []string // OAuth scopes
	RedirectURI string   // OAuth callback URL

	// Metadata
	Enabled   bool
	CreatedAt time.Time
	UpdatedAt time.Time
}

ProviderConfig represents OAuth app configuration for a provider type. One config per provider - multiple installations can use the same config.

func (*ProviderConfig) IsConfigured

func (p *ProviderConfig) IsConfigured() bool

IsConfigured returns true if the provider has credentials set.

type ProviderConfigSummary

type ProviderConfigSummary struct {
	ProviderType ProviderType
	Enabled      bool
	HasSecrets   bool // true if secrets are configured
	CreatedAt    time.Time
	UpdatedAt    time.Time
}

ProviderConfigSummary is a safe view without secrets (for listing).

type ProviderSecrets

type ProviderSecrets struct {
	ClientID     string `json:"client_id,omitempty"`
	ClientSecret string `json:"client_secret,omitempty"`
	APIKey       string `json:"api_key,omitempty"` // For non-OAuth providers
}

ProviderSecrets contains decrypted secret values. Encrypted before storage using same AES-GCM as installations.

type ProviderType

type ProviderType string

ProviderType identifies a data source provider

const (
	// Only implemented connectors
	ProviderTypeGitHub   ProviderType = "github"
	ProviderTypeLocalFS  ProviderType = "localfs"
	ProviderTypeNotion   ProviderType = "notion"
	ProviderTypeOneDrive ProviderType = "onedrive"
)

func ServicesFor added in v0.2.1

func ServicesFor(platform PlatformType) []ProviderType

ServicesFor returns all services under a platform.

type QueryFrequency

type QueryFrequency struct {
	Query string `json:"query"`
	Count int64  `json:"count"`
}

QueryFrequency represents how often a query appears

type RankedChunk

type RankedChunk struct {
	Chunk      *Chunk    `json:"chunk"`
	Document   *Document `json:"document"`
	Score      float64   `json:"score"`
	Highlights []string  `json:"highlights,omitempty"`
}

RankedChunk is kept for backward compatibility with the legacy Search port. Deprecated: Use SearchResultItem instead.

type RefreshRequest

type RefreshRequest struct {
	RefreshToken string `json:"refresh_token"`
}

RefreshRequest represents a token refresh attempt

type RetryAttempt

type RetryAttempt struct {
	// Attempt is the attempt number (1-indexed)
	Attempt int `json:"attempt"`

	// Error is the error message from this attempt
	Error string `json:"error"`

	// Timestamp is when this attempt occurred
	Timestamp time.Time `json:"timestamp"`
}

RetryAttempt represents a single retry attempt for a job

type RevokeRequest added in v0.2.1

type RevokeRequest struct {
	Token         string `json:"token"`
	TokenTypeHint string `json:"token_type_hint,omitempty"` // "access_token" or "refresh_token"
}

RevokeRequest represents a token revocation request (RFC 7009)

type Role

type Role string

Role defines user permission level

const (
	RoleAdmin  Role = "admin"  // Manage users, sources, settings
	RoleMember Role = "member" // Search, view documents
	RoleViewer Role = "viewer" // Search only (future)
)

type RuntimeConfig

type RuntimeConfig struct {

	// Static (set at startup, read-only)
	SessionBackend string // "redis" or "postgres"
	// contains filtered or unexported fields
}

RuntimeConfig tracks which services are available at runtime. This is determined at startup and can be updated dynamically for AI services. Thread-safe for concurrent access.

func NewRuntimeConfig

func NewRuntimeConfig(sessionBackend string) *RuntimeConfig

NewRuntimeConfig creates a new RuntimeConfig with initial values

func (*RuntimeConfig) CanDoHybridSearch

func (c *RuntimeConfig) CanDoHybridSearch() bool

CanDoHybridSearch returns true if hybrid search is possible

func (*RuntimeConfig) CanDoLLMAssisted

func (c *RuntimeConfig) CanDoLLMAssisted() bool

CanDoLLMAssisted returns true if LLM features are available

func (*RuntimeConfig) CanDoSemanticSearch

func (c *RuntimeConfig) CanDoSemanticSearch() bool

CanDoSemanticSearch returns true if semantic search is possible

func (*RuntimeConfig) EffectiveSearchMode

func (c *RuntimeConfig) EffectiveSearchMode() SearchMode

EffectiveSearchMode returns the best available search mode

func (*RuntimeConfig) EmbeddingAvailable

func (c *RuntimeConfig) EmbeddingAvailable() bool

EmbeddingAvailable returns whether embedding service is available

func (*RuntimeConfig) LLMAvailable

func (c *RuntimeConfig) LLMAvailable() bool

LLMAvailable returns whether LLM service is available

func (*RuntimeConfig) SetEmbeddingAvailable

func (c *RuntimeConfig) SetEmbeddingAvailable(available bool)

SetEmbeddingAvailable updates the embedding availability flag

func (*RuntimeConfig) SetLLMAvailable

func (c *RuntimeConfig) SetLLMAvailable(available bool)

SetLLMAvailable updates the LLM availability flag

type ScheduledTask

type ScheduledTask struct {
	// ID is the unique identifier for this scheduled task
	ID string `json:"id"`

	// Name is a human-readable name for the task
	Name string `json:"name"`

	// Type is the task type to create when triggered
	Type TaskType `json:"type"`

	// TeamID is the team this schedule belongs to
	TeamID string `json:"team_id"`

	// Interval is how often to run the task
	Interval time.Duration `json:"interval"`

	// Enabled indicates if the schedule is active
	Enabled bool `json:"enabled"`

	// LastRun is when the task was last triggered
	LastRun *time.Time `json:"last_run,omitempty"`

	// NextRun is when the task should next be triggered
	NextRun time.Time `json:"next_run"`

	// LastError contains the last error if the scheduled task failed
	LastError string `json:"last_error,omitempty"`
}

ScheduledTask represents a recurring task configuration

func DefaultSchedulerConfig

func DefaultSchedulerConfig(teamID string, intervalMinutes int) []*ScheduledTask

DefaultSchedulerConfig returns the default scheduled tasks with custom interval If intervalMinutes is 0, defaults to 60 minutes

func NewScheduledTask

func NewScheduledTask(id, name string, taskType TaskType, teamID string, interval time.Duration) *ScheduledTask

NewScheduledTask creates a new scheduled task

func (*ScheduledTask) IsDue

func (s *ScheduledTask) IsDue() bool

IsDue returns true if the scheduled task should be triggered

func (*ScheduledTask) UpdateNextRun

func (s *ScheduledTask) UpdateNextRun()

UpdateNextRun calculates the next run time after execution

type ScopeList added in v0.2.1

type ScopeList []string

ScopeList is a []string that can unmarshal from either a JSON string (space-delimited, per RFC 7591) or a JSON array of strings.

func (ScopeList) MarshalJSON added in v0.2.1

func (s ScopeList) MarshalJSON() ([]byte, error)

func (*ScopeList) UnmarshalJSON added in v0.2.1

func (s *ScopeList) UnmarshalJSON(data []byte) error

type SearchAnalytics

type SearchAnalytics struct {
	// TotalSearches is the total number of searches in the period
	TotalSearches int64 `json:"total_searches"`

	// UniqueUsers is the number of unique users who searched
	UniqueUsers int64 `json:"unique_users"`

	// AverageDuration is the average search duration in milliseconds
	AverageDuration float64 `json:"average_duration_ms"`

	// AverageResults is the average number of results per search
	AverageResults float64 `json:"average_results"`

	// TopQueries are the most common search queries
	TopQueries []QueryFrequency `json:"top_queries"`

	// SearchesByMode shows the breakdown by search mode
	SearchesByMode map[SearchMode]int64 `json:"searches_by_mode"`

	// Period is the time range for these analytics
	Period AnalyticsPeriod `json:"period"`
}

SearchAnalytics represents aggregated search analytics data This is a value object (no identity) representing computed statistics

type SearchMetrics

type SearchMetrics struct {
	// FastSearches is the number of searches under 100ms
	FastSearches int64 `json:"fast_searches"`

	// MediumSearches is the number of searches 100ms-500ms
	MediumSearches int64 `json:"medium_searches"`

	// SlowSearches is the number of searches over 500ms
	SlowSearches int64 `json:"slow_searches"`

	// P50Duration is the 50th percentile search duration in milliseconds
	P50Duration float64 `json:"p50_duration_ms"`

	// P95Duration is the 95th percentile search duration in milliseconds
	P95Duration float64 `json:"p95_duration_ms"`

	// P99Duration is the 99th percentile search duration in milliseconds
	P99Duration float64 `json:"p99_duration_ms"`

	// ZeroResultSearches is the number of searches that returned no results
	ZeroResultSearches int64 `json:"zero_result_searches"`

	// Period is the time range for these metrics
	Period AnalyticsPeriod `json:"period"`
}

SearchMetrics represents performance metrics for searches This is a value object for monitoring search performance

type SearchMode

type SearchMode string

SearchMode determines the search strategy

const (
	SearchModeHybrid       SearchMode = "hybrid"   // BM25 + vector (default)
	SearchModeTextOnly     SearchMode = "text"     // BM25 only
	SearchModeSemanticOnly SearchMode = "semantic" // Vector only
)

func (SearchMode) RequiresEmbedding

func (mode SearchMode) RequiresEmbedding() bool

RequiresEmbedding returns true if the given search mode requires embedding

type SearchOptions

type SearchOptions struct {
	Mode        SearchMode `json:"mode"`
	Limit       int        `json:"limit"`
	Offset      int        `json:"offset"`
	SourceIDs   []string   `json:"source_ids,omitempty"`   // Filter by sources
	DocumentIDs []string   `json:"document_ids,omitempty"` // Filter by specific document IDs
	Filters     Filters    `json:"filters,omitempty"`
}

SearchOptions configures a search request

func DefaultSearchOptions

func DefaultSearchOptions() SearchOptions

DefaultSearchOptions returns sensible defaults

type SearchQuery

type SearchQuery struct {
	// ID is the unique identifier for this search query log entry
	ID string `json:"id"`

	// TeamID is the team that performed the search
	TeamID string `json:"team_id"`

	// UserID is the user who performed the search
	UserID string `json:"user_id"`

	// Query is the search text that was submitted
	Query string `json:"query"`

	// Mode is the search mode used (hybrid, text, semantic)
	Mode SearchMode `json:"mode"`

	// ResultCount is the number of results returned
	ResultCount int `json:"result_count"`

	// Duration is how long the search took to execute (in nanoseconds)
	Duration int64 `json:"duration"`

	// SourceIDs are the source IDs that were filtered (if any)
	SourceIDs []string `json:"source_ids,omitempty"`

	// Filters are the additional filters applied
	HasFilters bool `json:"has_filters"`

	// CreatedAt is when the search was performed
	CreatedAt time.Time `json:"created_at"`
}

SearchQuery represents a logged search query for analytics This is an entity (has identity) used to track search usage and performance

func NewSearchQuery

func NewSearchQuery(teamID, userID, query string, mode SearchMode, resultCount int, duration time.Duration) *SearchQuery

NewSearchQuery creates a new search query log entry

func (*SearchQuery) GetDuration

func (sq *SearchQuery) GetDuration() time.Duration

GetDuration returns the duration as a time.Duration

func (*SearchQuery) WithFilters

func (sq *SearchQuery) WithFilters(hasFilters bool) *SearchQuery

WithFilters marks that additional filters were applied

func (*SearchQuery) WithSourceFilters

func (sq *SearchQuery) WithSourceFilters(sourceIDs []string) *SearchQuery

WithSourceFilters sets the source IDs filter

type SearchResult

type SearchResult struct {
	Query      string              `json:"query"`
	Mode       SearchMode          `json:"mode"`
	Results    []*SearchResultItem `json:"results"`
	TotalCount int                 `json:"total_count"`
	Took       time.Duration       `json:"took" swaggertype:"integer" example:"1500000"`
}

SearchResult represents the result of a search query

type SearchResultItem

type SearchResultItem struct {
	DocumentID string    `json:"document_id"`
	SourceID   string    `json:"source_id"`
	Title      string    `json:"title"`
	Path       string    `json:"path"`
	MimeType   string    `json:"mime_type"`
	Snippet    string    `json:"snippet"`
	Score      float64   `json:"score"`
	IndexedAt  time.Time `json:"indexed_at"`
}

SearchResultItem represents a single search result at document level.

type Session

type Session struct {
	ID           string    `json:"id"`
	UserID       string    `json:"user_id"`
	Token        string    `json:"token"`
	RefreshToken string    `json:"refresh_token,omitempty"`
	ExpiresAt    time.Time `json:"expires_at"`
	CreatedAt    time.Time `json:"created_at"`
	UserAgent    string    `json:"user_agent,omitempty"`
	IPAddress    string    `json:"ip_address,omitempty"`
}

Session represents an authenticated user session

func (*Session) IsExpired

func (s *Session) IsExpired() bool

IsExpired checks if the session has expired

type Settings

type Settings struct {
	TeamID string `json:"team_id"`

	// Search Defaults
	DefaultSearchMode SearchMode `json:"default_search_mode"`
	ResultsPerPage    int        `json:"results_per_page"`
	MaxResultsPerPage int        `json:"max_results_per_page"`

	// Sync Configuration
	SyncIntervalMinutes int                    `json:"sync_interval_minutes"`
	SyncEnabled         bool                   `json:"sync_enabled"`
	SyncExclusions      *SyncExclusionSettings `json:"sync_exclusions,omitempty"`

	// Metadata
	UpdatedAt time.Time `json:"updated_at"`
	UpdatedBy string    `json:"updated_by"` // User ID
}

Settings holds team-wide configuration Note: AI configuration (provider, model, API keys) is managed via AISettings and the /settings/ai endpoint, not here. Note: Semantic/vector search is now controlled via CapabilityPreferences.

func DefaultSettings

func DefaultSettings(teamID string) *Settings

DefaultSettings returns sensible defaults for a new team

type Source

type Source struct {
	ID           string       `json:"id"`
	Name         string       `json:"name"`
	ProviderType ProviderType `json:"provider_type"`
	Config       SourceConfig `json:"config"`
	Enabled      bool         `json:"enabled"`
	CreatedAt    time.Time    `json:"created_at"`
	UpdatedAt    time.Time    `json:"updated_at"`
	CreatedBy    string       `json:"created_by"` // User ID of creator

	// ConnectionID references the connector connection for authentication
	ConnectionID string `json:"connection_id,omitempty"`

	// Containers lists the containers to index (typed)
	// Empty means index all accessible containers
	// Examples: repos for GitHub, channels for Slack, folders for Drive
	Containers []Container `json:"containers,omitempty"`
}

Source represents a data source to index

type SourceConfig

type SourceConfig struct {
	// Common fields
	CredentialID string `json:"credential_id,omitempty"`

	// GitHub/GitLab
	Owner      string   `json:"owner,omitempty"`
	Repository string   `json:"repository,omitempty"`
	Branch     string   `json:"branch,omitempty"`
	Paths      []string `json:"paths,omitempty"`

	// Slack
	Channels []string `json:"channels,omitempty"`

	// Notion
	DatabaseIDs []string `json:"database_ids,omitempty"`
	PageIDs     []string `json:"page_ids,omitempty"`

	// Confluence
	SpaceKeys []string `json:"space_keys,omitempty"`

	// Google Drive
	FolderIDs []string `json:"folder_ids,omitempty"`

	// Jira
	ProjectKeys []string `json:"project_keys,omitempty"`
	JQL         string   `json:"jql,omitempty"`

	// Generic
	BaseURL string            `json:"base_url,omitempty"`
	Extra   map[string]string `json:"extra,omitempty"`
}

SourceConfig holds provider-specific configuration

type SourceSummary

type SourceSummary struct {
	Source        *Source    `json:"source"`
	DocumentCount int        `json:"document_count"`
	LastSyncAt    *time.Time `json:"last_sync_at,omitempty"`
	SyncStatus    string     `json:"sync_status"`
}

SourceSummary provides a summary of a source's state

type SyncExclusionSettings

type SyncExclusionSettings struct {
	// EnabledPatterns are the default patterns that are currently enabled
	EnabledPatterns []string `json:"enabled_patterns"`

	// DisabledPatterns are the default patterns that have been toggled off
	DisabledPatterns []string `json:"disabled_patterns"`

	// CustomPatterns are user-defined exclusion patterns
	CustomPatterns []string `json:"custom_patterns"`

	// MimeExclusions are MIME type patterns to exclude (e.g., "image/*", "font/*")
	MimeExclusions []string `json:"mime_exclusions"`
}

SyncExclusionSettings holds sync exclusion patterns configuration

func DefaultSyncExclusions

func DefaultSyncExclusions() *SyncExclusionSettings

DefaultSyncExclusions returns common file/folder patterns to exclude from sync

func (*SyncExclusionSettings) GetActiveMimeExclusions added in v0.2.1

func (s *SyncExclusionSettings) GetActiveMimeExclusions() []string

GetActiveMimeExclusions returns all active MIME type exclusion patterns

func (*SyncExclusionSettings) GetActivePatterns

func (s *SyncExclusionSettings) GetActivePatterns() []string

GetActivePatterns returns all active exclusion patterns (enabled defaults + custom)

func (*SyncExclusionSettings) HasMimeExclusions added in v0.2.1

func (s *SyncExclusionSettings) HasMimeExclusions() bool

HasMimeExclusions returns true if there are any MIME exclusion patterns

func (*SyncExclusionSettings) HasPatterns

func (s *SyncExclusionSettings) HasPatterns() bool

HasPatterns returns true if there are any active exclusion patterns

type SyncResult

type SyncResult struct {
	SourceID string    `json:"source_id"`
	Success  bool      `json:"success"`
	Stats    SyncStats `json:"stats"`
	Error    string    `json:"error,omitempty"`
	Duration float64   `json:"duration_seconds"`
	Cursor   string    `json:"cursor,omitempty"`
}

SyncResult represents the outcome of a sync operation

type SyncState

type SyncState struct {
	SourceID    string     `json:"source_id"`
	Status      SyncStatus `json:"status"`
	LastSyncAt  *time.Time `json:"last_sync_at,omitempty"`
	NextSyncAt  *time.Time `json:"next_sync_at,omitempty"`
	Cursor      string     `json:"cursor,omitempty"` // Pagination cursor for incremental sync
	Stats       SyncStats  `json:"stats"`
	Error       string     `json:"error,omitempty"`
	StartedAt   *time.Time `json:"started_at,omitempty"`
	CompletedAt *time.Time `json:"completed_at,omitempty"`
}

SyncState tracks the sync state for a source

type SyncStats

type SyncStats struct {
	DocumentsAdded   int `json:"documents_added"`
	DocumentsUpdated int `json:"documents_updated"`
	DocumentsDeleted int `json:"documents_deleted"`
	ChunksIndexed    int `json:"chunks_indexed"`
	Errors           int `json:"errors"`
}

SyncStats holds statistics for a sync operation

type SyncStatus

type SyncStatus string

SyncStatus represents the current state of a sync operation

const (
	SyncStatusIdle      SyncStatus = "idle"
	SyncStatusRunning   SyncStatus = "running"
	SyncStatusCompleted SyncStatus = "completed"
	SyncStatusFailed    SyncStatus = "failed"
)

type Task

type Task struct {
	// ID is the unique identifier for this task
	ID string `json:"id"`

	// Type identifies what kind of task this is
	Type TaskType `json:"type"`

	// TeamID is the team this task belongs to
	TeamID string `json:"team_id"`

	// Payload contains task-specific data
	// For sync_source: {"source_id": "src-123"}
	// For sync_container: {"source_id": "src-123", "container_id": "cnt-456"}
	// For sync_all: {} (empty)
	Payload map[string]string `json:"payload"`

	// Status is the current state of the task
	Status TaskStatus `json:"status"`

	// Priority determines processing order (higher = more urgent)
	// Default is 0, range is -100 to 100
	Priority int `json:"priority"`

	// Attempts is how many times this task has been attempted
	Attempts int `json:"attempts"`

	// MaxAttempts is the maximum retry count before giving up
	MaxAttempts int `json:"max_attempts"`

	// Error contains the last error message if failed
	Error string `json:"error,omitempty"`

	// CreatedAt is when the task was enqueued
	CreatedAt time.Time `json:"created_at"`

	// UpdatedAt is when the task was last modified
	UpdatedAt time.Time `json:"updated_at"`

	// StartedAt is when processing began (nil if not started)
	StartedAt *time.Time `json:"started_at,omitempty"`

	// CompletedAt is when processing finished (nil if not complete)
	CompletedAt *time.Time `json:"completed_at,omitempty"`

	// ScheduledFor is when the task should be processed (for delayed tasks)
	ScheduledFor time.Time `json:"scheduled_for"`
}

Task represents a background job to be processed by workers

func NewSyncAllTask

func NewSyncAllTask(teamID string) *Task

NewSyncAllTask creates a task to sync all sources for a team

func NewSyncContainerTask added in v0.2.1

func NewSyncContainerTask(teamID, sourceID, containerID string) *Task

NewSyncContainerTask creates a task to sync a single container within a source

func NewSyncSourceTask

func NewSyncSourceTask(teamID, sourceID string) *Task

NewSyncSourceTask creates a task to sync a specific source

func NewTask

func NewTask(taskType TaskType, teamID string, payload map[string]string) *Task

NewTask creates a new task with default values

func (*Task) CanRetry

func (t *Task) CanRetry() bool

CanRetry returns true if the task can be retried

func (*Task) ContainerID added in v0.2.1

func (t *Task) ContainerID() string

ContainerID extracts the container_id from the payload (for sync_container tasks)

func (*Task) IsReady

func (t *Task) IsReady() bool

IsReady returns true if the task is ready to be processed

func (*Task) MarkCompleted

func (t *Task) MarkCompleted()

MarkCompleted updates the task to completed state

func (*Task) MarkFailed

func (t *Task) MarkFailed(err string)

MarkFailed updates the task to failed state

func (*Task) MarkProcessing

func (t *Task) MarkProcessing()

MarkProcessing updates the task to processing state

func (*Task) Retry

func (t *Task) Retry(err string)

Retry resets the task for retry with exponential backoff

func (*Task) SourceID

func (t *Task) SourceID() string

SourceID extracts the source_id from the payload (for sync_source and sync_container tasks)

type TaskResult

type TaskResult struct {
	TaskID      string        `json:"task_id"`
	Success     bool          `json:"success"`
	Error       string        `json:"error,omitempty"`
	Duration    time.Duration `json:"duration"`
	ItemsCount  int           `json:"items_count,omitempty"`  // e.g., documents synced
	ErrorsCount int           `json:"errors_count,omitempty"` // e.g., documents failed
}

TaskResult represents the outcome of processing a task

type TaskStatus

type TaskStatus string

TaskStatus represents the current state of a task

const (
	TaskStatusPending    TaskStatus = "pending"
	TaskStatusProcessing TaskStatus = "processing"
	TaskStatusCompleted  TaskStatus = "completed"
	TaskStatusFailed     TaskStatus = "failed"
)

type TaskType

type TaskType string

TaskType identifies the type of background task

const (
	// TaskTypeSyncSource syncs a specific source
	TaskTypeSyncSource TaskType = "sync_source"
	// TaskTypeSyncAll syncs all sources for a team
	TaskTypeSyncAll TaskType = "sync_all"
	// TaskTypeSyncContainer syncs a single container within a source
	TaskTypeSyncContainer TaskType = "sync_container"
)

type Team

type Team struct {
	ID        string    `json:"id"`
	Name      string    `json:"name"`
	CreatedAt time.Time `json:"created_at"`
	UpdatedAt time.Time `json:"updated_at"`
}

Team represents an organization/team

type TokenClaims

type TokenClaims struct {
	UserID    string `json:"user_id"`
	Email     string `json:"email"`
	Role      Role   `json:"role"`
	TeamID    string `json:"team_id"`
	SessionID string `json:"session_id"`
	IssuedAt  int64  `json:"iat"`
	ExpiresAt int64  `json:"exp"`
}

TokenClaims represents the JWT token payload

type TokenRequest added in v0.2.1

type TokenRequest struct {
	GrantType    OAuthGrantType `json:"grant_type"`
	Code         string         `json:"code,omitempty"`         // For authorization_code grant
	RedirectURI  string         `json:"redirect_uri,omitempty"` // For authorization_code grant
	ClientID     string         `json:"client_id"`
	ClientSecret string         `json:"client_secret,omitempty"` // For confidential clients
	CodeVerifier string         `json:"code_verifier,omitempty"` // PKCE verifier
	RefreshToken string         `json:"refresh_token,omitempty"` // For refresh_token grant
	Resource     string         `json:"resource,omitempty"`      // RFC 8707 resource indicator
}

TokenRequest represents an OAuth 2.0 token request

type TokenResponse added in v0.2.1

type TokenResponse struct {
	AccessToken  string `json:"access_token"`
	TokenType    string `json:"token_type"`              // "Bearer"
	ExpiresIn    int64  `json:"expires_in"`              // Seconds until expiration
	RefreshToken string `json:"refresh_token,omitempty"` // Optional refresh token
	Scope        string `json:"scope,omitempty"`         // Space-delimited scopes
}

TokenResponse represents an OAuth 2.0 token response

type TokenUsage added in v0.2.2

type TokenUsage struct {
	// PromptTokens is the number of tokens in the input prompt
	PromptTokens int `json:"prompt_tokens"`

	// CompletionTokens is the number of tokens in the generated response
	CompletionTokens int `json:"completion_tokens"`

	// TotalTokens is the sum of prompt and completion tokens
	TotalTokens int `json:"total_tokens"`
}

TokenUsage tracks token consumption for an LLM request. This is useful for cost tracking and rate limiting.

type UpcomingJobs

type UpcomingJobs struct {
	// PendingTasks are tasks ready to be processed now
	PendingTasks []*Task `json:"pending_tasks"`

	// ScheduledTasks are recurring task schedules
	ScheduledTasks []*ScheduledTask `json:"scheduled_tasks"`

	// NextScheduledRun is when the next scheduled task will run
	NextScheduledRun *time.Time `json:"next_scheduled_run,omitempty"`
}

UpcomingJobs represents pending and scheduled jobs This is a value object combining different job types for the upcoming jobs view

func NewUpcomingJobs

func NewUpcomingJobs(pendingTasks []*Task, scheduledTasks []*ScheduledTask) *UpcomingJobs

NewUpcomingJobs creates a new upcoming jobs value object

type User

type User struct {
	ID           string     `json:"id"`
	Email        string     `json:"email"`
	PasswordHash string     `json:"-"` // Never serialize
	Name         string     `json:"name"`
	Role         Role       `json:"role"`
	TeamID       string     `json:"team_id"`
	Active       bool       `json:"active"`
	CreatedAt    time.Time  `json:"created_at"`
	UpdatedAt    time.Time  `json:"updated_at"`
	LastLoginAt  *time.Time `json:"last_login_at,omitempty"`
}

User represents a team member

func (*User) CanManageSources

func (u *User) CanManageSources() bool

CanManageSources checks if the user can create/delete sources

func (*User) CanManageUsers

func (u *User) CanManageUsers() bool

CanManageUsers checks if the user can create/delete other users

func (*User) CanSearch

func (u *User) CanSearch() bool

CanSearch checks if the user can perform searches

func (*User) IsAdmin

func (u *User) IsAdmin() bool

IsAdmin checks if the user has admin privileges

func (*User) ToSummary

func (u *User) ToSummary() *UserSummary

ToSummary converts a User to UserSummary

type UserSummary

type UserSummary struct {
	ID          string     `json:"id"`
	Email       string     `json:"email"`
	Name        string     `json:"name"`
	Role        Role       `json:"role"`
	Active      bool       `json:"active"`
	LastLoginAt *time.Time `json:"last_login_at,omitempty"`
}

UserSummary provides a safe view of user data (no password hash)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL