Documentation
¶
Overview ¶
Package domain defines the core domain types for the Sercha search platform.
Caller represents request-source identity: it is constructed at every driving entry point (HTTP search handler, MCP search handler, MCP get_document handler) and threaded through SearchContext so that pipeline stages which branch on caller type — for example, to apply policy only to a specific request origin — have a stable, well-typed signal to read.
Index ¶
- Constants
- Variables
- func GenerateID() string
- func MatchesMimePattern(mimeType string, pattern string) bool
- func PlatformDisplayName(platform PlatformType) string
- func RegisterPlatformDisplayName(platform PlatformType, displayName string)
- func RegisterPlatformMapping(provider ProviderType, platform PlatformType)
- func ShouldExcludeMimeType(mimeType string, exclusionPatterns []string) bool
- type AIModelInfo
- type AIProvider
- type AIProviderInfo
- type AISettings
- type AnalyticsPeriod
- type AuthContext
- type AuthMethod
- type AuthProvider
- type AuthorizationCode
- type AuthorizeRequest
- type AvailabilityFunc
- type AvailabilityResolver
- type Caller
- type CallerSource
- type Capability
- type CapabilityDescriptor
- type CapabilityPreferences
- type CapabilityRegistry
- type CapabilityType
- type Change
- type ChangePasswordRequest
- type ChangeType
- type ClientRegistrationRequest
- type ClientRegistrationResponse
- type CompletionRequest
- type CompletionResponse
- type CompositeAvailabilityResolver
- type Connection
- func (c *Connection) GetAccessToken() string
- func (c *Connection) HasScope(scope string) bool
- func (c *Connection) HasSecrets() bool
- func (c *Connection) IsExpired() bool
- func (c *Connection) MissingScopes(required []string) []string
- func (c *Connection) NeedsRefresh() bool
- func (c *Connection) ToSummary() *ConnectionSummary
- type ConnectionSecrets
- type ConnectionSummary
- type Container
- type CredentialSummary
- type Credentials
- type Document
- type DocumentContent
- type DocumentIDFilter
- type EmbeddingConfig
- type EmbeddingSettings
- type Filters
- type JobDetail
- type JobHistory
- type JobStats
- type LLMSettings
- type LoginRequest
- type LoginResponse
- type OAuthAccessToken
- type OAuthClient
- type OAuthGrantType
- type OAuthRefreshToken
- type PasswordResetConfirm
- type PasswordResetRequest
- type PipelinePhase
- type PlatformType
- type ProviderConfig
- type ProviderConfigSummary
- type ProviderMetadata
- type ProviderSecrets
- type ProviderType
- type QueryFrequency
- type RefreshRequest
- type RetryAttempt
- type RevokeRequest
- type Role
- type RuntimeConfig
- func (c *RuntimeConfig) CanDoHybridSearch() bool
- func (c *RuntimeConfig) CanDoLLMAssisted() bool
- func (c *RuntimeConfig) CanDoSemanticSearch() bool
- func (c *RuntimeConfig) EffectiveSearchMode() SearchMode
- func (c *RuntimeConfig) EmbeddingAvailable() bool
- func (c *RuntimeConfig) LLMAvailable() bool
- func (c *RuntimeConfig) SetEmbeddingAvailable(available bool)
- func (c *RuntimeConfig) SetLLMAvailable(available bool)
- type ScheduledTask
- type ScopeList
- type SearchAnalytics
- type SearchMetrics
- type SearchMode
- type SearchOptions
- type SearchQuery
- type SearchResult
- type SearchResultItem
- type Session
- type Settings
- type Source
- type SourceConfig
- type SourceSummary
- type SyncEvent
- type SyncExclusionSettings
- type SyncFailedDoc
- type SyncResult
- type SyncState
- type SyncStats
- type SyncStatus
- type Task
- func NewSyncAllTask(teamID string) *Task
- func NewSyncContainerTask(teamID, sourceID, containerID string) *Task
- func NewSyncSourceTask(teamID, sourceID string) *Task
- func NewSyncSourceTaskWithTrigger(teamID, sourceID string, trigger TaskTrigger) *Task
- func NewTask(taskType TaskType, teamID string, payload map[string]string) *Task
- func (t *Task) CanRetry() bool
- func (t *Task) ContainerID() string
- func (t *Task) IsReady() bool
- func (t *Task) MarkCompleted()
- func (t *Task) MarkFailed(err string)
- func (t *Task) MarkProcessing()
- func (t *Task) Retry(err string)
- func (t *Task) SourceID() string
- func (t *Task) Trigger() TaskTrigger
- type TaskResult
- type TaskStatus
- type TaskTrigger
- type TaskType
- type Team
- type TokenClaims
- type TokenRequest
- type TokenResponse
- type TokenUsage
- type UpcomingJobs
- type User
- type UserSummary
Constants ¶
const ( ScopeMCPSearch = "mcp:search" ScopeMCPDocRead = "mcp:documents:read" ScopeMCPSourcesList = "mcp:sources:list" )
MCP Scope constants
const ( AccessTokenTTL = 15 * time.Minute RefreshTokenTTL = 30 * 24 * time.Hour // 30 days AuthorizationCodeTTL = 10 * time.Minute )
Token configuration constants
Variables ¶
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 = 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 = 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
var DefaultMCPScopes = []string{ScopeMCPSearch, ScopeMCPDocRead, ScopeMCPSourcesList}
DefaultMCPScopes contains the default scopes for MCP clients
Functions ¶
func MatchesMimePattern ¶ added in v0.2.1
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
PlatformDisplayName returns a human-readable name for a platform. Custom names registered via RegisterPlatformDisplayName take precedence; otherwise the built-in switch is consulted; otherwise the raw PlatformType string is returned.
func RegisterPlatformDisplayName ¶ added in v0.4.0
func RegisterPlatformDisplayName(platform PlatformType, displayName string)
RegisterPlatformDisplayName declares a human-readable display name for a PlatformType not represented in the built-in switch. Optional companion to RegisterPlatformMapping for entirely new platforms.
func RegisterPlatformMapping ¶ added in v0.4.0
func RegisterPlatformMapping(provider ProviderType, platform PlatformType)
RegisterPlatformMapping declares that a custom ProviderType belongs to an existing PlatformType. Wiring code (typically the binary's main) calls this at startup before any sync work begins. Subsequent calls to PlatformFor and ServicesFor honour the registration.
The corresponding PlatformDisplayName falls back to the platform's built-in display name. Use RegisterPlatformDisplayName to override it for a brand-new PlatformType not represented in the built-in switch.
Safe to call concurrently with itself; not designed to race with reads.
func ShouldExcludeMimeType ¶ added in v0.2.1
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 ¶
AnalyticsPeriod represents the time range for analytics
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 // AuthMethodAppOnly represents the client_credentials (app-only) OAuth 2.0 // flow. Unlike AuthMethodOAuth2, which is a delegated grant tied to a // specific signed-in user, AuthMethodAppOnly uses a long-lived application // credential (client secret or certificate) to obtain access tokens on behalf // of the application itself — no user interaction required. // // The application credential is referenced by AppCredentialsRef on the // Connection and is never stored directly in the Connection record. The // identity scope (tenant, org, customer) the credential is valid for is // captured in TenantID. The format of both fields is provider-defined. AuthMethodAppOnly AuthMethod = "app_only" )
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 AvailabilityFunc ¶ added in v0.4.0
type AvailabilityFunc func(ctx context.Context, t CapabilityType) bool
AvailabilityFunc is a function adapter for AvailabilityResolver.
func (AvailabilityFunc) IsAvailable ¶ added in v0.4.0
func (f AvailabilityFunc) IsAvailable(ctx context.Context, t CapabilityType) bool
IsAvailable implements AvailabilityResolver.
type AvailabilityResolver ¶ added in v0.4.0
type AvailabilityResolver interface {
// IsAvailable returns true when the runtime can support this
// capability now. Returning false for a capability that has been
// registered is normal — it just means the backend isn't configured
// or healthy at this moment.
//
// For an unknown capability type (one not registered) the resolver
// SHOULD return false to surface the configuration mistake.
IsAvailable(ctx context.Context, t CapabilityType) bool
}
AvailabilityResolver answers whether a capability is currently available in the running system. Composable: a base resolver covers built-in backend checks (search engine, vector store, LLM) and consumers can wrap it to add new rules for their own capability types.
Resolvers must be safe for concurrent use. They are called from request handling paths and should not perform blocking I/O — runtime services usually expose simple availability getters that the resolver consults.
type Caller ¶ added in v0.4.0
type Caller struct {
// Source identifies the entry point that constructed this Caller.
Source CallerSource `json:"source"`
// UserID is the authenticated user performing the request.
// Empty string signals an unauthenticated or service-to-service call.
UserID string `json:"user_id"`
}
Caller carries the request-source identity for a single pipeline execution.
This is the base form understood by Core. Consumers may extend it with additional metadata (e.g. OAuth2 client identity, delegation mode) by embedding this struct in a richer type and threading the richer value through the request context — see the CallerEnricher hook on the MCP adapter for the canonical pattern.
The UserID field mirrors SearchContext.UserID — it is duplicated here so that stages receiving only the Caller have all the identity they need without an extra context lookup.
type CallerSource ¶ added in v0.4.0
type CallerSource string
CallerSource identifies the entry point through which a search request arrived. It is an open string type following the same convention as SearchMode — a small fixed set of constants covers the currently known values, but consumers should not panic on unrecognised values.
const ( // CallerSourceDirect indicates the request arrived via the direct HTTP search // API (the UI or REST API consumer). CallerSourceDirect CallerSource = "direct" // CallerSourceMCP indicates the request arrived from an OAuth2 LLM client via // the Model Context Protocol server. CallerSourceMCP CallerSource = "mcp" )
type Capability ¶
type Capability struct {
Type CapabilityType `json:"type"`
DisplayName string `json:"display_name"`
Description string `json:"description"`
Phase PipelinePhase `json:"phase"`
BackendID string `json:"backend_id,omitempty"`
DependsOn []CapabilityType `json:"depends_on,omitempty"`
Grants []CapabilityType `json:"grants,omitempty"`
// Available means the runtime can support this capability (backends are
// configured, services are healthy, etc.). Computed by the resolver.
Available bool `json:"available"`
// Enabled means the operator has turned this capability on. Reflects
// per-team preference, falling back to the descriptor's DefaultEnabled.
Enabled bool `json:"enabled"`
}
Capability is the resolved runtime state of a single capability for a particular team. Built by combining a CapabilityDescriptor with availability and persisted preferences.
func ResolveCapabilities ¶
func ResolveCapabilities( descriptors []CapabilityDescriptor, available map[CapabilityType]bool, prefs *CapabilityPreferences, ) []*Capability
ResolveCapabilities builds the runtime list of resolved Capability values from descriptors + availability + persisted preferences. Dependency cascades are enforced: a capability whose dependency is not active is marked disabled.
The function does not interpret any specific capability type — it walks descriptors generically. Adding a new capability requires only registering a descriptor (and an availability rule); no code change to this function is needed.
func (*Capability) IsActive ¶
func (c *Capability) IsActive() bool
IsActive reports whether the capability is both available and enabled — i.e. ready to use right now.
func (*Capability) IsIndexingCapability ¶
func (c *Capability) IsIndexingCapability() bool
IsIndexingCapability reports whether this is an indexing-phase capability.
func (*Capability) IsSearchCapability ¶
func (c *Capability) IsSearchCapability() bool
IsSearchCapability reports whether this is a search-phase capability.
type CapabilityDescriptor ¶ added in v0.4.0
type CapabilityDescriptor struct {
// Type is the unique string key. Must match the registry's view.
Type CapabilityType `json:"type"`
// DisplayName is the human-readable label rendered in the admin UI.
DisplayName string `json:"display_name"`
// Description is one-line guidance text rendered alongside the toggle.
Description string `json:"description"`
// Phase indicates whether this is an indexing or search capability.
Phase PipelinePhase `json:"phase"`
// BackendID is an optional tag identifying the implementation backend
// (e.g. "opensearch", "pgvector", "llm"). Used purely for UX
// (grouping, badges); the capability resolution path does not consult
// it. Empty when the capability has no specific backend.
BackendID string `json:"backend_id,omitempty"`
// DependsOn lists other capability types that must be enabled and
// available for this capability to function. The resolver cascades
// disable: if any dependency is not active, this capability is
// marked disabled.
DependsOn []CapabilityType `json:"depends_on,omitempty"`
// Grants lists capabilities that this capability enables. Reverse of
// DependsOn — purely informational for the UI today.
Grants []CapabilityType `json:"grants,omitempty"`
// DefaultEnabled is the toggle's default value when no per-team
// preference exists. The resolver uses this as the initial enabled
// state before applying stored preferences.
DefaultEnabled bool `json:"default_enabled"`
}
CapabilityDescriptor is the registered metadata for one capability.
The registry stores descriptors; the capabilities service combines them with availability checks and per-team toggle state to produce the final list of Capability values served to consumers (UI, pipeline factories).
Descriptors are pure metadata: no behaviour, no backend handles. Backend availability is computed by an AvailabilityResolver at request time so a running system reflects current state (e.g. an LLM provider added at runtime makes LLM-backed capabilities Available without restart).
type CapabilityPreferences ¶
type CapabilityPreferences struct {
TeamID string `json:"team_id"`
Toggles map[CapabilityType]bool `json:"toggles"`
UpdatedAt time.Time `json:"updated_at"`
}
CapabilityPreferences is the persisted per-team toggle state. Stored as row-per-toggle in the backing store; presented to consumers as a flat map keyed by CapabilityType.
Capabilities absent from the map fall back to the descriptor's DefaultEnabled at resolution time. This keeps the storage minimal — only explicit operator overrides are persisted.
func DefaultCapabilityPreferences ¶
func DefaultCapabilityPreferences(teamID string) *CapabilityPreferences
DefaultCapabilityPreferences returns an empty preferences struct for a team — no toggles set, every capability inherits its descriptor default.
func (*CapabilityPreferences) IsEnabled ¶ added in v0.4.0
func (p *CapabilityPreferences) IsEnabled(t CapabilityType, fallbackDefault bool) bool
IsEnabled returns the operator's preference for the given capability, defaulting to fallbackDefault when no explicit preference is set. Pass the descriptor's DefaultEnabled here so unset toggles inherit the capability's intended default rather than always returning false.
type CapabilityRegistry ¶ added in v0.4.0
type CapabilityRegistry interface {
// Register adds a descriptor to the registry. Returns an error when a
// descriptor with the same Type is already registered — duplicate
// registration is a programmer error and must surface, not silently
// overwrite.
Register(d CapabilityDescriptor) error
// All returns every registered descriptor. The returned slice is a
// copy; mutation does not affect the registry.
All() []CapabilityDescriptor
// Get returns the descriptor for the given type, or false if no
// descriptor with that type is registered.
Get(t CapabilityType) (CapabilityDescriptor, bool)
}
CapabilityRegistry is a runtime registry of capability descriptors. The capabilities service iterates the registry to know which capabilities exist; consumers (built-in or add-on) register their descriptors at startup before the service handles requests.
Registration order is not significant — descriptors expose their own dependency graph via DependsOn / Grants and the resolver walks it generically. Adding a new capability requires only registering a descriptor; no service-side code changes.
Implementations must be safe for concurrent reads. Registration is expected to happen during startup (single-goroutine) and is not performance-critical.
func NewCapabilityRegistry ¶ added in v0.4.0
func NewCapabilityRegistry() CapabilityRegistry
NewCapabilityRegistry creates an empty in-memory registry.
type CapabilityType ¶
type CapabilityType string
CapabilityType is the open-string identifier for a capability. Built-in capabilities ship with constants below; add-ons (or Core consumers wiring their own pipeline stages) MAY register additional types via the CapabilityRegistry without modifying this file.
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 (require 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"` // Eager content; ignored when LoadContent is set
LoadContent func(ctx context.Context) (string, error) `json:"-"` // Optional. When set, invoked once during processing to fetch content lazily.
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.
Content resolution: when LoadContent is non-nil, the orchestrator invokes it lazily during processing and uses the returned bytes as the document content; otherwise the eager Content field is used. Connectors with non-trivial body fetches SHOULD populate LoadContent rather than downloading inline during FetchChanges, so listing returns quickly and downloads parallelise with the per-document worker pool.
LoadContent is intentionally not serialised — the closure captures connector-scoped state (HTTP client, auth) that is not portable across process boundaries.
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 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 CompositeAvailabilityResolver ¶ added in v0.4.0
type CompositeAvailabilityResolver struct {
// contains filtered or unexported fields
}
CompositeAvailabilityResolver chains multiple resolvers; the first one to return a definitive answer for a known capability wins. This lets Core ship a base resolver and add-ons compose their own rules without modifying Core's resolver.
"Definitive answer" semantics: each resolver in the chain reports both a known/unknown signal and an availability bit. Use the AnswerableResolver wrapper or implement IsKnown directly when you need chain-aware resolution.
For the common case of "either resolver says yes → yes", use resolverAny instead.
func NewCompositeAvailabilityResolver ¶ added in v0.4.0
func NewCompositeAvailabilityResolver(resolvers ...AvailabilityResolver) *CompositeAvailabilityResolver
NewCompositeAvailabilityResolver builds a chain. The first resolver that returns true for a given type wins; if none return true the answer is false.
This means the chain is "OR" semantics: the capability is available if ANY resolver says it is. Suitable for the common pattern of a base resolver + add-on resolvers each contributing knowledge of their own capability set.
func (*CompositeAvailabilityResolver) IsAvailable ¶ added in v0.4.0
func (c *CompositeAvailabilityResolver) IsAvailable(ctx context.Context, t CapabilityType) bool
IsAvailable implements AvailabilityResolver.
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"`
// TenantID identifies the organization-level identity scope this connection
// is valid for (e.g. a directory tenant, customer ID, or org name depending
// on the provider). Only set for AuthMethodAppOnly connections; empty for
// delegated connections. The format is provider-defined.
TenantID string `json:"tenant_id,omitempty"`
// AppCredentialsRef is a reference into the secret store pointing to the
// long-lived application credential (client secret or certificate) used for
// AuthMethodAppOnly flows. It is an opaque identifier — the credential
// itself is never stored on the Connection record.
AppCredentialsRef string `json:"app_credentials_ref,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. For AppOnly: returns the in-memory cached access token if set, otherwise empty string. The actual token fetch is performed by the TokenProvider; this method is a convenience accessor for an already-cached token.
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"`
TenantID string `json:"tenant_id,omitempty"`
AppCredentialsRef string `json:"app_credentials_ref,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]any `json:"metadata,omitempty"`
}
Container represents a selectable unit within a connection. Examples: a repository, a Slack channel, a Drive folder, a Notion database.
Metadata mirrors driven.Container.Metadata's map[string]any shape — values arrive from connector listings (booleans, ints, strings) and the UI re-sends them on /sources POST. A typed map[string]string here would reject any container whose lister reports non-string metadata (e.g. GitHub's `private`/`fork` booleans, OneDrive's int `child_count`).
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 DocumentIDFilter ¶ added in v0.3.0
DocumentIDFilter expresses an authoritative document-id filter with three-case semantics designed to close a fail-open hole in the permission-aware search path.
A nil *DocumentIDFilter means "no filter" (the field is unset).
A non-nil *DocumentIDFilter has two further cases controlled by Apply:
- Apply == false: no filter is applied. (Equivalent to a nil pointer; normalise callers should prefer nil to express this.)
- Apply == true && len(IDs) == 0: authoritative deny-all. Downstream MUST return zero results; adapters MUST NOT silently treat this as "no filter".
- Apply == true && len(IDs) > 0: authoritative allow-list. Downstream MUST restrict results to exactly these IDs.
This type exists specifically because bare []string conflates "no filter" and "deny all" — a provider that returns an empty slice for a user with access to zero documents would otherwise be silently granted access to every indexed document.
func AllowDocumentIDs ¶ added in v0.3.0
func AllowDocumentIDs(ids []string) *DocumentIDFilter
AllowDocumentIDs returns a filter restricting results to the given IDs. If ids is empty, this is equivalent to DenyAllDocumentIDFilter.
func DenyAllDocumentIDFilter ¶ added in v0.3.0
func DenyAllDocumentIDFilter() *DocumentIDFilter
DenyAllDocumentIDFilter returns a filter that matches zero documents.
func (*DocumentIDFilter) IsAllowList ¶ added in v0.3.0
func (f *DocumentIDFilter) IsAllowList() bool
IsAllowList reports whether the filter is an active allow-list with at least one ID. A nil receiver or Apply==false returns false.
func (*DocumentIDFilter) IsDenyAll ¶ added in v0.3.0
func (f *DocumentIDFilter) IsDenyAll() bool
IsDenyAll reports whether the filter, if applied, denies all documents. A nil receiver or Apply==false returns false (no filter means "no denial").
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 ¶
NewJobDetail creates a new job detail value object
func (*JobDetail) WithExecutionLogs ¶
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 ¶
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 ¶
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 identifies which phase of the pipeline a capability belongs to. The registry uses this to group capabilities for the UI; consumers that gate on phase (e.g. a stage factory) may also use it.
const ( PipelinePhaseIndexing PipelinePhase = "indexing" PipelinePhaseSearch PipelinePhase = "search" )
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) map multiple ProviderTypes to one PlatformType.
Custom mappings registered via RegisterPlatformMapping take precedence over the built-in switch. Unknown providers fall through to PlatformType(provider).
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 ProviderMetadata ¶ added in v0.3.0
type ProviderMetadata struct {
Type ProviderType
DisplayName string
Platform PlatformType
IconID string
}
ProviderMetadata describes presentation details for a ProviderType. This is the single source of truth adapters consult when they need to render provider-facing UI (icons, display names) — MCP widgets, the Next.js admin UI, and any future adapter should all read from here rather than hard-coding provider strings.
IconID is a stable identifier, not a filesystem path. Each adapter maps IconID to its own asset source: the MCP adapter serves a PNG from embed.FS, the Next.js UI bundles an SVG, a hypothetical CLI renders an ASCII glyph. Keeping the domain ignorant of paths preserves the hexagonal boundary.
func AllProviderMetadata ¶ added in v0.3.0
func AllProviderMetadata() []ProviderMetadata
AllProviderMetadata returns metadata for every known provider in a stable order. Callers must not mutate the returned slice.
func MetadataFor ¶ added in v0.3.0
func MetadataFor(p ProviderType) (ProviderMetadata, bool)
MetadataFor returns metadata for a ProviderType. The second return value is false if the provider is not registered.
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. The result combines the built-in mapping with anything registered via RegisterPlatformMapping.
type QueryFrequency ¶
QueryFrequency represents how often a query appears
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 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 (*ScopeList) UnmarshalJSON ¶ added in v0.2.1
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
DocumentIDFilter *DocumentIDFilter `json:"document_id_filter,omitempty"` // Three-case filter (see DocumentIDFilter godoc). Nil = no filter.
Filters Filters `json:"filters,omitempty"`
BoostTerms map[string]float64 `json:"boost_terms,omitempty"` // term -> boost factor
// Phrases lists user-quoted phrases extracted by the query parser. Each is
// run as a match_phrase clause against title^3 and content alongside the
// main query terms — without this the standard analyser drops the quotes
// and a "merge sort" search collapses into two unrelated tokens.
Phrases []string `json:"phrases,omitempty"`
// PipelineID optionally selects a registered search pipeline by ID.
// Empty string falls back to the default ("default-search"). Callers
// can register additional pipelines via PipelineRegistry and route
// per-request by setting this field.
PipelineID string `json:"pipeline_id,omitempty"`
// Caller identifies the entity making the search request. Nil means the
// origin is unknown. Stages that gate on caller identity (e.g. sensitivity
// masker) treat nil as non-MCP (skip execution). Populated by HTTP handlers
// (CallerSourceDirect) and MCP handlers (CallerSourceMCP).
Caller *Caller `json:"caller,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"`
// Metadata carries arbitrary key-value annotations produced by pipeline
// stages and copied through from pipeline.PresentedResult.Metadata by the
// search service.
//
// This mirrors the Metadata fields already present on pipeline.Candidate
// and pipeline.PresentedResult: stages can attach derived information to a
// result (faceting hints, ranking signals, query-expansion match info,
// stage-specific outcome flags) and have it survive the projection from
// the pipeline's internal types to the public domain type.
//
// Keys are convention-based and stage-specific; the search service does
// not interpret them, it only forwards what the presenter exposes.
// Driving adapters (HTTP handlers, MCP servers, downstream services) read
// keys they care about and ignore the rest.
//
// Stages that do not need to attach metadata may leave this nil.
Metadata map[string]any `json:"metadata,omitempty"`
}
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
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 ¶
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 SyncEvent ¶ added in v0.3.0
type SyncEvent struct {
// ID is the unique identifier for this sync event log entry
ID string `json:"id"`
// TeamID is the team that owns the source being synced
TeamID string `json:"team_id"`
// SourceID is the source that was synced
SourceID string `json:"source_id"`
// SourceName is the display name of the source at sync time
SourceName string `json:"source_name"`
// ProviderType identifies the connector type (github, notion, etc.)
ProviderType ProviderType `json:"provider_type"`
// Status indicates if the sync completed successfully or failed
Status SyncStatus `json:"status"`
// DocumentsAdded is the number of new documents discovered
DocumentsAdded int `json:"documents_added"`
// DocumentsUpdated is the number of existing documents modified
DocumentsUpdated int `json:"documents_updated"`
// DocumentsDeleted is the number of documents removed
DocumentsDeleted int `json:"documents_deleted"`
// ChunksIndexed is the total number of chunks created/updated in the vector store
ChunksIndexed int `json:"chunks_indexed"`
// ErrorCount is the number of errors encountered during sync
ErrorCount int `json:"error_count"`
// ErrorMessage contains the primary error message if Status is failed
ErrorMessage string `json:"error_message,omitempty"`
// DurationSeconds is how long the sync operation took to execute
DurationSeconds float64 `json:"duration_seconds"`
// CreatedAt is when the sync event was logged
CreatedAt time.Time `json:"created_at"`
}
SyncEvent represents a logged sync operation for audit and analytics This is an entity (has identity) used to track sync history and performance
func NewSyncEvent ¶ added in v0.3.0
func NewSyncEvent( teamID string, sourceID string, sourceName string, providerType ProviderType, status SyncStatus, stats SyncStats, durationSeconds float64, ) *SyncEvent
NewSyncEvent creates a new sync event log entry for a completed sync
func (*SyncEvent) GetDuration ¶ added in v0.3.0
GetDuration returns the duration as a time.Duration
func (*SyncEvent) IsSuccessful ¶ added in v0.3.0
IsSuccessful returns true if the sync completed without failure
func (*SyncEvent) TotalDocuments ¶ added in v0.3.0
TotalDocuments returns the total number of documents affected by the sync
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 SyncFailedDoc ¶ added in v0.4.0
type SyncFailedDoc struct {
// SourceID is the parent source — the (source_id, external_id) pair
// is the primary key.
SourceID string `json:"source_id"`
// ExternalID is the connector's identifier for the doc that failed.
// Not the Sercha-internal document_id: failures often happen before
// any internal row gets created.
ExternalID string `json:"external_id"`
// AttemptCount is the number of times we've tried this doc since the
// row was created. Drives backoff and the terminal cutoff.
AttemptCount int `json:"attempt_count"`
// LastError is the error message from the most recent attempt,
// truncated by the store layer for storage hygiene.
LastError string `json:"last_error"`
// LastAttemptedAt is when the most recent attempt ran. Useful for
// "stuck since X" presentations in admin UIs.
LastAttemptedAt time.Time `json:"last_attempted_at"`
// NextRetryAfter is the earliest time the orchestrator should retry
// this doc. The retry pre-pass picks rows where
// next_retry_after <= now() AND terminal = false.
NextRetryAfter time.Time `json:"next_retry_after"`
// Terminal is true once the row has exceeded the configured maximum
// attempt count. Excluded from automatic retry; remains in the table
// for operator visibility.
Terminal bool `json:"terminal"`
// CreatedAt is when the first failure for this (source_id,
// external_id) was recorded.
CreatedAt time.Time `json:"created_at"`
}
SyncFailedDoc is the in-memory shape of one row in the sync_failed_documents skip-list table. Mirrors the schema 1:1; lives in domain so the driven port can reference it without importing postgres-specific types.
type SyncResult ¶
type SyncResult struct {
SourceID string `json:"source_id"`
Success bool `json:"success"`
Skipped bool `json:"skipped,omitempty"` // true when another sync was already in progress for this source
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 ¶
NewSyncAllTask creates a task to sync all sources for a team. Defaults to scheduled — only the periodic scheduler enqueues this variant today.
func NewSyncContainerTask ¶ added in v0.2.1
NewSyncContainerTask creates a task to sync a single container within a source. Defaults to manual because the only caller today is the admin path that adds a new container to an existing source — it's an explicit user action, not a scheduler tick.
func NewSyncSourceTask ¶
NewSyncSourceTask creates a task to sync a specific source. The trigger defaults to TaskTriggerScheduled; callers that know better (the manual HTTP handler, the webhook receiver) should use NewSyncSourceTaskWithTrigger.
func NewSyncSourceTaskWithTrigger ¶ added in v0.4.0
func NewSyncSourceTaskWithTrigger(teamID, sourceID string, trigger TaskTrigger) *Task
NewSyncSourceTaskWithTrigger constructs a sync_source task with an explicit trigger label. Used by the admin "Sync now" button (manual) and by the future webhook receiver path.
func (*Task) ContainerID ¶ added in v0.2.1
ContainerID extracts the container_id from the payload (for sync_container tasks)
func (*Task) MarkCompleted ¶
func (t *Task) MarkCompleted()
MarkCompleted updates the task to completed state
func (*Task) MarkFailed ¶
MarkFailed updates the task to failed state
func (*Task) MarkProcessing ¶
func (t *Task) MarkProcessing()
MarkProcessing updates the task to processing state
func (*Task) SourceID ¶
SourceID extracts the source_id from the payload (for sync_source and sync_container tasks)
func (*Task) Trigger ¶ added in v0.4.0
func (t *Task) Trigger() TaskTrigger
Trigger returns the TaskTrigger recorded on the payload, or TaskTriggerScheduled when absent / unrecognised. The fallback matches the previous implicit default so any task enqueued before the trigger field existed is treated as a scheduled sync.
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 TaskTrigger ¶ added in v0.4.0
type TaskTrigger string
TaskTrigger identifies why a sync task was enqueued. Carried on the task payload so the worker can thread it into the orchestrator's context; downstream observers can read it back via SyncTriggerFromContext to label sync events accurately.
"scheduled" is the historical default and what callers get if the payload key is missing — preserves backward compat for any tasks that were enqueued before the field existed.
const ( // TaskTriggerManual — a user clicked "Sync now" in the admin UI. TaskTriggerManual TaskTrigger = "manual" // TaskTriggerScheduled — the periodic scheduler tick enqueued the task. TaskTriggerScheduled TaskTrigger = "scheduled" // TaskTriggerWebhook — an external push notification (e.g. Microsoft // Graph driveItem webhook) triggered the sync. Reserved for future // wiring; no caller sets this today. TaskTriggerWebhook TaskTrigger = "webhook" )
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 ¶
CanManageSources checks if the user can create/delete sources
func (*User) CanManageUsers ¶
CanManageUsers checks if the user can create/delete other users
func (*User) ToSummary ¶
func (u *User) ToSummary() *UserSummary
ToSummary converts a User to UserSummary