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
- Variables
- type AIConversation
- type AIMessage
- type AIProviderConfig
- type AIProviderKind
- type AIProviderSummary
- type AIToolCallRecord
- type Access
- type AgentEnrollment
- type AgentEnrollmentStatus
- type AuditEntry
- type AuditResult
- type Connection
- type ConnectionFolder
- type ConnectionPlacement
- type Credential
- type CredentialGrant
- type CredentialSummary
- type Grant
- type Invitation
- type InvitationStatus
- type InvitationSummary
- type PolicyRule
- type Preference
- type Recording
- type RecordingStatus
- type Role
- type Snippet
- type User
Constants ¶
const ( AIModeDisabled = "disabled" AIModeReadOnly = "read_only" AIModeReadWrite = "read_write" )
AI mode values stored on Connection.AIMode.
Variables ¶
var ( ErrNotFound = errors.New("not found") ErrConflict = errors.New("conflict") 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.
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 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
// 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).
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.
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.
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.
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.