package domain import ( "context" "time" ) // Localizable defines an interface for entities that support localization type Localizable interface { GetEntityType() string GetEntityID() string } // Localization represents localized strings for any entity and field type Localization struct { ID string `gorm:"primaryKey;type:text"` EntityType string `gorm:"type:varchar(50);index"` // 'site', 'organization', 'business', 'user' EntityID string `gorm:"type:text;index"` Field string `gorm:"type:varchar(50);index"` // 'name', 'description' Locale string `gorm:"type:varchar(10);index"` // 'ru', 'en', 'tt' Value string `gorm:"type:text"` // Timestamps CreatedAt time.Time `gorm:"autoCreateTime"` UpdatedAt time.Time `gorm:"autoUpdateTime"` } // TableName specifies the table name for GORM func (Localization) TableName() string { return "localizations" } // LocalizationService provides methods for managing localized content type LocalizationService interface { GetLocalizedValue(entityType, entityID, field, locale string) (string, error) SetLocalizedValue(entityType, entityID, field, locale, value string) error GetAllLocalizedValues(entityType, entityID string) (map[string]map[string]string, error) // field -> locale -> value } // Helper methods for models to implement Localizable func (s *Site) GetEntityType() string { return "site" } func (s *Site) GetEntityID() string { return s.ID } func (o *Organization) GetEntityType() string { return "organization" } func (o *Organization) GetEntityID() string { return o.ID } func (u *User) GetEntityType() string { return "user" } func (u *User) GetEntityID() string { return u.ID } // GetLocalizedName retrieves the localized name for an entity, falling back to primary name func GetLocalizedName(entity Localizable, locale string, service LocalizationService) string { if locale == "ru" { // Return primary name for Russian switch e := entity.(type) { case *Site: return e.Name case *Organization: return e.Name case *User: return e.Name } } // Try to get localized value value, err := service.GetLocalizedValue(entity.GetEntityType(), entity.GetEntityID(), "name", locale) if err != nil || value == "" { // Fallback to primary name switch e := entity.(type) { case *Site: return e.Name case *Organization: return e.Name case *User: return e.Name } } return value } // SetLocalizedName sets the localized name for an entity func SetLocalizedName(entity Localizable, locale, value string, service LocalizationService) error { return service.SetLocalizedValue(entity.GetEntityType(), entity.GetEntityID(), "name", locale, value) } type LocalizationRepository interface { Create(ctx context.Context, loc *Localization) error GetByEntityAndField(ctx context.Context, entityType, entityID, field, locale string) (*Localization, error) GetAllByEntity(ctx context.Context, entityType, entityID string) ([]*Localization, error) Update(ctx context.Context, loc *Localization) error Delete(ctx context.Context, id string) error }