turash/models/market/market.go
Damir Mukimov 4a2fda96cd
Initial commit: Repository setup with .gitignore, golangci-lint v2.6.0, and code quality checks
- Initialize git repository
- Add comprehensive .gitignore for Go projects
- Install golangci-lint v2.6.0 (latest v2) globally
- Configure .golangci.yml with appropriate linters and formatters
- Fix all formatting issues (gofmt)
- Fix all errcheck issues (unchecked errors)
- Adjust complexity threshold for validation functions
- All checks passing: build, test, vet, lint
2025-11-01 07:36:22 +01:00

88 lines
3.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package market
import (
"fmt"
"github.com/damirmukimov/city_resource_graph/models/params"
)
// MarketSize represents market size metrics.
// These are contextual constants for documentation, not drivers of calculations.
type MarketSize struct {
TAM float64 `json:"tam"` // Total Addressable Market (EUR)
SAM float64 `json:"sam"` // Serviceable Addressable Market (EUR)
SOM float64 `json:"som"` // Serviceable Obtainable Market (EUR)
}
// Constants represents market size constants for EU funding context.
// These are not computed - they represent the problem space.
type Constants struct {
TAM float64 `json:"tam"` // €500B - EU industrial resource flows
AddressableDigital float64 `json:"addressable_digital"` // €2-5B - Small/medium cities
PilotCityEconomicBenefit float64 `json:"pilot_city_economic_benefit"` // €3-5M/year per city
ScalabilityPotential float64 `json:"scalability_potential"` // €300-500M/year if 100 cities
EUIndustrialFacilities int `json:"eu_industrial_facilities"` // 2.1M facilities
EnergyWastePotential float64 `json:"energy_waste_potential"` // 45% recoverable
ResourceCostReduction float64 `json:"resource_cost_reduction"` // 20-30% via symbiosis
}
// ErrMissingMarketData indicates required market data is missing from params.
type ErrMissingMarketData struct {
Field string
}
func (e ErrMissingMarketData) Error() string {
return fmt.Sprintf("missing market data: %s", e.Field)
}
// GetMarketSize returns market size constants from parameters.
// Returns error if required fields are missing.
func GetMarketSize(p *params.Params) (Constants, error) {
mp := p.Market
if mp.TAM == 0 {
return Constants{}, ErrMissingMarketData{Field: "market.tam"}
}
return Constants{
TAM: mp.TAM,
AddressableDigital: mp.AddressableDigital,
PilotCityEconomicBenefit: mp.PilotCityEconomicBenefit,
ScalabilityPotential: mp.ScalabilityPotential,
EUIndustrialFacilities: mp.EUIndustrialFacilities,
EnergyWastePotential: mp.EnergyWastePotential,
ResourceCostReduction: mp.ResourceCostReduction,
}, nil
}
// CalculateSAM computes the Serviceable Addressable Market.
// Formula: SAM = TAM × Viable Exchange Rate × Platform Capture Rate × 2
// (×2 accounts for additional procurement optimization)
// Returns error if required fields are missing.
func CalculateSAM(p *params.Params) (float64, error) {
mp := p.Market
if mp.TAM == 0 {
return 0, ErrMissingMarketData{Field: "market.tam"}
}
if mp.ViableExchangeRate == 0 {
return 0, ErrMissingMarketData{Field: "market.viable_exchange_rate"}
}
if mp.PlatformCaptureRate == 0 {
return 0, ErrMissingMarketData{Field: "market.platform_capture_rate"}
}
return mp.TAM * mp.ViableExchangeRate * mp.PlatformCaptureRate * 2.0, nil
}
// GetSOM returns the Serviceable Obtainable Market for a given year.
// This represents post-grant commercial scaling potential.
// Returns error if SOM data for the year is missing.
func GetSOM(year int, p *params.Params) (float64, error) {
som := p.Market.SOM.GetYear(year)
if som == 0 {
return 0, ErrMissingMarketData{Field: fmt.Sprintf("market.som.%d", year)}
}
return som, nil
}