models

package
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Aug 9, 2026 License: GPL-3.0 Imports: 4 Imported by: 0

Documentation

Overview

Package models holds the core entity types shared across ShellCN. These structs double as the GORM models (gorm tags live directly on them); only internal/store imports the gorm package, so the ORM never leaks outward.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrNotFound     = errors.New("not found")
	ErrConflict     = errors.New("conflict")
	ErrInvalidInput = errors.New("invalid input")
	ErrUnauthorized = errors.New("unauthorized")
	ErrForbidden    = errors.New("forbidden")
)

Domain-level sentinel errors shared across layers.

Functions

This section is empty.

Types

type AIConversation

type AIConversation struct {
	ID            string `gorm:"primaryKey" json:"id"`
	OwnerID       string `gorm:"index" json:"ownerId"`
	ConnectionID  string `gorm:"index" json:"connectionId"`
	Title         string `json:"title"`
	TitleResolved bool   `json:"titleResolved"`
	// ProviderID is the user provider used (empty = shared/global). Model records
	// which model served the thread.
	ProviderID string `json:"providerId"`
	Model      string `json:"model"`
	// Summary is the rolling compaction of older turns (see internal/ai/memory).
	Summary string `json:"-"`
	// CompactedCount is how many of the oldest messages are already folded into Summary.
	CompactedCount int       `json:"-"`
	CreatedAt      time.Time `json:"createdAt"`
	UpdatedAt      time.Time `json:"updatedAt"`
}

AIConversation is one chat thread, scoped to a user + connection. Summary holds the rolling compaction of older turns kept within the model's context window.

func (AIConversation) TableName

func (AIConversation) TableName() string

type AIMessage

type AIMessage struct {
	ID             string             `gorm:"primaryKey" json:"id"`
	ConversationID string             `gorm:"index;uniqueIndex:idx_ai_messages_conversation_seq" json:"conversationId"`
	Seq            int                `gorm:"index;uniqueIndex:idx_ai_messages_conversation_seq" json:"seq"`
	Role           string             `json:"role"` // user | assistant
	Content        string             `json:"content"`
	ToolCalls      []AIToolCallRecord `gorm:"serializer:json" json:"toolCalls"`
	Reasoning      string             `json:"reasoning,omitempty"`
	Truncated      bool               `json:"truncated,omitempty"`
	CreatedAt      time.Time          `json:"createdAt"`
}

AIMessage is one persisted turn message. ToolCalls capture the assistant's tool activity; Reasoning is optional model thinking.

func (AIMessage) TableName

func (AIMessage) TableName() string

type AIMode added in v0.1.1

type AIMode string
const (
	AIModeDisabled  AIMode = "disabled"
	AIModeReadOnly  AIMode = "read_only"
	AIModeReadWrite AIMode = "read_write"
)

Empty AIMode preserves older rows and is treated as read_only.

type AIProviderConfig

type AIProviderConfig struct {
	ID      string         `gorm:"primaryKey"`
	OwnerID string         `gorm:"index;uniqueIndex:idx_ai_provider_owner_name"`
	Kind    AIProviderKind `gorm:"index"`
	Name    string         `gorm:"uniqueIndex:idx_ai_provider_owner_name"`
	BaseURL string
	Model   string
	// APIKeyCiphertext is opaque ciphertext; the store never sees the plaintext key.
	APIKeyCiphertext []byte `json:"-"`
	CreatedAt        time.Time
	UpdatedAt        time.Time
}

AIProviderConfig is a user-scoped AI provider the owner manages themselves. The API key is stored only as ciphertext (encrypted above the store via the Vault) and never serializes to clients. Global/shared AI is config-only and has no row here.

func (AIProviderConfig) Summary

func (c AIProviderConfig) Summary() AIProviderSummary

Summary projects the row to its non-secret client form.

func (AIProviderConfig) TableName

func (AIProviderConfig) TableName() string

type AIProviderKind

type AIProviderKind string

AIProviderKind selects the engine adapter. Custom providers are just openai_compatible rows with their own name and base URL.

const (
	AIProviderOpenAI       AIProviderKind = "openai"
	AIProviderOpenRouter   AIProviderKind = "openrouter"
	AIProviderAnthropic    AIProviderKind = "anthropic"
	AIProviderGoogle       AIProviderKind = "google"
	AIProviderOpenAICompat AIProviderKind = "openai_compatible"
)

type AIProviderSummary

type AIProviderSummary struct {
	ID        string         `json:"id"`
	Kind      AIProviderKind `json:"kind"`
	Name      string         `json:"name"`
	BaseURL   string         `json:"baseUrl,omitempty"`
	Model     string         `json:"model"`
	HasKey    bool           `json:"hasKey"`
	CreatedAt time.Time      `json:"createdAt"`
	UpdatedAt time.Time      `json:"updatedAt"`
}

AIProviderSummary is the non-secret projection returned to clients: it never includes the key, only whether one is set.

type AIToolCallRecord

type AIToolCallRecord struct {
	ID     string `json:"id"`
	Name   string `json:"name"`
	Input  any    `json:"input,omitempty"`
	Output any    `json:"output,omitempty"`
	Err    string `json:"err,omitempty"`
}

AIToolCallRecord is a persisted tool call/result pair on an assistant message.

type Access

type Access string

Access is the level a grant confers on a shared resource.

const (
	AccessView       Access = "view"
	AccessManage     Access = "manage"
	AccessPrivileged Access = "privileged"
)

func ConnectionGrantAccesses added in v0.1.1

func ConnectionGrantAccesses() []Access

func CredentialGrantAccesses added in v0.1.1

func CredentialGrantAccesses() []Access

type AgentEnrollment

type AgentEnrollment struct {
	ID           string `gorm:"primaryKey"`
	ConnectionID string `gorm:"index"`
	TokenHash    string `gorm:"uniqueIndex"` // never the raw token
	Status       AgentEnrollmentStatus
	ExpiresAt    time.Time
	CreatedAt    time.Time
	UpdatedAt    time.Time
}

AgentEnrollment binds an agent install token to one connection + proxy target.

func (AgentEnrollment) TableName

func (AgentEnrollment) TableName() string

type AgentEnrollmentStatus

type AgentEnrollmentStatus string

AgentEnrollmentStatus tracks the lifecycle of an agent enrollment.

const (
	EnrollmentPending AgentEnrollmentStatus = "pending"
	EnrollmentOnline  AgentEnrollmentStatus = "online"
	EnrollmentOffline AgentEnrollmentStatus = "offline"
	EnrollmentExpired AgentEnrollmentStatus = "expired"
	EnrollmentRevoked AgentEnrollmentStatus = "revoked"
)

type AuditEntry

type AuditEntry struct {
	ID           string    `gorm:"primaryKey"`
	Time         time.Time `gorm:"index"`
	UserID       string    `gorm:"index"`
	Username     string
	Event        string `gorm:"index"` // route AuditEvent, e.g. "vm.snapshot.list"
	ConnectionID string `gorm:"index"`
	RouteID      string
	Risk         string
	Result       AuditResult
	Params       map[string]string `gorm:"serializer:json"` // secrets already redacted
	Error        string
	RemoteAddr   string
	// Source distinguishes how the operation was initiated: "http" for a direct
	// request, "ai" for an agent tool call. TurnID correlates AI-initiated calls
	// to their conversation/turn.
	Source string `gorm:"index"`
	TurnID string
}

AuditEntry is one append-only audit record. Params are redacted before write.

func (AuditEntry) TableName

func (AuditEntry) TableName() string

type AuditResult

type AuditResult string

AuditResult is the outcome recorded for an audited operation.

const (
	AuditAllowed AuditResult = "allowed"
	AuditDenied  AuditResult = "denied"
	AuditError   AuditResult = "error"
)

type Connection

type Connection struct {
	ID       string `gorm:"primaryKey"`
	Name     string
	Protocol string `gorm:"index"`
	OwnerID  string `gorm:"index"`
	// Transport is "direct" or "agent".
	Transport string
	Shared    bool

	// Config holds non-secret connection fields (host, port, …).
	Config map[string]any `gorm:"serializer:json"`
	// Secrets holds ciphertext for inline Secret==true fields, keyed by field key.
	// The store only ever sees ciphertext; encryption happens in the service layer.
	Secrets map[string][]byte `gorm:"serializer:json"`

	// Recording is the per-class recording policy (class -> disabled|manual|auto).
	// Absent/empty means recording is off, which is the default.
	Recording map[string]string `gorm:"serializer:json"`
	// RetentionDays caps how long this connection's recordings are kept; 0 = keep.
	RetentionDays int

	AIMode             AIMode
	AIAllowDestructive bool
	AIAutoApprove      bool

	CreatedAt time.Time
	UpdatedAt time.Time
}

Connection is stored config describing how to reach one target. It is owned by a user, optionally shared, and may carry inline encrypted secrets or reference reusable credentials.

func (Connection) TableName

func (Connection) TableName() string

type ConnectionFolder

type ConnectionFolder struct {
	ID        string `gorm:"primaryKey"`
	UserID    string `gorm:"index"`
	ParentID  string `gorm:"index"`
	Name      string
	Color     string
	SortOrder int
	CreatedAt time.Time
	UpdatedAt time.Time
}

ConnectionFolder is a per-user sidebar grouping for visible connections.

func (ConnectionFolder) TableName

func (ConnectionFolder) TableName() string

type ConnectionPlacement

type ConnectionPlacement struct {
	UserID       string `gorm:"primaryKey"`
	ConnectionID string `gorm:"primaryKey"`
	FolderID     string `gorm:"index"`
	SortOrder    int
	UpdatedAt    time.Time
}

ConnectionPlacement stores a user's folder and ordering preference for one accessible connection. FolderID is empty for the root list.

func (ConnectionPlacement) TableName

func (ConnectionPlacement) TableName() string

type Credential

type Credential struct {
	ID        string            `gorm:"primaryKey"`
	Name      string            `gorm:"not null"`
	Kind      string            `gorm:"index;not null"`
	OwnerID   string            `gorm:"index;not null"`
	Values    map[string]string `gorm:"serializer:json"`
	Protocols []string          `gorm:"serializer:json"`
	// EncryptedValues is encrypted JSON for secret credential fields.
	EncryptedValues []byte
	CreatedAt       time.Time
	UpdatedAt       time.Time
}

Credential is a reusable encrypted secret bundle with its own ownership and grants, referenced by many connections without exposing its value.

func (Credential) Summary

func (c Credential) Summary() CredentialSummary

Summary projects a Credential to its non-secret summary.

func (Credential) TableName

func (Credential) TableName() string

type CredentialGrant

type CredentialGrant struct {
	ID           string `gorm:"primaryKey"`
	CredentialID string `gorm:"index;uniqueIndex:idx_credgrant_cred_subject"`
	SubjectID    string `gorm:"index;uniqueIndex:idx_credgrant_cred_subject"`
	Access       Access // typically AccessView
	CreatedAt    time.Time
}

CredentialGrant shares a credential's use with a subject without readback.

func (CredentialGrant) TableName

func (CredentialGrant) TableName() string

type CredentialSummary

type CredentialSummary struct {
	ID        string            `json:"id"`
	Name      string            `json:"name"`
	Kind      string            `json:"kind"`
	OwnerID   string            `json:"ownerId,omitempty"`
	OwnerName string            `json:"ownerName,omitempty"`
	Values    map[string]string `json:"values,omitempty"`
	Protocols []string          `json:"protocols,omitempty"`
	UpdatedAt time.Time         `json:"updatedAt,omitzero"`
}

CredentialSummary is the non-secret view returned to clients for selection. It never carries secret material, encrypted blobs, or storage keys.

type Grant

type Grant struct {
	ID           string `gorm:"primaryKey"`
	ConnectionID string `gorm:"index;uniqueIndex:idx_grant_conn_subject"`
	SubjectID    string `gorm:"index;uniqueIndex:idx_grant_conn_subject"`
	Access       Access
	CreatedAt    time.Time
}

Grant is an explicit per-connection sharing grant to a subject (user).

func (Grant) TableName

func (Grant) TableName() string

type Invitation

type Invitation struct {
	ID         string `gorm:"primaryKey"`
	Email      string `gorm:"index"`
	Role       Role
	TokenHash  string `gorm:"uniqueIndex"`
	Status     InvitationStatus
	InvitedBy  string
	CreatedAt  time.Time
	ExpiresAt  time.Time
	AcceptedAt time.Time
}

Invitation is an emailed (or link-shared) offer to create an account with a preset role. Only the token hash is stored; the raw token lives in the link.

func (Invitation) Summary

func (i Invitation) Summary() InvitationSummary

Summary projects an invitation, downgrading a lapsed pending invite to expired.

func (Invitation) TableName

func (Invitation) TableName() string

type InvitationStatus

type InvitationStatus string

InvitationStatus tracks an invite through its lifecycle.

const (
	InvitePending  InvitationStatus = "pending"
	InviteAccepted InvitationStatus = "accepted"
	InviteRevoked  InvitationStatus = "revoked"
)

type InvitationSummary

type InvitationSummary struct {
	ID        string           `json:"id"`
	Email     string           `json:"email"`
	Role      Role             `json:"role"`
	Status    InvitationStatus `json:"status"`
	CreatedAt time.Time        `json:"createdAt"`
	ExpiresAt time.Time        `json:"expiresAt"`
}

InvitationSummary is the non-secret view returned to clients (no token).

type LiveStateLease added in v0.1.1

type LiveStateLease struct {
	Key          string `gorm:"primaryKey;column:lease_key"`
	InstanceID   string `gorm:"index;not null"`
	InternalURL  string
	InternalURLs string
	LeaseID      string    `gorm:"index;not null"`
	ExpiresAt    time.Time `gorm:"index"`
	CreatedAt    time.Time
	UpdatedAt    time.Time
}

func (LiveStateLease) TableName added in v0.1.1

func (LiveStateLease) TableName() string

type PluginStorageItem added in v0.1.1

type PluginStorageItem struct {
	Collection   string `gorm:"primaryKey;not null;check:plugin_storage_collection_required,collection <> ''"`
	Plugin       string `gorm:"primaryKey;not null;check:plugin_storage_plugin_required,plugin <> ''"`
	ConnectionID string `gorm:"primaryKey;not null;check:plugin_storage_connection_required,connection_id <> ''"`
	OwnerID      string `gorm:"primaryKey;not null;check:plugin_storage_owner_required,owner_id <> ''"`
	ItemKey      string `gorm:"primaryKey;not null;check:plugin_storage_key_required,item_key <> ''"`

	Value       []byte
	ContentType string
	Metadata    map[string]string `gorm:"serializer:json"`
	CreatedAt   time.Time
	UpdatedAt   time.Time
}

PluginStorageItem is generic plugin-owned platform object storage. Core owns the scope columns so plugins never receive raw database access.

func (PluginStorageItem) TableName added in v0.1.1

func (PluginStorageItem) TableName() string

func (PluginStorageItem) Validate added in v0.1.1

func (i PluginStorageItem) Validate() error

type PolicyRule

type PolicyRule struct {
	ID         string    `gorm:"primaryKey"`
	Role       Role      `gorm:"index:idx_policy_rule,unique"`
	Permission string    `gorm:"index:idx_policy_rule,unique"`
	Risk       string    `gorm:"index:idx_policy_rule,unique"`
	CreatedAt  time.Time `gorm:"index"`
}

PolicyRule is an additive role grant loaded into the embedded Casbin enforcer.

func (PolicyRule) TableName

func (PolicyRule) TableName() string

type Preference

type Preference struct {
	UserID    string `gorm:"primaryKey"`
	Key       string `gorm:"primaryKey;column:pref_key"`
	Value     string // JSON-encoded value
	UpdatedAt time.Time
}

Preference is a per-user key/value (e.g. a connection's layout override).

func (Preference) TableName

func (Preference) TableName() string

type ProtocolAvailability added in v0.1.1

type ProtocolAvailability string

ProtocolAvailability gates whether a protocol plugin can be used, and by whom.

const (
	ProtocolEnabled   ProtocolAvailability = "enabled"    // usable by everyone (default)
	ProtocolAdminOnly ProtocolAvailability = "admin_only" // usable by admins only
	ProtocolDisabled  ProtocolAvailability = "disabled"   // usable by no one
)

func (ProtocolAvailability) Allows added in v0.1.1

func (a ProtocolAvailability) Allows(isAdmin bool) bool

Allows reports whether a user may see and use the protocol. An empty/unknown state is treated as enabled, so a protocol with no stored row stays available.

func (ProtocolAvailability) Valid added in v0.1.1

func (a ProtocolAvailability) Valid() bool

Valid reports whether a is a known availability state.

type ProtocolSetting added in v0.1.1

type ProtocolSetting struct {
	Protocol     string `gorm:"primaryKey"`
	Availability ProtocolAvailability
	UpdatedAt    time.Time
}

ProtocolSetting is the admin-managed availability state for one protocol, keyed by the plugin name. A protocol with no row defaults to enabled.

func (ProtocolSetting) TableName added in v0.1.1

func (ProtocolSetting) TableName() string

type Recording

type Recording struct {
	ID             string `gorm:"primaryKey"`
	UserID         string `gorm:"index"`
	Username       string
	ConnectionID   string `gorm:"index"`
	ConnectionName string
	Protocol       string `gorm:"index"`
	RouteID        string
	StreamID       string
	Class          string `gorm:"index"` // terminal | desktop
	Format         string // asciicast_v2 | webm_canvas | ...
	Authoritative  bool
	Status         RecordingStatus `gorm:"index"`
	Title          string
	StartedAt      time.Time
	EndedAt        *time.Time
	DurationMS     int64
	Size           int64
	Checksum       string // sha256 hex of the finalized blob
	StorageKey     string
	Error          string
	ExpiresAt      *time.Time `gorm:"index"` // nil = retained indefinitely
	CreatedAt      time.Time
	UpdatedAt      time.Time
}

Recording is the control-plane metadata for one captured session. The bytes live in a blob store keyed by StorageKey; this row is the queryable index and never holds secret material.

func (Recording) TableName

func (Recording) TableName() string

type RecordingStatus

type RecordingStatus string

RecordingStatus is the lifecycle state of a session recording.

const (
	RecordingPending   RecordingStatus = "pending"   // metadata created, not yet writing
	RecordingActive    RecordingStatus = "active"    // capturing
	RecordingFinalized RecordingStatus = "finalized" // complete and playable
	RecordingFailed    RecordingStatus = "failed"    // capture errored
	RecordingDiscarded RecordingStatus = "discarded" // blob removed (retention/abort)
)

type Role

type Role string

Role is a coarse platform role; fine-grained access is layered via grants.

const (
	RoleAdmin    Role = "admin"
	RoleOperator Role = "operator"
	RoleViewer   Role = "viewer"
)

type User

type User struct {
	ID           string `gorm:"primaryKey"`
	Username     string `gorm:"uniqueIndex;not null"`
	Email        string
	DisplayName  string
	Roles        []Role `gorm:"serializer:json"`
	PasswordHash string `gorm:"column:password_hash" json:"-"`
	// SessionVersion invalidates existing browser sessions when sensitive
	// account state changes.
	SessionVersion int
	Disabled       bool
	// Protected marks the root admin, which can never be deleted.
	Protected bool

	// Two-factor authentication (TOTP). TOTPSecret holds the encrypted shared
	// secret and never serializes to clients. A non-empty secret with
	// TOTPEnabled=false is an in-progress enrollment awaiting code confirmation.
	TOTPSecret         []byte   `gorm:"column:totp_secret" json:"-"`
	TOTPEnabled        bool     `gorm:"column:totp_enabled"`
	RecoveryCodeHashes []string `gorm:"serializer:json" json:"-"`
	// MFARemindedAt is when the user was last nudged to enable 2FA (nil = never).
	MFARemindedAt *time.Time

	CreatedAt time.Time
	UpdatedAt time.Time
}

User is an authenticated platform principal — used for authz and audit. It is also the GORM model; PasswordHash never serializes to clients (json:"-") and is cleared by the store before a User leaves the persistence layer.

func (User) HasRole

func (u User) HasRole(r Role) bool

func (User) TableName

func (User) TableName() string

Jump to

Keyboard shortcuts

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