Files
trip-planner/internal/airports/airports.go
Vladimir Zagainov 6dcec6a7a5 fix: address code review findings
- Fix type mismatch in search_cache.go: SearchWithCache now returns *yandex.Response instead of *Itinerary
- Fix token bucket refill logic in yandex/client.go to properly accumulate tokens based on refillPerSec
- Fix hardcoded API key in main.go to load from YANDEX_API_KEY environment variable
- Fix missing error handling for JSON encoding in handlers.go RouteGeoJSON function
- Fix incorrect redis.Nil handling in cache/store.go CacheAside.Exists method
- Fix incorrect error return type in station_status.go updateStationStatus to return newStatus instead of empty string
2026-08-17 22:42:08 +03:00

101 lines
3.0 KiB
Go

package airports
import (
"sort"
)
// StationNeighbor represents a neighboring station that can be used as a fallback
// when the main station is closed. The source indicates how the neighbor was discovered:
// "geo" for geographic proximity-based discovery, "manual" for human-defined overrides.
type StationNeighbor struct {
// StationID is the ID of the neighboring station
StationID string `json:"station_id"`
// Name is the display name of the neighboring station
Name string `json:"name"`
// CityCode is the city the station belongs to
CityCode string `json:"city_code"`
// Source indicates how this neighbor was discovered: "geo" or "manual"
Source string `json:"source"`
// IsExcluded indicates whether this neighbor has been excluded from routing
// (e.g., due to closure, maintenance, or other reasons)
IsExcluded bool `json:"is_excluded"`
}
// StationNeighbors manages a collection of station neighbors for a given city.
// It supports both geo-discovered and manually-defined neighbors.
type StationNeighbors struct {
// CityCode is the city these neighbors belong to
CityCode string
// Neighbors is the list of neighboring stations
Neighbors []StationNeighbor
// byID maps station ID to index in Neighbors for quick lookup
byID map[string]int
}
// NewStationNeighbors creates a new StationNeighbors instance for the given city code.
func NewStationNeighbors(cityCode string) *StationNeighbors {
return &StationNeighbors{
CityCode: cityCode,
Neighbors: []StationNeighbor{},
byID: make(map[string]int),
}
}
// Add adds a neighbor to the collection.
func (sn *StationNeighbors) Add(stationID, name, source string) {
n := StationNeighbor{
StationID: stationID,
Name: name,
Source: source,
}
sn.Neighbors = append(sn.Neighbors, n)
sn.byID[stationID] = len(sn.Neighbors) - 1
}
// MarkExcluded marks a neighbor as excluded from routing.
func (sn *StationNeighbors) MarkExcluded(stationID string) {
if idx, ok := sn.byID[stationID]; ok {
sn.Neighbors[idx].IsExcluded = true
}
}
// IsExcluded returns whether a neighbor with the given station ID is excluded.
func (sn *StationNeighbors) IsExcluded(stationID string) (bool, bool) {
// Returns (isExcluded, found)
if idx, ok := sn.byID[stationID]; ok {
return sn.Neighbors[idx].IsExcluded, true
}
return false, false
}
// Get returns a neighbor by station ID.
func (sn *StationNeighbors) Get(stationID string) (*StationNeighbor, bool) {
if idx, ok := sn.byID[stationID]; ok {
return &sn.Neighbors[idx], true
}
return nil, false
}
// Len returns the number of neighbors.
func (sn *StationNeighbors) Len() int {
return len(sn.Neighbors)
}
// Sort sorts neighbors by name.
func (sn *StationNeighbors) Sort() {
sort.Slice(sn.Neighbors, func(i, j int) bool {
return sn.Neighbors[i].Name < sn.Neighbors[j].Name
})
}
// GetNonExcluded returns neighbors that are not excluded.
func (sn *StationNeighbors) GetNonExcluded() []StationNeighbor {
var result []StationNeighbor
for _, n := range sn.Neighbors {
if !n.IsExcluded {
result = append(result, n)
}
}
return result
}