turash/bugulma/backend/internal/domain/localization.go
Damir Mukimov 000eab4740
Major repository reorganization and missing backend endpoints implementation
Repository Structure:
- Move files from cluttered root directory into organized structure
- Create archive/ for archived data and scraper results
- Create bugulma/ for the complete application (frontend + backend)
- Create data/ for sample datasets and reference materials
- Create docs/ for comprehensive documentation structure
- Create scripts/ for utility scripts and API tools

Backend Implementation:
- Implement 3 missing backend endpoints identified in gap analysis:
  * GET /api/v1/organizations/{id}/matching/direct - Direct symbiosis matches
  * GET /api/v1/users/me/organizations - User organizations
  * POST /api/v1/proposals/{id}/status - Update proposal status
- Add complete proposal domain model, repository, and service layers
- Create database migration for proposals table
- Fix CLI server command registration issue

API Documentation:
- Add comprehensive proposals.md API documentation
- Update README.md with Users and Proposals API sections
- Document all request/response formats, error codes, and business rules

Code Quality:
- Follow existing Go backend architecture patterns
- Add proper error handling and validation
- Match frontend expected response schemas
- Maintain clean separation of concerns (handler -> service -> repository)
2025-11-25 06:01:16 +01:00

92 lines
3.0 KiB
Go

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
}