Remove AI/chat/search features, add solidtime integration and workspace setup
CI/CD Pipeline / Test (push) Successful in 22m22s
CI/CD Pipeline / Security Scan (push) Successful in 12m37s
CI/CD Pipeline / Build and Push Images (push) Failing after 2m23s

This commit is contained in:
Tomas Dvorak
2026-06-10 10:41:31 +02:00
parent 4dfdd500b4
commit 43acbfab15
51 changed files with 1284 additions and 15385 deletions
-153
View File
@@ -1,153 +0,0 @@
package models
import (
"time"
"gorm.io/gorm"
)
// AIRecommendation represents an AI-generated recommendation
type AIRecommendation struct {
ID uint `json:"id" gorm:"primaryKey"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt gorm.DeletedAt `json:"-" gorm:"index"`
// User information
UserID uint `json:"user_id" gorm:"not null;index"`
User User `json:"user,omitempty" gorm:"foreignKey:UserID"`
// Recommendation details
RecommendationType string `json:"recommendation_type" gorm:"not null;index"` // content, task, learning, connection
ContentType string `json:"content_type" gorm:"index"` // bookmark, note, task, course, user
ContentID *uint `json:"content_id,omitempty" gorm:"index"`
Title string `json:"title" gorm:"not null"`
Description string `json:"description"`
Reasoning string `json:"reasoning"` // Why this was recommended
// Content details (for display without additional queries)
ContentTitle string `json:"content_title"`
ContentURL string `json:"content_url"`
ContentPreview string `json:"content_preview"`
AuthorName string `json:"author_name"`
Tags string `json:"tags" gorm:"serializer:json"`
// Recommendation metadata
Confidence float64 `json:"confidence" gorm:"default:0.0"` // 0.0 to 1.0
Priority string `json:"priority" gorm:"default:medium"` // low, medium, high
Category string `json:"category"` // productivity, learning, collaboration, etc.
ExpiresAt *time.Time `json:"expires_at"`
Clicked bool `json:"clicked" gorm:"default:false"`
Dismissed bool `json:"dismissed" gorm:"default:false"`
ClickedAt *time.Time `json:"clicked_at"`
DismissedAt *time.Time `json:"dismissed_at"`
// Feedback
Feedback string `json:"feedback"` // helpful, not_helpful, irrelevant
FeedbackAt *time.Time `json:"feedback_at"`
FeedbackText string `json:"feedback_text"`
// Source information
SourceModel string `json:"source_model"` // Which AI model generated this
SourceVersion string `json:"source_version"` // Version of the recommendation engine
TrainingData string `json:"training_data"` // What data was used for training
}
// UserPreference represents user preferences for recommendations
type UserPreference struct {
ID uint `json:"id" gorm:"primaryKey"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt gorm.DeletedAt `json:"-" gorm:"index"`
// User information
UserID uint `json:"user_id" gorm:"not null;uniqueIndex"`
User User `json:"user,omitempty" gorm:"foreignKey:UserID"`
// Recommendation preferences
EnableRecommendations bool `json:"enable_recommendations" gorm:"default:true"`
ContentRecommendations bool `json:"content_recommendations" gorm:"default:true"`
TaskRecommendations bool `json:"task_recommendations" gorm:"default:true"`
LearningRecommendations bool `json:"learning_recommendations" gorm:"default:true"`
ConnectionRecommendations bool `json:"connection_recommendations" gorm:"default:false"`
// Frequency and timing
MaxRecommendationsPerDay int `json:"max_recommendations_per_day" gorm:"default:5"`
PreferredCategories []string `json:"preferred_categories" gorm:"serializer:json"`
BlockedCategories []string `json:"blocked_categories" gorm:"serializer:json"`
PreferredContentTypes []string `json:"preferred_content_types" gorm:"serializer:json"`
// Quality thresholds
MinConfidenceThreshold float64 `json:"min_confidence_threshold" gorm:"default:0.6"`
MaxAgeHours int `json:"max_age_hours" gorm:"default:168"` // 1 week
// Learning and adaptation
EnablePersonalization bool `json:"enable_personalization" gorm:"default:true"`
EnableFeedbackLearning bool `json:"enable_feedback_learning" gorm:"default:true"`
LastRecommendationAt *time.Time `json:"last_recommendation_at"`
}
// RecommendationInteraction tracks user interactions with recommendations
type RecommendationInteraction struct {
ID uint `json:"id" gorm:"primaryKey"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt gorm.DeletedAt `json:"-" gorm:"index"`
// Related entities
UserID uint `json:"user_id" gorm:"not null;index"`
User User `json:"user,omitempty" gorm:"foreignKey:UserID"`
RecommendationID uint `json:"recommendation_id" gorm:"not null;index"`
Recommendation AIRecommendation `json:"recommendation,omitempty" gorm:"foreignKey:RecommendationID"`
// Interaction details
InteractionType string `json:"interaction_type" gorm:"not null;index"` // view, click, dismiss, feedback, share
InteractionData string `json:"interaction_data" gorm:"serializer:json"` // Additional context
Duration int `json:"duration"` // Time spent in seconds (for views)
Context string `json:"context"` // Where the interaction occurred (dashboard, search, etc.)
// Machine learning features
UserActivityBefore string `json:"user_activity_before"` // What user was doing before
UserActivityAfter string `json:"user_activity_after"` // What user did after
SessionID string `json:"session_id"`
DeviceType string `json:"device_type"`
}
// TableName returns the table name for AIRecommendation
func (AIRecommendation) TableName() string {
return "ai_recommendations"
}
// TableName returns the table name for UserPreference
func (UserPreference) TableName() string {
return "user_preferences"
}
// TableName returns the table name for RecommendationInteraction
func (RecommendationInteraction) TableName() string {
return "recommendation_interactions"
}
// BeforeCreate hooks
func (r *AIRecommendation) BeforeCreate(tx *gorm.DB) error {
if r.Priority == "" {
r.Priority = "medium"
}
if r.Confidence == 0 {
r.Confidence = 0.5
}
return nil
}
func (up *UserPreference) BeforeCreate(tx *gorm.DB) error {
if up.MaxRecommendationsPerDay == 0 {
up.MaxRecommendationsPerDay = 5
}
if up.MinConfidenceThreshold == 0 {
up.MinConfidenceThreshold = 0.6
}
if up.MaxAgeHours == 0 {
up.MaxAgeHours = 168 // 1 week
}
return nil
}
-62
View File
@@ -1,62 +0,0 @@
package models
import (
"time"
"gorm.io/gorm"
)
// UserAISettings stores user-specific AI provider configurations
type UserAISettings struct {
ID uint `json:"id" gorm:"primaryKey"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt gorm.DeletedAt `json:"-" gorm:"index"`
UserID uint `json:"user_id" gorm:"not null;uniqueIndex"`
User User `json:"user,omitempty" gorm:"foreignKey:UserID"`
// Mistral Settings
MistralEnabled *bool `json:"mistral_enabled" gorm:"default:false"`
MistralAPIKey string `json:"-" gorm:"column:mistral_api_key"` // Encrypted
MistralModel string `json:"mistral_model" gorm:"default:mistral-small-latest"`
MistralModelThinking string `json:"mistral_model_thinking" gorm:"default:mistral-large-latest"`
// Grok Settings
GrokEnabled *bool `json:"grok_enabled" gorm:"default:false"`
GrokAPIKey string `json:"-" gorm:"column:grok_api_key"` // Encrypted
GrokBaseURL string `json:"grok_base_url" gorm:"default:https://api.x.ai/v1"`
GrokModel string `json:"grok_model" gorm:"default:grok-4-1-fast-non-reasoning-latest"`
GrokModelThinking string `json:"grok_model_thinking" gorm:"default:grok-4-1-fast-reasoning-latest"`
// DeepSeek Settings
DeepSeekEnabled *bool `json:"deepseek_enabled" gorm:"default:false"`
DeepSeekAPIKey string `json:"-" gorm:"column:deepseek_api_key"` // Encrypted
DeepSeekBaseURL string `json:"deepseek_base_url" gorm:"default:https://api.deepseek.com"`
DeepSeekModel string `json:"deepseek_model" gorm:"default:deepseek-chat"`
DeepSeekModelThinking string `json:"deepseek_model_thinking" gorm:"default:deepseek-reasoner"`
// Ollama Settings
OllamaEnabled *bool `json:"ollama_enabled" gorm:"default:false"`
OllamaBaseURL string `json:"ollama_base_url" gorm:"default:http://localhost:11434"`
OllamaModel string `json:"ollama_model" gorm:"default:llama3.1"`
OllamaModelThinking string `json:"ollama_model_thinking" gorm:"default:llama3.1"`
// LongCat Settings
LongCatEnabled *bool `json:"longcat_enabled" gorm:"default:false"`
LongCatAPIKey string `json:"-" gorm:"column:longcat_api_key"` // Encrypted
LongCatBaseURL string `json:"longcat_base_url" gorm:"default:https://api.longcat.chat"`
LongCatOpenAIEndpoint string `json:"longcat_openai_endpoint" gorm:"default:https://api.longcat.chat/openai"`
LongCatAnthropicEndpoint string `json:"longcat_anthropic_endpoint" gorm:"default:https://api.longcat.chat/anthropic"`
LongCatModel string `json:"longcat_model" gorm:"default:LongCat-Flash-Chat"`
LongCatModelThinking string `json:"longcat_model_thinking" gorm:"default:LongCat-Flash-Thinking"`
LongCatModelThinkingUpgraded string `json:"longcat_model_thinking_upgraded" gorm:"default:LongCat-Flash-Thinking-2601"`
LongCatFormat string `json:"longcat_format" gorm:"default:openai"`
// OpenRouter Settings
OpenRouterEnabled *bool `json:"openrouter_enabled" gorm:"default:false"`
OpenRouterAPIKey string `json:"-" gorm:"column:openrouter_api_key"` // Encrypted
OpenRouterBaseURL string `json:"openrouter_base_url" gorm:"default:https://openrouter.ai/api"`
OpenRouterModel string `json:"openrouter_model" gorm:"default:openrouter/auto"`
OpenRouterModelThinking string `json:"openrouter_model_thinking" gorm:"default:openrouter/auto"`
}
-56
View File
@@ -1,56 +0,0 @@
package models
import (
"time"
"gorm.io/gorm"
)
// ChatMessage represents a chat message in the AI conversation
type ChatMessage struct {
ID uint `json:"id" gorm:"primaryKey"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt gorm.DeletedAt `json:"-" gorm:"index"`
UserID uint `json:"user_id" gorm:"not null;index"`
User User `json:"user,omitempty" gorm:"foreignKey:UserID"`
Content string `json:"content" gorm:"not null"`
Role string `json:"role" gorm:"not null"` // "user" or "assistant"
// Session tracking
SessionID string `json:"session_id" gorm:"not null;index"`
// Metadata
TokenCount int `json:"token_count"`
ModelUsed string `json:"model_used"`
ProcessingMs int64 `json:"processing_ms"`
ContextItems []string `json:"context_items" gorm:"serializer:json"` // IDs of referenced items
}
// ChatSession represents a chat session
type ChatSession struct {
ID uint `json:"id" gorm:"primaryKey"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt gorm.DeletedAt `json:"-" gorm:"index"`
UserID uint `json:"user_id" gorm:"not null;index"`
User User `json:"user,omitempty" gorm:"foreignKey:UserID"`
Title string `json:"title"`
// Session metadata
MessageCount int `json:"message_count" gorm:"default:0"`
LastMessageAt *time.Time `json:"last_message_at"`
// Context configuration
IncludeBookmarks bool `json:"include_bookmarks" gorm:"default:true"`
IncludeTasks bool `json:"include_tasks" gorm:"default:true"`
IncludeFiles bool `json:"include_files" gorm:"default:true"`
IncludeNotes bool `json:"include_notes" gorm:"default:true"`
// Relationships
Messages []ChatMessage `json:"messages,omitempty" gorm:"foreignKey:SessionID"`
}
-200
View File
@@ -1,200 +0,0 @@
package models
import (
"time"
"gorm.io/gorm"
)
// ConversationType represents the type of a conversation.
type ConversationType string
const (
ConversationTypeGlobal ConversationType = "global"
ConversationTypeTeam ConversationType = "team"
ConversationTypeGroup ConversationType = "group"
ConversationTypeDM ConversationType = "dm"
ConversationTypeSelf ConversationType = "self"
ConversationTypePasswordVault ConversationType = "password_vault"
)
// ConversationMemberRole represents the role of a user in a conversation.
type ConversationMemberRole string
const (
ConversationMemberRoleOwner ConversationMemberRole = "owner"
ConversationMemberRoleAdmin ConversationMemberRole = "admin"
ConversationMemberRoleMember ConversationMemberRole = "member"
ConversationMemberRoleViewer ConversationMemberRole = "viewer"
)
// SuggestionStatus is the lifecycle state of a message suggestion.
type SuggestionStatus string
const (
SuggestionStatusPending SuggestionStatus = "pending"
SuggestionStatusAccepted SuggestionStatus = "accepted"
SuggestionStatusDismissed SuggestionStatus = "dismissed"
)
// Conversation is a user-to-user chat space (global/team/group/dm/self/password).
type Conversation struct {
ID uint `json:"id" gorm:"primaryKey"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt gorm.DeletedAt `json:"-" gorm:"index"`
Type ConversationType `json:"type" gorm:"not null;index"`
Name string `json:"name" gorm:"not null"`
Topic string `json:"topic"`
TeamID *uint `json:"team_id,omitempty" gorm:"index"`
Team *Team `json:"team,omitempty" gorm:"foreignKey:TeamID"`
CreatedBy uint `json:"created_by" gorm:"not null;index"`
Creator User `json:"creator,omitempty" gorm:"foreignKey:CreatedBy"`
IsDefault bool `json:"is_default" gorm:"default:false;index"`
IsArchived bool `json:"is_archived" gorm:"default:false;index"`
LastMessageAt *time.Time `json:"last_message_at"`
Members []ConversationMember `json:"members,omitempty" gorm:"foreignKey:ConversationID"`
Messages []Message `json:"messages,omitempty" gorm:"foreignKey:ConversationID"`
}
// ConversationMember links users to conversations.
type ConversationMember struct {
ID uint `json:"id" gorm:"primaryKey"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt gorm.DeletedAt `json:"-" gorm:"index"`
ConversationID uint `json:"conversation_id" gorm:"not null;index:idx_conv_member,unique"`
UserID uint `json:"user_id" gorm:"not null;index:idx_conv_member,unique"`
Role ConversationMemberRole `json:"role" gorm:"not null;default:member"`
JoinedAt time.Time `json:"joined_at"`
LastReadMessageID *uint `json:"last_read_message_id,omitempty" gorm:"index"`
LastReadAt *time.Time `json:"last_read_at,omitempty"`
MutedUntil *time.Time `json:"muted_until,omitempty"`
IsHidden bool `json:"is_hidden" gorm:"default:false"`
Conversation Conversation `json:"conversation,omitempty" gorm:"foreignKey:ConversationID"`
User User `json:"user,omitempty" gorm:"foreignKey:UserID"`
}
// Message is a single chat message in a conversation.
type Message struct {
ID uint `json:"id" gorm:"primaryKey"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
ConversationID uint `json:"conversation_id" gorm:"not null;index"`
Conversation Conversation `json:"conversation,omitempty" gorm:"foreignKey:ConversationID"`
SenderID uint `json:"sender_id" gorm:"not null;index"`
Sender User `json:"sender,omitempty" gorm:"foreignKey:SenderID"`
Body string `json:"body" gorm:"type:text"`
IsSensitive bool `json:"is_sensitive" gorm:"default:false"`
EditedAt *time.Time `json:"edited_at,omitempty"`
DeletedAt *time.Time `json:"deleted_at,omitempty" gorm:"index"`
MetadataJSON string `json:"metadata_json" gorm:"type:text"`
Attachments []MessageAttachment `json:"attachments,omitempty" gorm:"foreignKey:MessageID"`
References []MessageReference `json:"references,omitempty" gorm:"foreignKey:MessageID"`
Suggestions []MessageSuggestion `json:"suggestions,omitempty" gorm:"foreignKey:MessageID"`
Reactions []MessageReaction `json:"reactions,omitempty" gorm:"foreignKey:MessageID"`
}
// MessageAttachment represents file/link-style message attachments.
type MessageAttachment struct {
ID uint `json:"id" gorm:"primaryKey"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
MessageID uint `json:"message_id" gorm:"not null;index"`
Message Message `json:"message,omitempty" gorm:"foreignKey:MessageID"`
Kind string `json:"kind" gorm:"not null;index"` // file,image,youtube,github,website,bookmark,task,event,calendar,activity,learning_path,saved_search,voice_note
FileID *uint `json:"file_id,omitempty" gorm:"index"`
URL string `json:"url"`
Title string `json:"title"`
PreviewJSON string `json:"preview_json" gorm:"type:text"`
}
// MessageReference maps chat messages to Trackeep entities.
type MessageReference struct {
ID uint `json:"id" gorm:"primaryKey"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
MessageID uint `json:"message_id" gorm:"not null;index"`
Message Message `json:"message,omitempty" gorm:"foreignKey:MessageID"`
EntityType string `json:"entity_type" gorm:"not null;index"`
EntityID uint `json:"entity_id" gorm:"not null;index"`
DeepLink string `json:"deep_link" gorm:"not null"`
}
// MessageSuggestion stores non-blocking smart suggestions triggered by message text.
type MessageSuggestion struct {
ID uint `json:"id" gorm:"primaryKey"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
MessageID uint `json:"message_id" gorm:"not null;index"`
Message Message `json:"message,omitempty" gorm:"foreignKey:MessageID"`
Type string `json:"type" gorm:"not null;index"` // create_task, create_event, save_bookmark, ...
PayloadJSON string `json:"payload_json" gorm:"type:text"`
Status SuggestionStatus `json:"status" gorm:"not null;default:pending;index"`
}
// MessageReaction stores emoji reactions.
type MessageReaction struct {
ID uint `json:"id" gorm:"primaryKey"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
MessageID uint `json:"message_id" gorm:"not null;index:idx_message_reaction,unique"`
Message Message `json:"message,omitempty" gorm:"foreignKey:MessageID"`
UserID uint `json:"user_id" gorm:"not null;index:idx_message_reaction,unique"`
User User `json:"user,omitempty" gorm:"foreignKey:UserID"`
Emoji string `json:"emoji" gorm:"not null;index:idx_message_reaction,unique"`
}
// PasswordVaultItem is encrypted secret data owned by a user.
type PasswordVaultItem struct {
ID uint `json:"id" gorm:"primaryKey"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
OwnerUserID uint `json:"owner_user_id" gorm:"not null;index"`
OwnerUser User `json:"owner_user,omitempty" gorm:"foreignKey:OwnerUserID"`
Label string `json:"label" gorm:"not null"`
EncryptedSecret string `json:"-" gorm:"type:text;not null"`
EncryptedNotes string `json:"-" gorm:"type:text"`
SourceMessageID *uint `json:"source_message_id,omitempty" gorm:"index"`
SourceMessage *Message `json:"source_message,omitempty" gorm:"foreignKey:SourceMessageID"`
CreatedBy uint `json:"created_by" gorm:"not null;index"`
LastAccessedAt *time.Time `json:"last_accessed_at,omitempty"`
Shares []PasswordVaultShare `json:"shares,omitempty" gorm:"foreignKey:VaultItemID"`
}
// PasswordVaultShare controls explicit sharing of vault items.
type PasswordVaultShare struct {
ID uint `json:"id" gorm:"primaryKey"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
VaultItemID uint `json:"vault_item_id" gorm:"not null;index"`
VaultItem PasswordVaultItem `json:"vault_item,omitempty" gorm:"foreignKey:VaultItemID"`
SharedByUserID uint `json:"shared_by_user_id" gorm:"not null;index"`
SharedByUser User `json:"shared_by_user,omitempty" gorm:"foreignKey:SharedByUserID"`
TargetConversationID uint `json:"target_conversation_id" gorm:"not null;index"`
TargetConversation Conversation `json:"target_conversation,omitempty" gorm:"foreignKey:TargetConversationID"`
ExpiresAt *time.Time `json:"expires_at,omitempty"`
AllowReveal bool `json:"allow_reveal" gorm:"default:false"`
}
+12 -39
View File
@@ -127,36 +127,18 @@ func AutoMigrate() error {
{name: "BrowserExtension", model: &BrowserExtension{}},
{name: "TimeEntry", model: &TimeEntry{}},
{name: "FileAnalysis", model: &FileAnalysis{}},
{name: "ChatSession", model: &ChatSession{}},
{name: "ChatMessage", model: &ChatMessage{}},
{name: "LearningPath", model: &LearningPath{}},
{name: "LearningModule", model: &LearningModule{}},
{name: "ModuleResource", model: &ModuleResource{}},
{name: "Enrollment", model: &Enrollment{}},
{name: "Progress", model: &Progress{}},
{name: "Course", model: &Course{}},
{name: "LearningPathCourse", model: &LearningPathCourse{}},
{name: "CalendarEvent", model: &CalendarEvent{}},
{name: "RecurrenceRule", model: &RecurrenceRule{}},
{name: "CalendarSettings", model: &CalendarSettings{}},
{name: "ContentEmbedding", model: &ContentEmbedding{}},
{name: "SavedSearch", model: &SavedSearch{}},
{name: "SavedSearchTag", model: &SavedSearchTag{}},
{name: "SearchAnalytics", model: &SearchAnalytics{}},
{name: "SearchSuggestion", model: &SearchSuggestion{}},
{name: "AISummary", model: &AISummary{}},
{name: "AITaskSuggestion", model: &AITaskSuggestion{}},
{name: "UserAISettings", model: &UserAISettings{}},
{name: "UserSearchSettings", model: &UserSearchSettings{}},
{name: "UserUpdateSettings", model: &UserUpdateSettings{}},
{name: "AITagSuggestion", model: &AITagSuggestion{}},
{name: "AIContentGeneration", model: &AIContentGeneration{}},
{name: "AICodeReview", model: &AICodeReview{}},
{name: "AILearningRecommendation", model: &AILearningRecommendation{}},
{name: "AIRecommendation", model: &AIRecommendation{}},
{name: "UserPreference", model: &UserPreference{}},
{name: "RecommendationInteraction", model: &RecommendationInteraction{}},
{name: "Integration", model: &Integration{}},
{name: "LearningPath", model: &LearningPath{}},
{name: "LearningModule", model: &LearningModule{}},
{name: "ModuleResource", model: &ModuleResource{}},
{name: "Enrollment", model: &Enrollment{}},
{name: "Progress", model: &Progress{}},
{name: "Course", model: &Course{}},
{name: "LearningPathCourse", model: &LearningPathCourse{}},
{name: "CalendarEvent", model: &CalendarEvent{}},
{name: "RecurrenceRule", model: &RecurrenceRule{}},
{name: "CalendarSettings", model: &CalendarSettings{}},
{name: "UserUpdateSettings", model: &UserUpdateSettings{}},
{name: "Integration", model: &Integration{}},
{name: "SyncLog", model: &SyncLog{}},
{name: "WebhookEvent", model: &WebhookEvent{}},
{name: "ControlServiceSession", model: &ControlServiceSession{}},
@@ -208,15 +190,6 @@ func AutoMigrate() error {
{name: "MentorshipRequest", model: &MentorshipRequest{}},
{name: "YouTubeChannelCache", model: &YouTubeChannelCache{}},
{name: "VideoBookmark", model: &VideoBookmark{}},
{name: "Conversation", model: &Conversation{}},
{name: "ConversationMember", model: &ConversationMember{}},
{name: "Message", model: &Message{}},
{name: "MessageAttachment", model: &MessageAttachment{}},
{name: "MessageReference", model: &MessageReference{}},
{name: "MessageSuggestion", model: &MessageSuggestion{}},
{name: "MessageReaction", model: &MessageReaction{}},
{name: "PasswordVaultItem", model: &PasswordVaultItem{}},
{name: "PasswordVaultShare", model: &PasswordVaultShare{}},
}
criticalModels := map[string]bool{
-111
View File
@@ -1,111 +0,0 @@
package models
import (
"time"
"gorm.io/gorm"
)
// ContentEmbedding stores vector embeddings for semantic search
type ContentEmbedding struct {
ID uint `json:"id" gorm:"primaryKey"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt gorm.DeletedAt `json:"-" gorm:"index"`
// Content reference
ContentType string `json:"content_type" gorm:"not null;index"` // 'bookmark', 'task', 'note', 'file'
ContentID uint `json:"content_id" gorm:"not null;index"`
// Embedding data
Embedding string `json:"embedding" gorm:"type:text"` // JSON array of floats
Model string `json:"model" gorm:"not null"` // AI model used
Dimensions int `json:"dimensions" gorm:"not null"` // Vector dimensions
TextContent string `json:"text_content" gorm:"type:text"` // Original text for embedding
// Metadata
UserID uint `json:"user_id" gorm:"not null;index"`
User User `json:"user,omitempty" gorm:"foreignKey:UserID"`
}
// SavedSearch represents a user's saved search query
type SavedSearch struct {
ID uint `json:"id" gorm:"primaryKey"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt gorm.DeletedAt `json:"-" gorm:"index"`
UserID uint `json:"user_id" gorm:"not null;index"`
User User `json:"user,omitempty" gorm:"foreignKey:UserID"`
Name string `json:"name" gorm:"not null"`
Query string `json:"query" gorm:"not null"`
Filters string `json:"filters" gorm:"type:json"` // JSON serialized filters
Alert bool `json:"alert" gorm:"default:false"`
LastRun *time.Time `json:"last_run"`
RunCount int `json:"run_count" gorm:"default:0"`
IsPublic bool `json:"is_public" gorm:"default:false"`
Description string `json:"description"`
Tags []SavedSearchTag `json:"tags,omitempty" gorm:"many2many:saved_search_tags;"`
}
// SavedSearchTag represents tags for saved searches
type SavedSearchTag struct {
ID uint `json:"id" gorm:"primaryKey"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Name string `json:"name" gorm:"unique;not null"`
Color string `json:"color" gorm:"default:#3b82f6"`
}
// SearchAnalytics stores search analytics data
type SearchAnalytics struct {
ID uint `json:"id" gorm:"primaryKey"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt gorm.DeletedAt `json:"-" gorm:"index"`
UserID uint `json:"user_id" gorm:"not null;index"`
User User `json:"user,omitempty" gorm:"foreignKey:UserID"`
Query string `json:"query" gorm:"not null;index"`
Filters string `json:"filters" gorm:"type:json"`
ResultsCount int `json:"results_count"`
Took int `json:"took"` // Time in milliseconds
ContentType string `json:"content_type"`
ClickedResultID *uint `json:"clicked_result_id"` // Track which result was clicked
SessionID string `json:"session_id" gorm:"index"`
IPAddress string `json:"ip_address"`
UserAgent string `json:"user_agent"`
}
// SearchSuggestion represents search suggestions
type SearchSuggestion struct {
ID uint `json:"id" gorm:"primaryKey"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt gorm.DeletedAt `json:"-" gorm:"index"`
Text string `json:"text" gorm:"not null;uniqueIndex"`
Type string `json:"type" gorm:"not null"` // 'query', 'tag', 'content'
Frequency int `json:"frequency" gorm:"default:1"`
LastUsed time.Time `json:"last_used"`
ContentType *string `json:"content_type,omitempty"`
IsPublic bool `json:"is_public" gorm:"default:true"`
}
// BeforeCreate hook for ContentEmbedding
func (ce *ContentEmbedding) BeforeCreate(tx *gorm.DB) error {
// Set default model if not specified
if ce.Model == "" {
ce.Model = "text-embedding-ada-002"
}
// Set default dimensions if not specified
if ce.Dimensions == 0 {
ce.Dimensions = 1536 // Default for OpenAI embeddings
}
return nil
}