GreenOps Package Architecture
The internal/greenops/ package provides carbon emission equivalency calculations
for FinFocus, converting abstract CO2e values into human-readable comparisons.
Package Structure
Section titled “Package Structure”internal/greenops/├── equivalency.go # Core calculation functions├── equivalency_test.go # Unit tests (colocated)├── normalizer.go # Unit conversion utilities├── normalizer_test.go # Normalizer tests├── formatter.go # Number formatting utilities├── formatter_test.go # Formatter tests├── types.go # Data structures and enums├── constants.go # EPA formulas and thresholds└── errors.go # Error type definitionsCore Components
Section titled “Core Components”Types (types.go)
Section titled “Types (types.go)”// EquivalencyType enumerates supported equivalency categories.type EquivalencyType int
const ( EquivalencyMilesDriven EquivalencyType = iota EquivalencySmartphonesCharged EquivalencyTreeSeedlings // Optional/future EquivalencyHomeDays // Optional/future)
// CarbonInput represents carbon emission data for calculation.type CarbonInput struct { Value float64 // Emission amount Unit string // Original unit (g, kg, t, lb)}
// EquivalencyOutput contains calculated equivalencies.type EquivalencyOutput struct { InputKg float64 // Normalized input in kg Results []EquivalencyResult // Calculated equivalencies DisplayText string // Full prose format CompactText string // Abbreviated format IsEmpty bool // True if below threshold}
// EquivalencyResult represents a single equivalency calculation.type EquivalencyResult struct { Type EquivalencyType Value float64 FormattedValue string Label string}Constants (constants.go)
Section titled “Constants (constants.go)”// EPA formula constants (2024 edition)const ( EPAMilesDrivenFactor = 0.393 // kg CO2e per mile (8.89÷22.8×1.006) EPASmartphoneChargeFactor = 0.00822 // kg CO2e per charge EPATreeSeedlingFactor = 60.0 // kg absorbed per tree/10yr EPAHomeDayFactor = 18.3 // kg per day US home)
// Display thresholdsconst ( MinDisplayThresholdKg = 0.001 // Minimum for any display MinEquivalencyThresholdKg = 1.0 // Minimum for equivalencies LargeNumberThreshold = 1_000_000 // Abbreviated display)
// Carbon metric keysconst ( CarbonMetricKey = "carbon_footprint" // Canonical DeprecatedCarbonKey = "gCO2e" // Legacy)Core Functions (equivalency.go)
Section titled “Core Functions (equivalency.go)”// Calculate computes equivalencies from a CarbonInput.// Returns IsEmpty=true if below MinEquivalencyThresholdKg.func Calculate(input CarbonInput) (EquivalencyOutput, error)
// CalculateFromMap extracts carbon from a sustainability map.// Checks canonical key first, falls back to deprecated.func CalculateFromMap(metrics map[string]SustainabilityMetric) EquivalencyOutputNormalizer (normalizer.go)
Section titled “Normalizer (normalizer.go)”// NormalizeToKg converts any recognized unit to kilograms.func NormalizeToKg(value float64, unit string) (float64, error)
// IsRecognizedUnit returns true for valid unit strings.func IsRecognizedUnit(unit string) boolFormatter (formatter.go)
Section titled “Formatter (formatter.go)”// FormatNumber formats integers with thousand separators.func FormatNumber(n int64) string
// FormatFloat formats floats with specified precision.func FormatFloat(f float64, precision int) string
// FormatLarge abbreviates large numbers (million, billion).func FormatLarge(n float64) stringData Flow
Section titled “Data Flow”┌─────────────────┐│ CarbonInput ││ Value: 150.0 ││ Unit: "kg" │└────────┬────────┘ │ ▼┌─────────────────┐│ NormalizeToKg │───► Converts to kg (150.0)└────────┬────────┘ │ ▼┌─────────────────┐│ Threshold Check │───► Skip if < 1.0 kg└────────┬────────┘ │ ▼┌─────────────────┐ ┌──────────────────────┐│ EPA Formulas │────►│ Miles: 150/0.393 ││ │ │ Phones: 150/0.00822 │└────────┬────────┘ └──────────────────────┘ │ ▼┌─────────────────┐ ┌──────────────────────────────────────┐│ Format Values │────►│ FormattedValue: "382", "18,248" ││ │ │ DisplayText: "Equivalent to..." │└────────┬────────┘ │ CompactText: "(≈ 382 mi, 18,248...)" │ │ └──────────────────────────────────────┘ ▼┌─────────────────┐│ EquivalencyOut │└─────────────────┘Integration Points
Section titled “Integration Points”Engine (internal/engine/project.go)
Section titled “Engine (internal/engine/project.go)”import "github.com/rshade/finfocus/internal/greenops"
// In renderSustainabilitySummary()if metric, ok := sustainTotals["carbon_footprint"]; ok { input := greenops.CarbonInput{Value: metric.Value, Unit: metric.Unit} output, _ := greenops.Calculate(input) if !output.IsEmpty { fmt.Fprintf(w, " %s\n", output.DisplayText) }}TUI (internal/tui/cost_view.go)
Section titled “TUI (internal/tui/cost_view.go)”import "github.com/rshade/finfocus/internal/greenops"
// In RenderCostSummary()if carbonInput, found := aggregateCarbonFromResults(results); found { output, _ := greenops.Calculate(carbonInput) if !output.IsEmpty { content.WriteString(SubtleStyle.Render(output.DisplayText)) }}Analyzer (internal/analyzer/diagnostics.go)
Section titled “Analyzer (internal/analyzer/diagnostics.go)”import "github.com/rshade/finfocus/internal/greenops"
// In formatCostMessage()if metric, ok := sustainability["carbon_footprint"]; ok { input := greenops.CarbonInput{Value: metric.Value, Unit: metric.Unit} output, _ := greenops.Calculate(input) if !output.IsEmpty { message += " " + output.CompactText }}Error Handling
Section titled “Error Handling”var ( ErrInvalidUnit = errors.New("invalid carbon unit") ErrNegativeValue = errors.New("negative carbon value") ErrCalculationOverflow = errors.New("calculation overflow"))All integration points handle errors gracefully:
- Invalid units: Log warning, skip equivalency display
- Negative values: Log warning, skip equivalency display
- Below threshold: Return IsEmpty=true, no display
Testing Strategy
Section titled “Testing Strategy”Unit Tests
Section titled “Unit Tests”TestCalculate: EPA formula accuracy within 1% marginTestCalculateFromMap: Canonical and legacy key handlingTestNormalizeToKg: All unit conversionsTestFormatNumber/Float/Large: Number formatting
Integration Tests
Section titled “Integration Tests”test/integration/greenops_cli_test.go: CLI output verificationinternal/tui/cost_view_test.go: TUI rendering testsinternal/analyzer/diagnostics_test.go: Diagnostic format tests
Coverage Target
Section titled “Coverage Target”- Minimum 80% for greenops package
- 95% for critical calculation paths
Dependencies
Section titled “Dependencies”golang.org/x/text/language: Locale-aware formattinggolang.org/x/text/message: Number formatting with separatorsgithub.com/rs/zerolog: Structured logging (for deprecation warnings)
No external APIs or network calls required.
Future Extensions
Section titled “Future Extensions”The package is designed for extensibility:
- New equivalencies: Add to
EquivalencyTypeenum and formulas - Regional variations: Support locale-specific formulas
- Custom thresholds: Allow user configuration
- Tree absorption: Implement
EquivalencyTreeSeedlings(commented out)