package domain import ( "context" "encoding/json" "time" "gorm.io/datatypes" ) // unmarshalStringSlice safely unmarshals datatypes.JSON to []string func unmarshalStringSlice(data datatypes.JSON) []string { if len(data) == 0 { return []string{} } var result []string if err := json.Unmarshal(data, &result); err != nil { // If it's not an array, return empty slice return []string{} } return result } // MarshalJSON custom marshaling to ensure arrays are always arrays func (o Organization) MarshalJSON() ([]byte, error) { type Alias Organization return json.Marshal(&struct { GalleryImages []string `json:"GalleryImages"` Certifications []string `json:"Certifications"` BusinessFocus []string `json:"BusinessFocus"` TechnicalExpertise []string `json:"TechnicalExpertise"` AvailableTechnology []string `json:"AvailableTechnology"` ManagementSystems []string `json:"ManagementSystems"` TrustNetwork []string `json:"TrustNetwork"` ExistingSymbioticRelationships []string `json:"ExistingSymbioticRelationships"` *Alias }{ GalleryImages: unmarshalStringSlice(o.GalleryImages), Certifications: unmarshalStringSlice(o.Certifications), BusinessFocus: unmarshalStringSlice(o.BusinessFocus), TechnicalExpertise: unmarshalStringSlice(o.TechnicalExpertise), AvailableTechnology: unmarshalStringSlice(o.AvailableTechnology), ManagementSystems: unmarshalStringSlice(o.ManagementSystems), TrustNetwork: unmarshalStringSlice(o.TrustNetwork), ExistingSymbioticRelationships: unmarshalStringSlice(o.ExistingSymbioticRelationships), Alias: (*Alias)(&o), }) } // OrganizationSubtype defines the specific business type of organization type OrganizationSubtype string // OrganizationSector defines the broader economic sector of organization type OrganizationSector string // Sector constants const ( SectorHealthcare OrganizationSector = "healthcare" SectorReligious OrganizationSector = "religious" SectorFoodBeverage OrganizationSector = "food_beverage" SectorRetail OrganizationSector = "retail" SectorServices OrganizationSector = "services" SectorEducation OrganizationSector = "education" SectorBeautyWellness OrganizationSector = "beauty_wellness" SectorAutomotive OrganizationSector = "automotive" SectorHospitality OrganizationSector = "hospitality" SectorManufacturing OrganizationSector = "manufacturing" SectorEnergy OrganizationSector = "energy" SectorConstruction OrganizationSector = "construction" SectorFinancial OrganizationSector = "financial" SectorEntertainment OrganizationSector = "entertainment" SectorFurniture OrganizationSector = "furniture" SectorSports OrganizationSector = "sports" SectorAgriculture OrganizationSector = "agriculture" SectorTechnology OrganizationSector = "technology" SectorInfrastructure OrganizationSector = "infrastructure" SectorGovernment OrganizationSector = "government" SectorOther OrganizationSector = "other" ) // Healthcare subtypes const ( SubtypePharmacy OrganizationSubtype = "pharmacy" SubtypeClinic OrganizationSubtype = "clinic" SubtypeDentist OrganizationSubtype = "dentist" SubtypeHospital OrganizationSubtype = "hospital" SubtypeLaboratory OrganizationSubtype = "laboratory" SubtypeTherapy OrganizationSubtype = "therapy" SubtypeOptician OrganizationSubtype = "optician" SubtypeVeterinary OrganizationSubtype = "veterinary" ) // Religious subtypes const ( SubtypeMosque OrganizationSubtype = "mosque" SubtypeTemple OrganizationSubtype = "temple" SubtypeChurch OrganizationSubtype = "church" SubtypeSynagogue OrganizationSubtype = "synagogue" SubtypeGurudwara OrganizationSubtype = "gurudwara" SubtypeBuddhistCenter OrganizationSubtype = "buddhist_center" SubtypeReligiousSchool OrganizationSubtype = "religious_school" ) // Food & Beverage subtypes const ( SubtypeRestaurant OrganizationSubtype = "restaurant" SubtypeCafe OrganizationSubtype = "cafe" SubtypeFastFood OrganizationSubtype = "fast_food" SubtypeBakery OrganizationSubtype = "bakery" SubtypeBar OrganizationSubtype = "bar" SubtypeCatering OrganizationSubtype = "catering" SubtypeFoodTruck OrganizationSubtype = "food_truck" ) // Retail subtypes const ( SubtypeGroceryStore OrganizationSubtype = "grocery_store" SubtypeDepartmentStore OrganizationSubtype = "department_store" SubtypeBoutique OrganizationSubtype = "boutique" SubtypeElectronicsStore OrganizationSubtype = "electronics_store" SubtypeBookstore OrganizationSubtype = "bookstore" SubtypeConvenienceStore OrganizationSubtype = "convenience_store" SubtypeMarket OrganizationSubtype = "market" ) // Services subtypes const ( SubtypeLawyer OrganizationSubtype = "lawyer" SubtypeAccountant OrganizationSubtype = "accountant" SubtypeConsultant OrganizationSubtype = "consultant" SubtypeITServices OrganizationSubtype = "it_services" SubtypeCleaning OrganizationSubtype = "cleaning" SubtypeRepairService OrganizationSubtype = "repair_service" SubtypeTutoring OrganizationSubtype = "tutoring" ) // Education subtypes const ( SubtypeSchool OrganizationSubtype = "school" SubtypeCollege OrganizationSubtype = "college" SubtypeUniversity OrganizationSubtype = "university" SubtypeKindergarten OrganizationSubtype = "kindergarten" SubtypeTrainingCenter OrganizationSubtype = "training_center" ) // Personal services subtypes const ( SubtypeSalon OrganizationSubtype = "salon" SubtypeSpa OrganizationSubtype = "spa" SubtypeBarber OrganizationSubtype = "barber" SubtypeGym OrganizationSubtype = "gym" SubtypeNailSalon OrganizationSubtype = "nail_salon" SubtypeMassageTherapy OrganizationSubtype = "massage_therapy" SubtypeBeautySupply OrganizationSubtype = "beauty_supply" SubtypePersonalServices OrganizationSubtype = "personal_services" ) // Automotive & Transportation subtypes const ( SubtypeCarDealership OrganizationSubtype = "car_dealership" SubtypeAutoRepair OrganizationSubtype = "auto_repair" SubtypeCarWash OrganizationSubtype = "car_wash" SubtypeAutoParts OrganizationSubtype = "auto_parts" SubtypeTireShop OrganizationSubtype = "tire_shop" SubtypeMotorcycleShop OrganizationSubtype = "motorcycle_shop" SubtypeTaxi OrganizationSubtype = "taxi" SubtypeBusStation OrganizationSubtype = "bus_station" SubtypeDelivery OrganizationSubtype = "delivery" SubtypeTransportation OrganizationSubtype = "transportation" ) // Hospitality subtypes const ( SubtypeHotel OrganizationSubtype = "hotel" SubtypeHostel OrganizationSubtype = "hostel" ) // Manufacturing & Industrial subtypes const ( SubtypeFactory OrganizationSubtype = "factory" SubtypeWorkshop OrganizationSubtype = "workshop" SubtypeManufacturing OrganizationSubtype = "manufacturing" ) // Energy subtypes const ( SubtypePowerPlant OrganizationSubtype = "power_plant" SubtypeFuelStation OrganizationSubtype = "fuel_station" SubtypeEnergy OrganizationSubtype = "energy" ) // Construction subtypes const ( SubtypeConstructionContractor OrganizationSubtype = "construction_contractor" SubtypeConstruction OrganizationSubtype = "construction" ) // Financial subtypes const ( SubtypeBank OrganizationSubtype = "bank" SubtypeInsurance OrganizationSubtype = "insurance" SubtypeFinancial OrganizationSubtype = "financial" ) // Entertainment & Cultural subtypes const ( SubtypeTheater OrganizationSubtype = "theater" SubtypeCinema OrganizationSubtype = "cinema" SubtypeMuseum OrganizationSubtype = "museum" SubtypeConcertHall OrganizationSubtype = "concert_hall" SubtypeGamingCenter OrganizationSubtype = "gaming_center" SubtypeNightclub OrganizationSubtype = "nightclub" SubtypeCultural OrganizationSubtype = "cultural" ) // Furniture subtypes const ( SubtypeFurnitureStore OrganizationSubtype = "furniture_store" SubtypeFurnitureManufacturer OrganizationSubtype = "furniture_manufacturer" SubtypeInteriorDesign OrganizationSubtype = "interior_design" SubtypeFurnitureRepair OrganizationSubtype = "furniture_repair" ) // Sports subtypes const ( SubtypeSportsClub OrganizationSubtype = "sports_club" SubtypeStadium OrganizationSubtype = "stadium" SubtypeSportsEquipment OrganizationSubtype = "sports_equipment" ) // Agriculture subtypes const ( SubtypeFarm OrganizationSubtype = "farm" SubtypeAgriculturalSupplier OrganizationSubtype = "agricultural_supplier" SubtypeGreenhouse OrganizationSubtype = "greenhouse" SubtypeLivestock OrganizationSubtype = "livestock" ) // Technology subtypes const ( SubtypeSoftwareCompany OrganizationSubtype = "software_company" SubtypeHardwareCompany OrganizationSubtype = "hardware_company" SubtypeTechSupport OrganizationSubtype = "tech_support" SubtypeWebDevelopment OrganizationSubtype = "web_development" SubtypeTelecommunications OrganizationSubtype = "telecommunications" ) // Infrastructure subtypes const ( SubtypePowerStation OrganizationSubtype = "power_station" SubtypeWaterTreatment OrganizationSubtype = "water_treatment" SubtypeWasteManagement OrganizationSubtype = "waste_management" ) // Legacy/Generic subtypes (kept for backward compatibility and migration) const ( SubtypeCommercial OrganizationSubtype = "commercial" SubtypeGovernment OrganizationSubtype = "government" SubtypeReligious OrganizationSubtype = "religious" SubtypeEducational OrganizationSubtype = "educational" SubtypeInfrastructure OrganizationSubtype = "infrastructure" SubtypeHealthcare OrganizationSubtype = "healthcare" SubtypeOther OrganizationSubtype = "other" SubtypeNeedsReview OrganizationSubtype = "needs_review" // Temporary for migration ) // IsValidSubtype checks if a subtype value is valid func IsValidSubtype(subtype OrganizationSubtype) bool { validSubtypes := map[OrganizationSubtype]bool{ // Healthcare SubtypePharmacy: true, SubtypeClinic: true, SubtypeDentist: true, SubtypeHospital: true, SubtypeLaboratory: true, SubtypeTherapy: true, SubtypeOptician: true, SubtypeVeterinary: true, // Religious SubtypeMosque: true, SubtypeTemple: true, SubtypeChurch: true, SubtypeSynagogue: true, SubtypeGurudwara: true, SubtypeBuddhistCenter: true, SubtypeReligiousSchool: true, // Food & Beverage SubtypeRestaurant: true, SubtypeCafe: true, SubtypeFastFood: true, SubtypeBakery: true, SubtypeBar: true, SubtypeCatering: true, SubtypeFoodTruck: true, // Retail SubtypeGroceryStore: true, SubtypeDepartmentStore: true, SubtypeBoutique: true, SubtypeElectronicsStore: true, SubtypeBookstore: true, SubtypeConvenienceStore: true, SubtypeMarket: true, // Services SubtypeLawyer: true, SubtypeAccountant: true, SubtypeConsultant: true, SubtypeITServices: true, SubtypeCleaning: true, SubtypeRepairService: true, SubtypeTutoring: true, // Education SubtypeSchool: true, SubtypeCollege: true, SubtypeUniversity: true, SubtypeKindergarten: true, SubtypeTrainingCenter: true, // Personal services SubtypeSalon: true, SubtypeSpa: true, SubtypeBarber: true, SubtypeGym: true, SubtypeNailSalon: true, SubtypeMassageTherapy: true, SubtypeBeautySupply: true, SubtypePersonalServices: true, // Automotive & Transportation SubtypeCarDealership: true, SubtypeAutoRepair: true, SubtypeCarWash: true, SubtypeAutoParts: true, SubtypeTireShop: true, SubtypeMotorcycleShop: true, SubtypeTaxi: true, SubtypeBusStation: true, SubtypeDelivery: true, SubtypeTransportation: true, // Hospitality SubtypeHotel: true, SubtypeHostel: true, // Manufacturing & Industrial SubtypeFactory: true, SubtypeWorkshop: true, SubtypeManufacturing: true, // Energy SubtypePowerPlant: true, SubtypeFuelStation: true, SubtypeEnergy: true, // Construction SubtypeConstructionContractor: true, SubtypeConstruction: true, // Financial SubtypeBank: true, SubtypeInsurance: true, SubtypeFinancial: true, // Entertainment & Cultural SubtypeTheater: true, SubtypeCinema: true, SubtypeMuseum: true, SubtypeConcertHall: true, SubtypeGamingCenter: true, SubtypeNightclub: true, SubtypeCultural: true, // Furniture SubtypeFurnitureStore: true, SubtypeFurnitureManufacturer: true, SubtypeInteriorDesign: true, SubtypeFurnitureRepair: true, // Sports SubtypeSportsClub: true, SubtypeStadium: true, SubtypeSportsEquipment: true, // Agriculture SubtypeFarm: true, SubtypeAgriculturalSupplier: true, SubtypeGreenhouse: true, SubtypeLivestock: true, // Technology SubtypeSoftwareCompany: true, SubtypeHardwareCompany: true, SubtypeTechSupport: true, SubtypeWebDevelopment: true, SubtypeTelecommunications: true, // Infrastructure SubtypePowerStation: true, SubtypeWaterTreatment: true, SubtypeWasteManagement: true, // Legacy/Generic SubtypeCommercial: true, SubtypeGovernment: true, SubtypeReligious: true, SubtypeEducational: true, SubtypeInfrastructure: true, SubtypeHealthcare: true, SubtypeOther: true, // Temporary SubtypeNeedsReview: true, } return validSubtypes[subtype] } // GetAllSubtypes returns all valid organization subtypes dynamically func GetAllSubtypes() []OrganizationSubtype { return []OrganizationSubtype{ // Healthcare SubtypePharmacy, SubtypeClinic, SubtypeDentist, SubtypeHospital, SubtypeLaboratory, SubtypeTherapy, SubtypeOptician, SubtypeVeterinary, // Religious SubtypeMosque, SubtypeTemple, SubtypeChurch, SubtypeSynagogue, SubtypeGurudwara, SubtypeBuddhistCenter, SubtypeReligiousSchool, // Food & Beverage SubtypeRestaurant, SubtypeCafe, SubtypeFastFood, SubtypeBakery, SubtypeBar, SubtypeCatering, SubtypeFoodTruck, // Retail SubtypeGroceryStore, SubtypeDepartmentStore, SubtypeBoutique, SubtypeElectronicsStore, SubtypeBookstore, SubtypeConvenienceStore, SubtypeMarket, // Services SubtypeLawyer, SubtypeAccountant, SubtypeConsultant, SubtypeITServices, SubtypeCleaning, SubtypeRepairService, SubtypeTutoring, // Education SubtypeSchool, SubtypeCollege, SubtypeUniversity, SubtypeKindergarten, SubtypeTrainingCenter, // Personal services SubtypeSalon, SubtypeSpa, SubtypeBarber, SubtypeGym, SubtypeNailSalon, SubtypeMassageTherapy, SubtypeBeautySupply, SubtypePersonalServices, // Automotive & Transportation SubtypeCarDealership, SubtypeAutoRepair, SubtypeCarWash, SubtypeAutoParts, SubtypeTireShop, SubtypeMotorcycleShop, SubtypeTaxi, SubtypeBusStation, SubtypeDelivery, SubtypeTransportation, // Hospitality SubtypeHotel, SubtypeHostel, // Manufacturing & Industrial SubtypeFactory, SubtypeWorkshop, SubtypeManufacturing, // Energy SubtypePowerPlant, SubtypeFuelStation, SubtypeEnergy, // Construction SubtypeConstructionContractor, SubtypeConstruction, // Financial SubtypeBank, SubtypeInsurance, SubtypeFinancial, // Entertainment & Cultural SubtypeTheater, SubtypeCinema, SubtypeMuseum, SubtypeConcertHall, SubtypeGamingCenter, SubtypeNightclub, SubtypeCultural, // Furniture SubtypeFurnitureStore, SubtypeFurnitureManufacturer, SubtypeInteriorDesign, SubtypeFurnitureRepair, // Sports SubtypeSportsClub, SubtypeStadium, SubtypeSportsEquipment, // Agriculture SubtypeFarm, SubtypeAgriculturalSupplier, SubtypeGreenhouse, SubtypeLivestock, // Technology SubtypeSoftwareCompany, SubtypeHardwareCompany, SubtypeTechSupport, SubtypeWebDevelopment, SubtypeTelecommunications, // Infrastructure SubtypePowerStation, SubtypeWaterTreatment, SubtypeWasteManagement, // Legacy/Generic SubtypeCommercial, SubtypeGovernment, SubtypeReligious, SubtypeEducational, SubtypeInfrastructure, SubtypeHealthcare, SubtypeOther, } } // GetSubtypesBySector returns subtypes that are commonly associated with a given sector // This is a helper function for filtering/validation, not a strict requirement func GetSubtypesBySector(sector OrganizationSector) []OrganizationSubtype { switch sector { case SectorHealthcare: return []OrganizationSubtype{ SubtypePharmacy, SubtypeClinic, SubtypeDentist, SubtypeHospital, SubtypeLaboratory, SubtypeTherapy, SubtypeOptician, SubtypeVeterinary, } case SectorReligious: return []OrganizationSubtype{ SubtypeMosque, SubtypeTemple, SubtypeChurch, SubtypeSynagogue, SubtypeGurudwara, SubtypeBuddhistCenter, SubtypeReligiousSchool, } case SectorFoodBeverage: return []OrganizationSubtype{ SubtypeRestaurant, SubtypeCafe, SubtypeFastFood, SubtypeBakery, SubtypeBar, SubtypeCatering, SubtypeFoodTruck, } case SectorRetail: return []OrganizationSubtype{ SubtypeGroceryStore, SubtypeDepartmentStore, SubtypeBoutique, SubtypeElectronicsStore, SubtypeBookstore, SubtypeConvenienceStore, SubtypeMarket, } case SectorServices: return []OrganizationSubtype{ SubtypeLawyer, SubtypeAccountant, SubtypeConsultant, SubtypeITServices, SubtypeCleaning, SubtypeRepairService, SubtypeTutoring, } case SectorEducation: return []OrganizationSubtype{ SubtypeSchool, SubtypeCollege, SubtypeUniversity, SubtypeKindergarten, SubtypeTrainingCenter, } case SectorBeautyWellness: return []OrganizationSubtype{ SubtypeSalon, SubtypeSpa, SubtypeBarber, SubtypeGym, SubtypeNailSalon, SubtypeMassageTherapy, SubtypeBeautySupply, SubtypePersonalServices, } case SectorAutomotive: return []OrganizationSubtype{ SubtypeCarDealership, SubtypeAutoRepair, SubtypeCarWash, SubtypeAutoParts, SubtypeTireShop, SubtypeMotorcycleShop, SubtypeTaxi, SubtypeBusStation, SubtypeDelivery, SubtypeTransportation, } case SectorHospitality: return []OrganizationSubtype{ SubtypeHotel, SubtypeHostel, } case SectorManufacturing: return []OrganizationSubtype{ SubtypeFactory, SubtypeWorkshop, SubtypeManufacturing, } case SectorEnergy: return []OrganizationSubtype{ SubtypePowerPlant, SubtypeFuelStation, SubtypeEnergy, } case SectorConstruction: return []OrganizationSubtype{ SubtypeConstructionContractor, SubtypeConstruction, } case SectorFinancial: return []OrganizationSubtype{ SubtypeBank, SubtypeInsurance, SubtypeFinancial, } case SectorEntertainment: return []OrganizationSubtype{ SubtypeTheater, SubtypeCinema, SubtypeMuseum, SubtypeConcertHall, SubtypeGamingCenter, SubtypeNightclub, SubtypeCultural, } case SectorFurniture: return []OrganizationSubtype{ SubtypeFurnitureStore, SubtypeFurnitureManufacturer, SubtypeInteriorDesign, SubtypeFurnitureRepair, } case SectorSports: return []OrganizationSubtype{ SubtypeSportsClub, SubtypeStadium, SubtypeSportsEquipment, } case SectorAgriculture: return []OrganizationSubtype{ SubtypeFarm, SubtypeAgriculturalSupplier, SubtypeGreenhouse, SubtypeLivestock, } case SectorTechnology: return []OrganizationSubtype{ SubtypeSoftwareCompany, SubtypeHardwareCompany, SubtypeTechSupport, SubtypeWebDevelopment, SubtypeTelecommunications, } default: // Return all subtypes for unknown sectors or generic sectors return GetAllSubtypes() } } // SectorStat represents sector statistics type SectorStat struct { Sector string `json:"sector"` Count int `json:"count"` } // Image represents an uploaded image type Image struct { URL string `json:"url"` Path string `json:"path"` } // LegalForm represents the legal structure of a business organization type LegalForm string const ( LegalFormLLC LegalForm = "LLC" LegalFormCorporation LegalForm = "corporation" LegalFormPartnership LegalForm = "partnership" LegalFormSoleProprietorship LegalForm = "sole_proprietorship" LegalFormGmbH LegalForm = "GmbH" LegalFormUG LegalForm = "UG" LegalFormAG LegalForm = "AG" ) // SupplyChainRole represents the organization's role in the supply chain type SupplyChainRole string const ( RoleManufacturer SupplyChainRole = "manufacturer" RoleSupplier SupplyChainRole = "supplier" RoleDistributor SupplyChainRole = "distributor" RoleConsumer SupplyChainRole = "consumer" ) // PrimaryContact stores contact information type PrimaryContact struct { Email string `json:"email"` Phone string `json:"phone"` } // ProductJSON represents a product offered by an organization (for API/JSON serialization) type ProductJSON struct { Name string `json:"name"` Category string `json:"category"` UnitPrice float64 `json:"unit_price"` MOQ int `json:"moq,omitempty"` Certifications []string `json:"certifications,omitempty"` } // ServiceJSON represents a service offered by an organization (for API/JSON serialization) type ServiceJSON struct { Type string `json:"type"` // maintenance, consulting, transport, inspection Domain string `json:"domain"` // compressors, HVAC, waste_management, etc. OnSite bool `json:"on_site"` // on-site or remote HourlyRate float64 `json:"hourly_rate"` // €/hour ServiceAreaKm float64 `json:"service_area_km"` // service radius Certifications []string `json:"certifications,omitempty"` } // ServiceNeedJSON represents a service needed by an organization (for API/JSON serialization) type ServiceNeedJSON struct { Type string `json:"type"` Urgency string `json:"urgency,omitempty"` // low, medium, high Budget float64 `json:"budget,omitempty"` PreferredProviders []string `json:"preferred_providers,omitempty"` // Organization IDs } type Organization struct { ID string `gorm:"primaryKey;type:text" json:"ID"` Name string `gorm:"not null;type:text;index" json:"Name"` // Primary name (Russian) // Subtype categorization (commercial, healthcare, educational, etc.) Subtype OrganizationSubtype `gorm:"not null;type:varchar(50);index" json:"Subtype"` Sector OrganizationSector `gorm:"type:varchar(50);index" json:"Sector"` // NACE code or category // Basic information Description string `gorm:"type:text" json:"Description"` LogoURL string `gorm:"column:logo_url;type:text" json:"LogoURL"` GalleryImages datatypes.JSON `gorm:"column:gallery_images;type:jsonb;default:'[]'" json:"-"` // []string - URLs of gallery images Website string `gorm:"type:text" json:"Website"` // Geolocation (from primary address) Latitude float64 `gorm:"type:double precision;index:idx_org_location" json:"Latitude"` Longitude float64 `gorm:"type:double precision;index:idx_org_location" json:"Longitude"` // Business-specific fields (for commercial subtype) LegalForm string `gorm:"type:varchar(50)" json:"LegalForm"` PrimaryContact datatypes.JSON `gorm:"type:jsonb" json:"PrimaryContact"` // PrimaryContact IndustrialSector string `gorm:"type:varchar(10)" json:"IndustrialSector"` CompanySize int `gorm:"type:integer" json:"CompanySize"` YearsOperation int `gorm:"type:integer" json:"YearsOperation"` SupplyChainRole SupplyChainRole `gorm:"type:varchar(50)" json:"SupplyChainRole"` Certifications datatypes.JSON `gorm:"default:'[]'" json:"-"` // []string BusinessFocus datatypes.JSON `gorm:"default:'[]'" json:"-"` // []string StrategicVision string `gorm:"type:text" json:"StrategicVision"` DriversBarriers string `gorm:"type:text" json:"DriversBarriers"` ReadinessMaturity int `gorm:"type:integer;default:3" json:"ReadinessMaturity"` TrustScore float64 `gorm:"type:double precision;default:0.7" json:"TrustScore"` TechnicalExpertise datatypes.JSON `gorm:"default:'[]'" json:"-"` // []string AvailableTechnology datatypes.JSON `gorm:"default:'[]'" json:"-"` // []string ManagementSystems datatypes.JSON `gorm:"default:'[]'" json:"-"` // []string // Products and Services SellsProducts datatypes.JSON `gorm:"default:'[]'" json:"SellsProducts"` // []Product OffersServices datatypes.JSON `gorm:"default:'[]'" json:"OffersServices"` // []Service NeedsServices datatypes.JSON `gorm:"default:'[]'" json:"NeedsServices"` // []ServiceNeed // Historical/cultural building fields (for non-commercial subtypes) YearBuilt string `gorm:"type:text" json:"YearBuilt"` BuilderOwner string `gorm:"type:text" json:"BuilderOwner"` Architect string `gorm:"type:text" json:"Architect"` OriginalPurpose string `gorm:"type:text" json:"OriginalPurpose"` CurrentUse string `gorm:"type:text" json:"CurrentUse"` Style string `gorm:"type:text" json:"Style"` Materials string `gorm:"type:text" json:"Materials"` Storeys int `gorm:"type:integer" json:"Storeys"` HeritageStatus string `gorm:"type:text" json:"HeritageStatus"` // Metadata Verified bool `gorm:"default:false;index" json:"Verified"` Notes string `gorm:"type:text" json:"Notes"` Sources datatypes.JSON `gorm:"type:jsonb" json:"Sources"` // Relationships (will be populated via associations) TrustNetwork datatypes.JSON `gorm:"type:jsonb;default:'[]'" json:"-"` // []string - Organization IDs ExistingSymbioticRelationships datatypes.JSON `gorm:"type:jsonb;default:'[]'" json:"-"` // []string - Organization IDs // Products/materials for legacy compatibility Products datatypes.JSON `gorm:"type:jsonb" json:"Products"` // Timestamps CreatedAt time.Time `gorm:"autoCreateTime;index" json:"CreatedAt"` UpdatedAt time.Time `gorm:"autoUpdateTime" json:"UpdatedAt"` // Associations Addresses []Address `gorm:"many2many:organization_addresses;" json:"Addresses,omitempty"` OwnedSites []Site `gorm:"foreignKey:OwnerOrganizationID" json:"OwnedSites,omitempty"` OperatingSites []Site `gorm:"many2many:site_operating_organizations;" json:"OperatingSites,omitempty"` ResourceFlows []ResourceFlow `gorm:"foreignKey:OrganizationID" json:"ResourceFlows,omitempty"` } // TableName specifies the table name for GORM func (Organization) TableName() string { return "organizations" } // PrimaryAddress returns the primary (headquarters) address formatted string func (o *Organization) PrimaryAddress() string { for _, addr := range o.Addresses { if addr.AddressType == AddressTypeHeadquarters { if addr.FormattedRu != "" { return addr.FormattedRu } if addr.FormattedEn != "" { return addr.FormattedEn } } } // Fallback to any address if no headquarters found if len(o.Addresses) > 0 { if o.Addresses[0].FormattedRu != "" { return o.Addresses[0].FormattedRu } if o.Addresses[0].FormattedEn != "" { return o.Addresses[0].FormattedEn } } return "" } type OrganizationRepository interface { Create(ctx context.Context, org *Organization) error GetByID(ctx context.Context, id string) (*Organization, error) GetAll(ctx context.Context) ([]*Organization, error) Update(ctx context.Context, org *Organization) error Delete(ctx context.Context, id string) error GetBySector(ctx context.Context, sector OrganizationSector) ([]*Organization, error) GetBySubtype(ctx context.Context, subtype OrganizationSubtype) ([]*Organization, error) GetWithinRadius(ctx context.Context, lat, lng, radiusKm float64) ([]*Organization, error) GetByCertification(ctx context.Context, cert string) ([]*Organization, error) Search(ctx context.Context, query string, limit int) ([]*Organization, error) SearchSuggestions(ctx context.Context, query string, limit int) ([]string, error) GetSectorStats(ctx context.Context, limit int) ([]SectorStat, error) GetResourceFlowsByTypeAndDirection(ctx context.Context, resourceType string, direction string) ([]*ResourceFlow, error) }