package models import ( "time" "gorm.io/gorm" ) // Language represents a supported language type Language struct { ID string `gorm:"primaryKey;type:varchar(5)" json:"id"` Name string `gorm:"type:varchar(100);not null" json:"name"` NativeName string `gorm:"type:varchar(100);not null" json:"native_name"` Code string `gorm:"type:varchar(10);not null;uniqueIndex" json:"code"` IsDefault bool `gorm:"default:false" json:"is_default"` IsActive bool `gorm:"default:true" json:"is_active"` SortOrder int `gorm:"default:0" json:"sort_order"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` } // Translation represents a translatable string type Translation struct { ID uint `gorm:"primaryKey" json:"id"` Key string `gorm:"type:varchar(200);not null;index" json:"key"` LanguageCode string `gorm:"type:varchar(10);not null;index" json:"language_code"` Value string `gorm:"type:text;not null" json:"value"` Context string `gorm:"type:varchar(100)" json:"context"` // e.g., "navbar", "admin", "public" CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` // Relationships Language Language `gorm:"foreignKey:LanguageCode;references:Code" json:"language,omitempty"` } // ContentTranslation represents translations for content like articles, activities, etc. type ContentTranslation struct { ID uint `gorm:"primaryKey" json:"id"` ContentType string `gorm:"type:varchar(50);not null;index" json:"content_type"` // "article", "activity", "page", etc. ContentID uint `gorm:"not null;index" json:"content_id"` LanguageCode string `gorm:"type:varchar(10);not null;index" json:"language_code"` Title string `gorm:"type:varchar(500)" json:"title"` Content string `gorm:"type:text" json:"content"` Excerpt string `gorm:"type:text" json:"excerpt"` MetaTitle string `gorm:"type:varchar(200)" json:"meta_title"` MetaDescription string `gorm:"type:varchar(500)" json:"meta_description"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` // Relationships Language Language `gorm:"foreignKey:LanguageCode;references:Code" json:"language,omitempty"` } // UserLanguagePreference tracks user's preferred language type UserLanguagePreference struct { ID uint `gorm:"primaryKey" json:"id"` UserID uint `gorm:"not null;uniqueIndex" json:"user_id"` LanguageCode string `gorm:"type:varchar(10);not null" json:"language_code"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` // Relationships User User `gorm:"foreignKey:UserID" json:"user,omitempty"` Language Language `gorm:"foreignKey:LanguageCode;references:Code" json:"language,omitempty"` } // TableName returns the table name for Language model func (Language) TableName() string { return "languages" } // TableName returns the table name for Translation model func (Translation) TableName() string { return "translations" } // TableName returns the table name for ContentTranslation model func (ContentTranslation) TableName() string { return "content_translations" } // TableName returns the table name for UserLanguagePreference model func (UserLanguagePreference) TableName() string { return "user_language_preferences" } // BeforeCreate sets default values func (l *Language) BeforeCreate(tx *gorm.DB) error { if l.SortOrder == 0 { l.SortOrder = 100 } return nil } // GetDefaultLanguage returns the default language func GetDefaultLanguage(db *gorm.DB) (*Language, error) { var lang Language err := db.Where("is_default = ? AND is_active = ?", true, true).First(&lang).Error if err != nil { return nil, err } return &lang, nil } // GetActiveLanguages returns all active languages ordered by sort order func GetActiveLanguages(db *gorm.DB) ([]Language, error) { var languages []Language err := db.Where("is_active = ?", true).Order("sort_order ASC, name ASC").Find(&languages).Error return languages, err } // GetTranslation returns a translation for a specific key and language func GetTranslation(db *gorm.DB, key, languageCode string) (*Translation, error) { var translation Translation err := db.Where("key = ? AND language_code = ?", key, languageCode).First(&translation).Error if err != nil { return nil, err } return &translation, nil } // GetTranslationWithFallback returns a translation, falling back to default language if needed func GetTranslationWithFallback(db *gorm.DB, key, languageCode string) (*Translation, error) { // Try requested language first translation, err := GetTranslation(db, key, languageCode) if err == nil { return translation, nil } // Fall back to default language defaultLang, err := GetDefaultLanguage(db) if err != nil { return nil, err } return GetTranslation(db, key, defaultLang.Code) }