Files
honeyDueAPI/internal/services/region_lookup.go
Trey t 793e50ce52 Add regional task templates API with climate zone lookup
Adds a new endpoint GET /api/tasks/templates/by-region/?zip= that resolves
ZIP codes to IECC climate regions and returns relevant home maintenance
task templates. Includes climate region model, region lookup service with
tests, seed data for all 8 climate zones with 50+ templates, and OpenAPI spec.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 15:15:30 -06:00

158 lines
4.1 KiB
Go

package services
import (
"strconv"
"strings"
)
// StateToClimateRegion maps US state abbreviations to IECC climate zone IDs.
// Some states span multiple zones — this uses the dominant zone for the most populated areas.
var StateToClimateRegion = map[string]uint{
// Zone 1: Hot-Humid
"HI": 1, "FL": 1, "LA": 1,
// Zone 2: Hot-Dry / Hot-Humid mix
"TX": 2, "AZ": 2, "NV": 2, "NM": 2,
// Zone 3: Mixed-Humid
"GA": 3, "SC": 3, "AL": 3, "MS": 3, "AR": 3, "NC": 3, "TN": 3, "OK": 3, "CA": 3,
// Zone 4: Mixed
"VA": 4, "KY": 4, "MO": 4, "KS": 4, "DE": 4, "MD": 4, "DC": 4, "WV": 4, "OR": 4,
// Zone 5: Cold
"NJ": 5, "PA": 5, "CT": 5, "RI": 5, "MA": 5, "OH": 5, "IN": 5, "IL": 5,
"IA": 5, "NE": 5, "CO": 5, "UT": 5, "WA": 5, "ID": 5, "NY": 5, "MI": 5,
// Zone 6: Very Cold
"WI": 6, "MN": 6, "ND": 6, "SD": 6, "MT": 6, "WY": 6, "VT": 6, "NH": 6, "ME": 6,
// Zone 8: Arctic
"AK": 8,
}
// GetClimateRegionIDByState returns the climate region ID for a US state abbreviation.
// Returns 0 if the state is not found.
func GetClimateRegionIDByState(state string) uint {
regionID, ok := StateToClimateRegion[strings.ToUpper(strings.TrimSpace(state))]
if !ok {
return 0
}
return regionID
}
// ZipToState maps a US ZIP code to a state abbreviation using the 3-digit ZIP prefix.
// Returns empty string if the ZIP is invalid or unrecognized.
func ZipToState(zip string) string {
zip = strings.TrimSpace(zip)
if len(zip) < 3 {
return ""
}
prefix, err := strconv.Atoi(zip[:3])
if err != nil {
return ""
}
// ZIP prefix → state mapping (USPS ranges)
switch {
case prefix >= 10 && prefix <= 27:
return "MA"
case prefix >= 28 && prefix <= 29:
return "RI"
case prefix >= 30 && prefix <= 38:
return "NH"
case prefix >= 39 && prefix <= 49:
return "ME"
case prefix >= 50 && prefix <= 59:
return "VT"
case prefix >= 60 && prefix <= 69:
return "CT"
case prefix >= 70 && prefix <= 89:
return "NJ"
case prefix >= 100 && prefix <= 149:
return "NY"
case prefix >= 150 && prefix <= 196:
return "PA"
case prefix >= 197 && prefix <= 199:
return "DE"
case prefix >= 200 && prefix <= 205:
return "DC"
case prefix >= 206 && prefix <= 219:
return "MD"
case prefix >= 220 && prefix <= 246:
return "VA"
case prefix >= 247 && prefix <= 268:
return "WV"
case prefix >= 270 && prefix <= 289:
return "NC"
case prefix >= 290 && prefix <= 299:
return "SC"
case prefix >= 300 && prefix <= 319:
return "GA"
case prefix >= 320 && prefix <= 349:
return "FL"
case prefix >= 350 && prefix <= 369:
return "AL"
case prefix >= 370 && prefix <= 385:
return "TN"
case prefix >= 386 && prefix <= 397:
return "MS"
case prefix >= 400 && prefix <= 427:
return "KY"
case prefix >= 430 && prefix <= 458:
return "OH"
case prefix >= 460 && prefix <= 479:
return "IN"
case prefix >= 480 && prefix <= 499:
return "MI"
case prefix >= 500 && prefix <= 528:
return "IA"
case prefix >= 530 && prefix <= 549:
return "WI"
case prefix >= 550 && prefix <= 567:
return "MN"
case prefix >= 570 && prefix <= 577:
return "SD"
case prefix >= 580 && prefix <= 588:
return "ND"
case prefix >= 590 && prefix <= 599:
return "MT"
case prefix >= 600 && prefix <= 629:
return "IL"
case prefix >= 630 && prefix <= 658:
return "MO"
case prefix >= 660 && prefix <= 679:
return "KS"
case prefix >= 680 && prefix <= 693:
return "NE"
case prefix >= 700 && prefix <= 714:
return "LA"
case prefix >= 716 && prefix <= 729:
return "AR"
case prefix >= 730 && prefix <= 749:
return "OK"
case prefix >= 750 && prefix <= 799:
return "TX"
case prefix >= 800 && prefix <= 816:
return "CO"
case prefix >= 820 && prefix <= 831:
return "WY"
case prefix >= 832 && prefix <= 838:
return "ID"
case prefix >= 840 && prefix <= 847:
return "UT"
case prefix >= 850 && prefix <= 865:
return "AZ"
case prefix >= 870 && prefix <= 884:
return "NM"
case prefix >= 889 && prefix <= 898:
return "NV"
case prefix >= 900 && prefix <= 966:
return "CA"
case prefix >= 967 && prefix <= 968:
return "HI"
case prefix >= 970 && prefix <= 979:
return "OR"
case prefix >= 980 && prefix <= 994:
return "WA"
case prefix >= 995 && prefix <= 999:
return "AK"
default:
return ""
}
}