Help us shape the future of Go! Take the 2026 Go Developer Survey

models

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Aug 8, 2026 License: AGPL-3.0 Imports: 6 Imported by: 0

Documentation

Index

Constants

View Source
const (
	CleanupResolutionMerged        = "merged"
	CleanupResolutionIgnored       = "ignored"
	CleanupResolutionFalsePositive = "false_positive"
)

Cleanup resolution constants.

View Source
const (
	DocTypeProjectState = "project_state"
	DocTypeAudit        = "audit"
	DocTypeLearning     = "learning"
	DocTypePreference   = "preference"
	DocTypeTool         = "tool"
	DocTypeReference    = "reference"
)

DocType enumerates document kinds for staleness threshold lookup. Agents pick one when storing; mapped automatically from category for legacy docs.

View Source
const (
	ImportJobStatusQueued    = "queued"
	ImportJobStatusRunning   = "running"
	ImportJobStatusSucceeded = "succeeded"
	ImportJobStatusFailed    = "failed"
)

Import job status values — the lifecycle a worker drives a job through: queued -> running -> (succeeded | failed).

View Source
const (
	OverrideTypeForceCreate    = "force_create"
	OverrideTypeForceRead      = "force_read"
	OverrideTypeSettingsChange = "settings_change"
)

Override type constants for OverrideLog entries.

View Source
const (
	OverrideToolStoreMemory            = "store_memory"
	OverrideToolGetDocument            = "get_document"
	OverrideToolSearchMemory           = "search_memory"
	OverrideToolUpdateSection          = "update_section"
	OverrideToolUpdateMyTenantSettings = "update_my_tenant_settings"
	OverrideToolUpdateTenantSettings   = "update_tenant_settings"
)

Tool name constants for OverrideLog entries.

View Source
const (
	DuplicateGuardThreshold = 0.70
	ScanThreshold           = 0.85
)

Duplicate-similarity thresholds. Both use section-level cosine (best-matching section pair), tuned independently:

  • DuplicateGuardThreshold gates the write-time store_memory check (FindSimilarDocuments): new section embeddings vs every existing section.
  • ScanThreshold gates the nightly cleanup scanner (FindNearDuplicatePairs): MAX cosine over all section-pair combos per doc pair.

Kept separate so a tenant can run aggressive store-time dedup without flooding the nightly queue. ScanThreshold defaults higher — scanner output is reviewer queue noise, while the write-time guard fires once per store_memory call.

View Source
const (
	StalenessModeOff      = "off"
	StalenessModeAdvisory = "advisory"
	StalenessModeHard     = "hard"
)

Staleness mode constants for per-tenant enforcement level.

View Source
const (
	TenantTypePersonal = "personal"
	TenantTypeShared   = "shared"
)

Tenant type constants. A display/visibility classifier only — see Tenant.Type.

View Source
const (
	SelfServicePolicyOpen      = "open"
	SelfServicePolicyAdminOnly = "admin_only"
)

Self-service policy constants. The optional lock over the two self-service surfaces (feature-toggle editing, API-key creation): "open" keeps today's member/owner self-service; "admin_only" raises both to admin.

View Source
const (
	TenantUserRoleMember = "member"
	TenantUserRoleAdmin  = "admin"
	TenantUserRoleOwner  = "owner"
)

Tenant user role constants at the email->tenant mapping layer. member/admin apply to any tenant; owner is personal-tenant only — a full self-manager of their own tenant (owner ⇒ manager) that is NOT a system admin.

View Source
const (
	MaxCategoryLen    = 50
	MaxSubcategoryLen = 100
	MaxSlugLen        = 100
)

Path-segment length caps, aligned with the documents table column sizes (Document: category size:50, subcategory/slug size:100). Keeping the validation limits equal to the column widths means an over-long segment is rejected as invalid input (400/errorResult) instead of surfacing as a Postgres "value too long" error (500) at write time.

View Source
const DeletionReasonRetention = "retention_sweep"

DeletionReasonRetention is the reason recorded for retention-sweep deletions.

View Source
const EmbeddingMetadataSingletonID = 1

EmbeddingMetadataSingletonID is the fixed primary key of the single metadata row.

Variables

View Source
var BootstrapTenantID = uuid.MustParse("00000000-0000-0000-0000-000000000001")

BootstrapTenantID is the well-known UUID for the default tenant. Existing data gets assigned to this tenant during migration.

View Source
var DefaultStalenessThresholds = []StalenessThreshold{
	{DocType: DocTypeProjectState, Days: 14},
	{DocType: DocTypeAudit, Days: 30},
	{DocType: DocTypeLearning, Days: 180},
	{DocType: DocTypePreference, Days: 365},
	{DocType: DocTypeTool, Days: 90},
	{DocType: DocTypeReference, Days: 90},
}

DefaultStalenessThresholds is the seed set written on first migration. Project state decays fastest; preferences essentially never.

View Source
var ValidDocTypes = map[string]struct{}{
	DocTypeProjectState: {},
	DocTypeAudit:        {},
	DocTypeLearning:     {},
	DocTypePreference:   {},
	DocTypeTool:         {},
	DocTypeReference:    {},
}

ValidDocTypes lists all accepted doc_type values.

View Source
var ValidSelfServicePolicies = map[string]struct{}{
	SelfServicePolicyOpen:      {},
	SelfServicePolicyAdminOnly: {},
}

ValidSelfServicePolicies is the accepted set for the self-service policy — both the global config default and the per-tenant override.

View Source
var ValidStalenessModes = map[string]struct{}{
	StalenessModeOff:      {},
	StalenessModeAdvisory: {},
	StalenessModeHard:     {},
}

ValidStalenessModes is the accepted set for Tenant.StalenessMode.

View Source
var ValidTenantTypes = map[string]struct{}{
	TenantTypePersonal: {},
	TenantTypeShared:   {},
}

ValidTenantTypes is the accepted set for Tenant.Type.

View Source
var ValidTenantUserRoles = map[string]struct{}{
	TenantUserRoleMember: {},
	TenantUserRoleAdmin:  {},
	TenantUserRoleOwner:  {},
}

ValidTenantUserRoles is the accepted set for TenantUser.Role.

Functions

func BuildPath

func BuildPath(category string, subcategory *string, slug string) string

BuildPath constructs a hierarchical path from category/subcategory/slug.

func InferDocType

func InferDocType(category string, subcategory *string, slug string) string

InferDocType classifies a document by category/slug when doc_type wasn't set. Mirrors the SQL backfill rules for legacy docs so new writes land the same.

func IsValidSelfServicePolicy

func IsValidSelfServicePolicy(p string) bool

IsValidSelfServicePolicy reports whether p is an accepted self-service policy.

func IsValidTenantType

func IsValidTenantType(t string) bool

IsValidTenantType reports whether t is an accepted tenant type (personal or shared).

func ParsePath

func ParsePath(path string) (category string, subcategory *string, slug string)

ParsePath splits a hierarchical path into category, subcategory, and slug. Handles 3-part / 2-part / 1-part; single-part defaults to category "misc". 4+ segments are unmappable to the category/subcategory/slug contract and return empty ("", nil, "") so the caller skips them rather than storing a mangled slash-bearing slug.

func ValidateDocumentPath

func ValidateDocumentPath(category, slug string, subcategory *string) error

ValidateDocumentPath validates a document's (category, subcategory, slug) against the shared length + character contract. subcategory nil is allowed (no subcategory); a non-nil subcategory must itself be valid. Returns a descriptive error the caller wraps (service → ErrInvalidInput, MCP → errorResult) — this package stays free of the errors/response packages.

Types

type APIKey

type APIKey struct {
	ID        uuid.UUID  `gorm:"type:uuid;primaryKey;default:gen_random_uuid()" json:"id"`
	TenantID  uuid.UUID  `gorm:"type:uuid;not null;index" json:"tenant_id"`
	KeyHash   string     `gorm:"size:64;not null;uniqueIndex" json:"-"`
	Label     string     `gorm:"size:200;not null" json:"label"`
	Prefix    string     `gorm:"size:8;not null" json:"prefix"`
	CreatedAt time.Time  `json:"created_at"`
	RevokedAt *time.Time `json:"revoked_at,omitempty"`

	// ExpiresAt: instant after which the key stops authenticating (auth.ValidateKey).
	// NULL = never expires. Set at issue (--ttl) or by rotation's grace window.
	ExpiresAt *time.Time `json:"expires_at,omitempty"`

	// LastUsedAt: best-effort last successful validation (errors ignored). NULL =
	// never used. Admin listing uses it to spot stale keys.
	LastUsedAt *time.Time `json:"last_used_at,omitempty"`

	// SubjectID pins the key to a unified authz subject. NULL = tenant service
	// principal ("svc:<tenant_id>"); set = resolved subject id per request.
	SubjectID *string `gorm:"size:255;index" json:"subject_id,omitempty"`

	Tenant *Tenant `gorm:"foreignKey:TenantID" json:"tenant,omitempty"`
}

func (APIKey) TableName

func (APIKey) TableName() string

type CleanupQueue

type CleanupQueue struct {
	ID             uuid.UUID  `gorm:"type:uuid;primaryKey;default:gen_random_uuid()" json:"id"`
	TenantID       uuid.UUID  `gorm:"type:uuid;not null;index:idx_cleanup_pending,priority:1" json:"tenant_id"`
	DocAID         uuid.UUID  `gorm:"type:uuid;not null" json:"doc_a_id"`
	DocBID         uuid.UUID  `gorm:"type:uuid;not null" json:"doc_b_id"`
	Similarity     float64    `gorm:"not null" json:"similarity"`
	DetectedAt     time.Time  `gorm:"not null;default:NOW()" json:"detected_at"`
	ResolvedAt     *time.Time `gorm:"index:idx_cleanup_pending,priority:2" json:"resolved_at,omitempty"`
	Resolution     *string    `gorm:"size:32" json:"resolution,omitempty"`
	ResolutionNote *string    `gorm:"type:text" json:"resolution_note,omitempty"`
	MergedInto     *uuid.UUID `gorm:"type:uuid" json:"merged_into,omitempty"`
}

CleanupQueue holds near-duplicate candidates from the nightly lint scan. A scheduled agent pulls pending rows, LLM-merges, and marks them resolved.

func (CleanupQueue) TableName

func (CleanupQueue) TableName() string

type DeletionEvent

type DeletionEvent struct {
	ID           uint64     `gorm:"primaryKey;autoIncrement" json:"id"`
	TenantID     uuid.UUID  `gorm:"type:uuid;not null;index" json:"tenant_id"`
	DocumentPath string     `gorm:"type:text;not null" json:"document_path"`
	DocType      string     `gorm:"size:32" json:"doc_type,omitempty"`
	Reason       string     `gorm:"size:32;not null" json:"reason"`
	ArchivedAt   *time.Time `json:"archived_at,omitempty"`
	DeletedAt    time.Time  `gorm:"not null;default:now()" json:"deleted_at"`
}

DeletionEvent is an append-only audit row written on hard-delete (currently only the retention sweep). Kept forever — records what was removed and when.

func (DeletionEvent) TableName

func (DeletionEvent) TableName() string

type Document

type Document struct {
	ID          uuid.UUID `gorm:"type:uuid;primaryKey;default:gen_random_uuid()" json:"id"`
	TenantID    uuid.UUID `gorm:"type:uuid;not null;default:'00000000-0000-0000-0000-000000000001';index" json:"tenant_id"`
	Category    string    `gorm:"size:50;not null" json:"category"`
	Subcategory *string   `gorm:"size:100" json:"subcategory,omitempty"`
	Slug        string    `gorm:"size:100;not null" json:"slug"`
	Title       string    `gorm:"size:500;not null" json:"title"`
	DocType     string    `gorm:"size:32;not null;default:'reference';index" json:"doc_type"`
	CreatedAt   time.Time `json:"created_at"`
	UpdatedAt   time.Time `json:"updated_at"`
	// ArchivedAt marks a document retired by the retention sweep. Non-NULL =
	// excluded from all reads; hard-deleted after the delete grace period.
	ArchivedAt *time.Time `gorm:"index:idx_documents_archived_at" json:"archived_at,omitempty"`

	Tenant   *Tenant   `gorm:"foreignKey:TenantID" json:"-"`
	Sections []Section `gorm:"foreignKey:DocumentID;constraint:OnDelete:CASCADE" json:"sections,omitempty"`
}

func (Document) Path

func (d Document) Path() string

Path returns the hierarchical path like "learnings/go/gorm"

func (Document) TableName

func (Document) TableName() string

type EmbeddingMetadata

type EmbeddingMetadata struct {
	ID         uint      `gorm:"primaryKey" json:"id"`
	Provider   string    `gorm:"not null" json:"provider"`
	Model      string    `gorm:"not null" json:"model"`
	Dimensions int       `gorm:"not null" json:"dimensions"`
	UpdatedAt  time.Time `json:"updated_at"`
}

EmbeddingMetadata records the embedding identity (provider, model, dimension) that built the corpus — single row keyed by EmbeddingMetadataSingletonID. The migration guard refuses a provider/model swap on a populated corpus: it silently corrupts similarity, the duplicate guard, and retention even at the same dimension (audit #13/#16). An empty/unrecorded corpus adopts the current identity.

func (EmbeddingMetadata) TableName

func (EmbeddingMetadata) TableName() string

type ImportJob

type ImportJob struct {
	ID       uuid.UUID `gorm:"type:uuid;primaryKey;default:gen_random_uuid()" json:"id"`
	TenantID uuid.UUID `gorm:"type:uuid;not null;index" json:"tenant_id"`

	// Status is one of the ImportJobStatus* constants.
	Status  string `gorm:"size:20;not null;default:'queued'" json:"status"`
	Archive []byte `gorm:"type:bytea" json:"-"`

	// Progress counters, updated by the worker as it processes the archive.
	Total    int `gorm:"not null;default:0" json:"total"`
	Imported int `gorm:"not null;default:0" json:"imported"`
	Skipped  int `gorm:"not null;default:0" json:"skipped"`
	Failed   int `gorm:"not null;default:0" json:"failed"`

	// Error carries the terminal failure reason when Status == failed.
	Error string `json:"error,omitempty"`

	CreatedAt time.Time `json:"created_at"`
	UpdatedAt time.Time `json:"updated_at"`
}

ImportJob tracks an async document-import request: the uploaded archive (stored as bytea, bounded by config.ImportMaxUploadBytes) plus progress counters a worker updates as it extracts and ingests each document.

func (ImportJob) TableName

func (ImportJob) TableName() string

type OverrideLog

type OverrideLog struct {
	ID           uint64     `gorm:"primaryKey;autoIncrement" json:"id"`
	TenantID     uuid.UUID  `gorm:"type:uuid;not null;index:idx_override_tenant_time,priority:1" json:"tenant_id"`
	Tool         string     `gorm:"size:32;not null" json:"tool"`
	TargetID     *uuid.UUID `gorm:"type:uuid" json:"target_id,omitempty"`
	OverrideType string     `gorm:"size:32;not null" json:"override_type"`
	Reason       string     `gorm:"type:text;not null" json:"reason"`
	APIKeyID     *uuid.UUID `gorm:"type:uuid" json:"api_key_id,omitempty"`
	CreatedAt    time.Time  `gorm:"index:idx_override_tenant_time,priority:2,sort:desc" json:"created_at"`
}

OverrideLog records every force-override call against the guarded tools. Kept forever — cheap rows, valuable audit trail for detecting agent abuse.

func (OverrideLog) TableName

func (OverrideLog) TableName() string

type Section

type Section struct {
	ID         uuid.UUID       `gorm:"type:uuid;primaryKey;default:gen_random_uuid()" json:"id"`
	DocumentID uuid.UUID       `gorm:"type:uuid;not null;index:idx_section_doc_ord" json:"document_id"`
	Ordinal    int             `gorm:"not null;index:idx_section_doc_ord" json:"ordinal"`
	Heading    *string         `gorm:"size:500" json:"heading,omitempty"`
	Content    string          `gorm:"type:text;not null" json:"content"`
	Embedding  pgvector.Vector `gorm:"type:vector" json:"-"`
	VerifiedAt *time.Time      `gorm:"index:idx_sections_verified_at" json:"verified_at,omitempty"`
	CreatedAt  time.Time       `json:"created_at"`
	UpdatedAt  time.Time       `json:"updated_at"`

	Document *Document `gorm:"foreignKey:DocumentID" json:"document,omitempty"`
}

func (Section) TableName

func (Section) TableName() string

type StalenessThreshold

type StalenessThreshold struct {
	DocType string `gorm:"size:32;primaryKey" json:"doc_type"`
	Days    int    `gorm:"not null" json:"days"`
}

StalenessThreshold maps a doc_type to its staleness threshold in days. Thresholds are configurable at runtime via the staleness_thresholds table.

func (StalenessThreshold) TableName

func (StalenessThreshold) TableName() string

type Tenant

type Tenant struct {
	ID    uuid.UUID `gorm:"type:uuid;primaryKey;default:gen_random_uuid()" json:"id"`
	Name  string    `gorm:"size:200;not null;uniqueIndex" json:"name"`
	Email string    `gorm:"size:200" json:"email,omitempty"`

	// Type is a DISPLAY-ONLY classifier ("personal" | "shared") for grouping
	// tenants in the UI. It MUST NOT be read by authorization: internal/authz
	// and authorize/Check never import or inspect this field, and access
	// decisions are identical regardless of its value. New tenants default to
	// "shared"; the NOT NULL DEFAULT backfills existing rows (incl. the default
	// pool) to "shared" on AutoMigrate.
	Type string `gorm:"type:text;not null;default:'shared'" json:"type"`

	// Per-tenant feature toggles. All default to the safest behavior so a tenant
	// upgrading from pre-tightening infra sees no change unless it opts in.
	StalenessMode      string `gorm:"size:16;not null;default:'off'" json:"staleness_mode"`
	DuplicateGuard     bool   `gorm:"not null;default:false" json:"duplicate_guard"`
	CleanupScanEnabled bool   `gorm:"not null;default:false" json:"cleanup_scan_enabled"`

	// SelfServicePolicy is the per-tenant override of the global self-service
	// gate: NULL = inherit the global default; else "open" | "admin_only". Set
	// and cleared by system admins only — never self-editable.
	SelfServicePolicy *string `gorm:"column:self_service_policy" json:"self_service_policy"`

	// EffectivePolicy is the resolved self-service policy (override ?? global),
	// computed on read paths — never persisted (gorm:"-").
	EffectivePolicy string `gorm:"-" json:"effective_self_service_policy,omitempty"`

	CreatedAt time.Time `json:"created_at"`
	UpdatedAt time.Time `json:"updated_at"`
}

func (Tenant) EffectiveSelfServicePolicy

func (t Tenant) EffectiveSelfServicePolicy(globalDefault string) string

EffectiveSelfServicePolicy resolves the tenant's effective self-service policy: the per-tenant override when set and valid, else the global default when valid, else "open" (so unset everywhere means open — today's behavior).

func (Tenant) TableName

func (Tenant) TableName() string

type TenantDefaults

type TenantDefaults struct {
	StalenessMode      string
	DuplicateGuard     bool
	CleanupScanEnabled bool
}

TenantDefaults is the operator-chosen baseline for the three per-tenant toggles. It is the single shared shape for these values across config parsing and the service create-path.

func BaselineTenantDefaults

func BaselineTenantDefaults() TenantDefaults

BaselineTenantDefaults is the built-in safe-retention bundle used when the operator sets no MEMORY_DEFAULT_OPTS override: staleness_mode=hard, duplicate_guard=true, cleanup_scan_enabled=true.

type TenantUser

type TenantUser struct {
	ID uuid.UUID `gorm:"type:uuid;primaryKey;default:gen_random_uuid()" json:"id"`
	// Email is globally unique — a single email maps to exactly one tenant.
	// size 320 = RFC 5321 max (64 local + @ + 255 domain).
	Email    string    `gorm:"size:320;not null;uniqueIndex" json:"email"`
	TenantID uuid.UUID `gorm:"type:uuid;not null;index" json:"tenant_id"`
	Role     string    `gorm:"size:16;not null;default:'member'" json:"role"`

	CreatedAt time.Time `json:"created_at"`

	// Tenant belongsTo — FK on tenant_id with ON DELETE CASCADE.
	Tenant *Tenant `gorm:"foreignKey:TenantID;constraint:OnDelete:CASCADE" json:"-"`
}

TenantUser maps a verified upstream Google email to a tenant. The authlet AS consults it at sign-in to translate an OIDC identity into a tenant_id. Rows are populated manually (admin SQL); never auto-provisioned from federated claims.

func (TenantUser) TableName

func (TenantUser) TableName() string

Jump to

Keyboard shortcuts

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