models

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jun 3, 2026 License: GPL-3.0 Imports: 3 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

View Source
const (
	AIModeDisabled  = "disabled"
	AIModeReadOnly  = "read_only"
	AIModeReadWrite = "read_write"
)

AI mode values stored on Connection.AIMode.

Variables

View Source
var (
	ErrNotFound     = errors.New("not found")
	ErrConflict     = errors.New("conflict")
	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"`
	AutoTitled   bool   `json:"autoTitled"`
	// 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:"-"`
	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" json:"conversationId"`
	Seq            int                `gorm:"index" 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 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
	Models  []string `gorm:"serializer:json"`
	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"`
	Models    []string       `json:"models"`
	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 (
	AccessUse    Access = "use"    // connect through / read non-secret metadata
	AccessManage Access = "manage" // edit/share/delete
)

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 gates the AI agent for this connection: "" (= read_only when any AI
	// is configured), "disabled", "read_only", or "read_write". AIAllowDestructive
	// is a further opt-in (only meaningful with read_write) that exposes
	// delete/drop/truncate tools, each behind mandatory confirmation.
	AIMode             string
	AIAllowDestructive 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
	Kind      string   `gorm:"index"` // ssh_private_key, ssh_password, tls_client_cert, db_password, api_token, …
	OwnerID   string   `gorm:"index"`
	Username  string   // optional identity/principal metadata; column name kept for existing databases
	Protocols []string `gorm:"serializer:json"` // derived from credential-kind compatibility
	// EncryptedSecret is opaque ciphertext; the store never sees plaintext.
	EncryptedSecret []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 AccessUse
	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"`
	Identity  string    `json:"identity,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 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 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 Snippet

type Snippet struct {
	ID        string `gorm:"primaryKey"`
	OwnerID   string `gorm:"index"`
	Protocol  string `gorm:"index"`
	Name      string
	Body      string
	CreatedAt time.Time
	UpdatedAt time.Time
}

Snippet is a saved command/query body scoped to a protocol and owner.

func (Snippet) TableName

func (Snippet) TableName() string

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

HasRole reports whether the user holds the given role.

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