package domain import ( "context" "time" ) // AddressType defines the purpose of an address type AddressType string const ( AddressTypeHeadquarters AddressType = "headquarters" AddressTypeBilling AddressType = "billing" AddressTypeShipping AddressType = "shipping" AddressTypeBranch AddressType = "branch" AddressTypeSite AddressType = "site" ) // Address represents a physical address that can be associated with organizations or sites type Address struct { ID string `gorm:"primaryKey;type:text"` // Address components Street string `gorm:"type:text"` City string `gorm:"type:text"` Region string `gorm:"type:text"` PostalCode string `gorm:"type:varchar(20)"` Country string `gorm:"type:varchar(2);default:'RU'"` // ISO country code // Full formatted address in different locales FormattedRu string `gorm:"type:text;index"` // Russian FormattedEn string `gorm:"type:text"` // English FormattedTt string `gorm:"type:text"` // Tatar // Geolocation Latitude float64 `gorm:"type:double precision;index:idx_address_location"` Longitude float64 `gorm:"type:double precision;index:idx_address_location"` // Address type and usage AddressType AddressType `gorm:"type:varchar(20);index"` // Metadata Verified bool `gorm:"default:false"` Source string `gorm:"type:text"` // OSM, manual, API, etc. // Timestamps CreatedAt time.Time `gorm:"autoCreateTime"` UpdatedAt time.Time `gorm:"autoUpdateTime"` // Associations - many-to-many relationships Organizations []Organization `gorm:"many2many:organization_addresses;"` Sites []Site `gorm:"many2many:site_addresses;"` } // TableName specifies the table name for GORM func (Address) TableName() string { return "addresses" } // AddressRepository defines operations for address management type AddressRepository interface { Create(ctx context.Context, address *Address) error GetByID(ctx context.Context, id string) (*Address, error) GetAll(ctx context.Context) ([]*Address, error) Update(ctx context.Context, address *Address) error Delete(ctx context.Context, id string) error // Find addresses by location GetWithinRadius(ctx context.Context, lat, lng, radiusKm float64) ([]*Address, error) // Find addresses by entity GetByOrganizationID(ctx context.Context, orgID string) ([]*Address, error) GetBySiteID(ctx context.Context, siteID string) ([]*Address, error) // Find or create address (deduplication) FindOrCreate(ctx context.Context, address *Address) (*Address, error) }