package models import ( "time" ) // BaseModel contains fields common to all models type BaseModel struct { ID string `json:"id" db:"id"` CreatedAt time.Time `json:"created_at" db:"created_at"` UpdatedAt time.Time `json:"updated_at" db:"updated_at"` } // User represents a user in the system type User struct { BaseModel Email string `json:"email" db:"email"` PasswordHash string `json:"-" db:"password_hash"` Name string `json:"name" db:"name"` Role string `json:"role" db:"role"` LastLoginAt *time.Time `json:"last_login_at,omitempty" db:"last_login_at"` IsActive bool `json:"is_active" db:"is_active"` } // UserRole constants const ( UserRoleUser = "user" UserRoleAdmin = "admin" ) // ── Channel Types ─────────────────────────── const ( ChannelTypeDirect = "direct" // 1:1 AI chat (legacy "chat") ChannelTypeGroup = "group" // multi-model conversation ChannelTypeChannel = "channel" // named, persistent, membered ) // Channel represents a conversation channel (unified: chats + channels). type Channel struct { BaseModel UserID string `json:"user_id" db:"user_id"` Title string `json:"title" db:"title"` Description string `json:"description,omitempty" db:"description"` Type string `json:"type" db:"type"` Model string `json:"model,omitempty" db:"model"` SystemPrompt string `json:"system_prompt,omitempty" db:"system_prompt"` APIConfigID *string `json:"api_config_id,omitempty" db:"api_config_id"` IsArchived bool `json:"is_archived" db:"is_archived"` IsPinned bool `json:"is_pinned" db:"is_pinned"` FolderID *string `json:"folder_id,omitempty" db:"folder_id"` } // Message represents a message in a channel type Message struct { BaseModel ChannelID string `json:"channel_id" db:"channel_id"` Role string `json:"role" db:"role"` Content string `json:"content" db:"content"` Tokens int `json:"tokens,omitempty" db:"tokens"` Model string `json:"model,omitempty" db:"model"` FinishReason string `json:"finish_reason,omitempty" db:"finish_reason"` ParentID *string `json:"parent_id,omitempty" db:"parent_id"` ParticipantType string `json:"participant_type,omitempty" db:"participant_type"` ParticipantID string `json:"participant_id,omitempty" db:"participant_id"` } const ( MessageRoleUser = "user" MessageRoleAssistant = "assistant" MessageRoleSystem = "system" ) // ── Channel Members & Models ──────────────── type ChannelMember struct { ID string `json:"id" db:"id"` ChannelID string `json:"channel_id" db:"channel_id"` UserID string `json:"user_id" db:"user_id"` Role string `json:"role" db:"role"` JoinedAt time.Time `json:"joined_at" db:"joined_at"` LastReadAt time.Time `json:"last_read_at" db:"last_read_at"` } type ChannelModel struct { ID string `json:"id" db:"id"` ChannelID string `json:"channel_id" db:"channel_id"` ModelID string `json:"model_id" db:"model_id"` APIConfigID string `json:"api_config_id,omitempty" db:"api_config_id"` DisplayName string `json:"display_name,omitempty" db:"display_name"` SystemPrompt string `json:"system_prompt,omitempty" db:"system_prompt"` IsDefault bool `json:"is_default" db:"is_default"` } type ChannelCursor struct { ID string `json:"id" db:"id"` ChannelID string `json:"channel_id" db:"channel_id"` UserID string `json:"user_id" db:"user_id"` ActiveLeafID *string `json:"active_leaf_id,omitempty" db:"active_leaf_id"` UpdatedAt time.Time `json:"updated_at" db:"updated_at"` } // ── Organization ──────────────────────────── type Folder struct { BaseModel UserID string `json:"user_id" db:"user_id"` Name string `json:"name" db:"name"` ParentID *string `json:"parent_id,omitempty" db:"parent_id"` } type Project struct { BaseModel UserID string `json:"user_id" db:"user_id"` Name string `json:"name" db:"name"` Description string `json:"description,omitempty" db:"description"` Color string `json:"color,omitempty" db:"color"` } // ── API Config ────────────────────────────── type APIConfig struct { BaseModel UserID string `json:"user_id" db:"user_id"` Name string `json:"name" db:"name"` Provider string `json:"provider" db:"provider"` APIKey string `json:"-" db:"api_key"` BaseURL string `json:"base_url,omitempty" db:"base_url"` Model string `json:"model" db:"model"` IsDefault bool `json:"is_default" db:"is_default"` } // ── Notes (future Phase 2) ────────────────── type Note struct { BaseModel UserID string `json:"user_id" db:"user_id"` Title string `json:"title" db:"title"` Content string `json:"content" db:"content"` Tags []string `json:"tags,omitempty" db:"tags"` FolderID string `json:"folder_id,omitempty" db:"folder_id"` IsShared bool `json:"is_shared" db:"is_shared"` } type KnowledgeBase struct { BaseModel UserID string `json:"user_id" db:"user_id"` Name string `json:"name" db:"name"` Source string `json:"source" db:"source"` Settings string `json:"settings,omitempty" db:"settings"` } // ── Model Presets ────────────────────────── const ( PresetScopeGlobal = "global" PresetScopeTeam = "team" PresetScopePersonal = "personal" ) type ModelPreset struct { BaseModel Name string `json:"name" db:"name"` Description string `json:"description" db:"description"` BaseModelID string `json:"base_model_id" db:"base_model_id"` APIConfigID *string `json:"api_config_id,omitempty" db:"api_config_id"` SystemPrompt string `json:"system_prompt,omitempty" db:"system_prompt"` Temperature *float64 `json:"temperature,omitempty" db:"temperature"` MaxTokens *int `json:"max_tokens,omitempty" db:"max_tokens"` ToolsEnabled string `json:"tools_enabled,omitempty" db:"tools_enabled"` // JSON array Scope string `json:"scope" db:"scope"` TeamID *string `json:"team_id,omitempty" db:"team_id"` CreatedBy string `json:"created_by" db:"created_by"` IsShared bool `json:"is_shared" db:"is_shared"` IsActive bool `json:"is_active" db:"is_active"` Icon string `json:"icon,omitempty" db:"icon"` } // ── Settings ──────────────────────────────── type Settings struct { UserID string `json:"user_id" db:"user_id"` Theme string `json:"theme" db:"theme"` Language string `json:"language" db:"language"` Model string `json:"model" db:"model"` SystemPrompt string `json:"system_prompt,omitempty" db:"system_prompt"` MaxTokens int `json:"max_tokens" db:"max_tokens"` Temperature float64 `json:"temperature" db:"temperature"` DefaultAPIConfigID string `json:"default_api_config_id,omitempty" db:"default_api_config_id"` } type APIToken struct { BaseModel UserID string `json:"user_id" db:"user_id"` Name string `json:"name" db:"name"` Token string `json:"-" db:"token"` ExpiresAt time.Time `json:"expires_at,omitempty" db:"expires_at"` LastUsedAt *time.Time `json:"last_used_at,omitempty" db:"last_used_at"` IsActive bool `json:"is_active" db:"is_active"` }