turash/bugulma/backend/internal/analysis/transport/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

138 lines
3.7 KiB
Go

package transport
import (
"bugulma/backend/internal/domain"
)
// TransportAnalysis represents transport feasibility and cost analysis
type TransportAnalysis struct {
Method string `json:"method"`
CostPerUnit float64 `json:"cost_per_unit"`
FeasibilityScore float64 `json:"feasibility_score"`
EstimatedTimeDays int `json:"estimated_time_days"`
EnvironmentalImpact float64 `json:"environmental_impact"`
}
// Service provides transport analysis functionality
type Service struct{}
// NewService creates a new transport analysis service
func NewService() *Service {
return &Service{}
}
// AnalyzeTransport performs transport feasibility and cost analysis
func (s *Service) AnalyzeTransport(distanceKm float64, resourceType domain.ResourceType) *TransportAnalysis {
analysis := &TransportAnalysis{}
// Determine transport method
analysis.Method = s.determineTransportMethod(resourceType, distanceKm)
// Calculate cost per unit
analysis.CostPerUnit = s.calculateTransportCost(distanceKm, resourceType)
// Assess feasibility
analysis.FeasibilityScore = s.assessTransportFeasibility(distanceKm, resourceType)
// Estimate delivery time
analysis.EstimatedTimeDays = s.estimateDeliveryTime(distanceKm, analysis.Method)
// Calculate environmental impact
analysis.EnvironmentalImpact = s.calculateTransportEnvironmentalImpact(distanceKm, analysis.Method)
return analysis
}
func (s *Service) determineTransportMethod(resourceType domain.ResourceType, distanceKm float64) string {
if distanceKm < 5 {
return "pipeline"
}
switch resourceType {
case domain.TypeHeat, domain.TypeSteam, domain.TypeCooling:
if distanceKm < 10 {
return "pipeline"
}
return "no_viable_transport"
case domain.TypeWater:
return "pipeline"
case domain.TypeCO2, domain.TypeBiowaste, domain.TypeMaterials:
return "truck"
case domain.TypeLogistics:
return "various"
case domain.TypeService:
return "on_site"
default:
return "truck"
}
}
func (s *Service) calculateTransportCost(distance float64, resourceType domain.ResourceType) float64 {
// Transport cost per km based on resource type
transportRates := map[domain.ResourceType]float64{
domain.TypeHeat: 0.0005, // €0.5 per km per MWh (piping)
domain.TypeWater: 0.001, // €1 per km per m³
domain.TypeSteam: 0.0005, // Similar to heat
domain.TypeCO2: 0.002, // Truck/tanker transport
domain.TypeBiowaste: 0.003, // Truck transport
domain.TypeCooling: 0.0005, // Piping
domain.TypeMaterials: 0.002, // Truck transport
domain.TypeLogistics: 0.001, // Variable
domain.TypeService: 0.0, // No transport for services
}
rate, exists := transportRates[resourceType]
if !exists {
rate = 0.001 // Default rate
}
return distance * rate
}
func (s *Service) assessTransportFeasibility(distanceKm float64, resourceType domain.ResourceType) float64 {
method := s.determineTransportMethod(resourceType, distanceKm)
switch method {
case "pipeline":
if distanceKm < 20 {
return 0.9
}
return 0.3
case "truck":
if distanceKm < 200 {
return 0.8
}
return 0.4
case "no_viable_transport":
return 0.1
case "on_site":
return 1.0
default:
return 0.7
}
}
func (s *Service) estimateDeliveryTime(distanceKm float64, method string) int {
switch method {
case "pipeline":
return 0 // Continuous flow
case "truck":
return int(distanceKm/800) + 1 // Assume 800km/day truck speed
case "on_site":
return 0
default:
return 1
}
}
func (s *Service) calculateTransportEnvironmentalImpact(distanceKm float64, method string) float64 {
switch method {
case "truck":
return distanceKm * 0.0005 // tonnes CO2 per km for diesel truck
case "pipeline":
return distanceKm * 0.0001 // Much lower for electricity-powered pumping
default:
return 0
}
}