turash/bugulma/backend/internal/analysis/risk/service.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

127 lines
3.5 KiB
Go

package risk
import "bugulma/backend/internal/domain"
// RiskAssessment represents a comprehensive risk analysis
type RiskAssessment struct {
TechnicalRisk float64 `json:"technical_risk"`
RegulatoryRisk float64 `json:"regulatory_risk"`
MarketRisk float64 `json:"market_risk"`
OverallRisk float64 `json:"overall_risk"`
RiskLevel string `json:"risk_level"`
PrimaryRisks []string `json:"primary_risks"`
}
// Service provides risk assessment functionality
type Service struct{}
// NewService creates a new risk analysis service
func NewService() *Service {
return &Service{}
}
// AssessResourceFlowRisk assesses risk for a resource flow match
func (s *Service) AssessResourceFlowRisk(distanceKm float64, resourceType domain.ResourceType, economicScore float64) *RiskAssessment {
risk := &RiskAssessment{}
// Technical risk based on distance and resource type
risk.TechnicalRisk = s.calculateTechnicalRisk(distanceKm, resourceType)
// Regulatory risk based on resource type
risk.RegulatoryRisk = s.calculateRegulatoryRisk(resourceType)
// Market risk based on economic viability
risk.MarketRisk = s.calculateMarketRisk(economicScore)
// Calculate overall risk as weighted average
risk.OverallRisk = (risk.TechnicalRisk*0.4 + risk.RegulatoryRisk*0.3 + risk.MarketRisk*0.3)
// Determine risk level
risk.RiskLevel = s.calculateRiskLevel(risk.OverallRisk)
// Identify primary risk factors
risk.PrimaryRisks = s.identifyPrimaryRiskFactors(distanceKm, resourceType, economicScore)
return risk
}
func (s *Service) calculateTechnicalRisk(distanceKm float64, resourceType domain.ResourceType) float64 {
risk := 0.0
// Distance risk
if distanceKm > 50 {
risk += 0.3
} else if distanceKm > 20 {
risk += 0.1
}
// Resource type risk
switch resourceType {
case domain.TypeHeat, domain.TypeSteam, domain.TypeCooling:
risk += 0.2 // Infrastructure complexity
case domain.TypeBiowaste, domain.TypeCO2:
risk += 0.4 // Handling and safety requirements
case domain.TypeMaterials:
risk += 0.1 // Relatively straightforward
}
return risk
}
func (s *Service) calculateRegulatoryRisk(resourceType domain.ResourceType) float64 {
switch resourceType {
case domain.TypeBiowaste:
return 0.6 // High regulatory requirements
case domain.TypeCO2, domain.TypeWater:
return 0.4 // Medium regulatory requirements
case domain.TypeHeat, domain.TypeSteam:
return 0.2 // Lower regulatory requirements
default:
return 0.3
}
}
func (s *Service) calculateMarketRisk(economicScore float64) float64 {
if economicScore < 0.3 {
return 0.7 // High risk for poor economics
} else if economicScore < 0.6 {
return 0.4 // Medium risk
}
return 0.1 // Low risk for good economics
}
func (s *Service) calculateRiskLevel(overallRisk float64) string {
switch {
case overallRisk > 0.6:
return "high"
case overallRisk > 0.3:
return "medium"
default:
return "low"
}
}
func (s *Service) identifyPrimaryRiskFactors(distanceKm float64, resourceType domain.ResourceType, economicScore float64) []string {
var primaryRisks []string
// Technical risk factors
if distanceKm > 100 {
primaryRisks = append(primaryRisks, "distance")
}
if resourceType == domain.TypeBiowaste || resourceType == domain.TypeCO2 {
primaryRisks = append(primaryRisks, "handling_complexity")
}
// Regulatory risk factors
if resourceType == domain.TypeBiowaste {
primaryRisks = append(primaryRisks, "regulatory_compliance")
}
// Market risk factors
if economicScore < 0.5 {
primaryRisks = append(primaryRisks, "economic_viability")
}
return primaryRisks
}