aboutsummaryrefslogtreecommitdiff
path: root/src/Enmarcha.Backend/Services
diff options
context:
space:
mode:
authorAriel Costas Guerrero <ariel@costas.dev>2026-03-21 00:36:25 +0100
committerAriel Costas Guerrero <ariel@costas.dev>2026-03-21 00:36:25 +0100
commitf1b0b5f7ceaf6d23ae347e12cf29eef617c7dc9b (patch)
treed92c6075d019d87fd03482774050d7fc8981a5aa /src/Enmarcha.Backend/Services
parent2ef155c0c68208eccf968919fea12133698b50a9 (diff)
feat: enhance geocoding and stop search with performance metrics and improved response handling
Diffstat (limited to 'src/Enmarcha.Backend/Services')
-rw-r--r--src/Enmarcha.Backend/Services/FareService.cs14
-rw-r--r--src/Enmarcha.Backend/Services/Geocoding/GeoapifyGeocodingService.cs25
2 files changed, 32 insertions, 7 deletions
diff --git a/src/Enmarcha.Backend/Services/FareService.cs b/src/Enmarcha.Backend/Services/FareService.cs
index bf85f03..fda5eb5 100644
--- a/src/Enmarcha.Backend/Services/FareService.cs
+++ b/src/Enmarcha.Backend/Services/FareService.cs
@@ -22,6 +22,9 @@ public class FareService
private const decimal SantiagoCashFare = 1.00M;
private const decimal SantiagoCardFare = 0.36M;
+ private const decimal OurenseCashFare = 0.85M;
+ private const decimal OurenseCardFare = 0.49M;
+
public FareService(
IOptions<AppConfiguration> config,
XuntaFareProvider xuntaFareProvider,
@@ -71,6 +74,9 @@ public class FareService
case "vitrasa":
total += VitrasaCashFare;
break;
+ case "ourense":
+ total += OurenseCashFare;
+ break;
case "xunta":
// TODO: Handle potentiall blow-ups
if (leg.From is not { ZoneId: not null })
@@ -126,6 +132,11 @@ public class FareService
maxUsages = 2;
initialFare = SantiagoCardFare;
break;
+ case "ourense":
+ maxMinutes = 60;
+ maxUsages = 2;
+ initialFare = OurenseCardFare;
+ break;
case "xunta":
if (leg.From?.ZoneId == null || leg.To?.ZoneId == null)
{
@@ -182,9 +193,7 @@ public class FareService
}
else
{
- // Free transfer for city systems or non-ATM Xunta (though non-ATM Xunta has maxUsages=1)
validTicket.UsedTimes++;
- _logger.LogDebug("Free transfer for {FeedId}", leg.FeedId);
}
}
else
@@ -199,7 +208,6 @@ public class FareService
StartZone = leg.FeedId == "xunta" ? leg.From!.ZoneId! : string.Empty,
TotalPaid = initialFare
});
- _logger.LogDebug("New ticket for {FeedId}: {Cost}€", leg.FeedId, initialFare);
}
}
diff --git a/src/Enmarcha.Backend/Services/Geocoding/GeoapifyGeocodingService.cs b/src/Enmarcha.Backend/Services/Geocoding/GeoapifyGeocodingService.cs
index ce86c49..515613a 100644
--- a/src/Enmarcha.Backend/Services/Geocoding/GeoapifyGeocodingService.cs
+++ b/src/Enmarcha.Backend/Services/Geocoding/GeoapifyGeocodingService.cs
@@ -53,9 +53,17 @@ public class GeoapifyGeocodingService : IGeocodingService
try
{
- var response = await _httpClient.GetFromJsonAsync<GeoapifyResult>(url + $"&apiKey={_config.GeoapifyApiKey}");
-
+ var httpResponse = await _httpClient.GetAsync(url + $"&apiKey={_config.GeoapifyApiKey}");
+ if (!httpResponse.IsSuccessStatusCode)
+ {
+ var body = await httpResponse.Content.ReadAsStringAsync();
+ _logger.LogWarning("Geoapify autocomplete returned {StatusCode} for query '{Query}': {Body}",
+ (int)httpResponse.StatusCode, query, body);
+ activity?.SetTag("http.status_code", (int)httpResponse.StatusCode);
+ return [];
+ }
+ var response = await httpResponse.Content.ReadFromJsonAsync<GeoapifyResult>();
var results = response?.results
.Where(x => !ForbiddenResultTypes.Contains(x.result_type))
.Select(MapToPlannerSearchResult)
@@ -69,7 +77,7 @@ public class GeoapifyGeocodingService : IGeocodingService
{
activity?.SetStatus(System.Diagnostics.ActivityStatusCode.Error, ex.Message);
_logger.LogError(ex, "Error fetching Geoapify autocomplete results from {Url}", url);
- return new List<PlannerSearchResult>();
+ return [];
}
}
@@ -90,8 +98,17 @@ public class GeoapifyGeocodingService : IGeocodingService
$"https://api.geoapify.com/v1/geocode/reverse?lat={lat.ToString(CultureInfo.InvariantCulture)}&lon={lon.ToString(CultureInfo.InvariantCulture)}&lang=gl&format=json";
try
{
- var response = await _httpClient.GetFromJsonAsync<GeoapifyResult>(url + $"&apiKey={_config.GeoapifyApiKey}");
+ var httpResponse = await _httpClient.GetAsync(url + $"&apiKey={_config.GeoapifyApiKey}");
+ if (!httpResponse.IsSuccessStatusCode)
+ {
+ var body = await httpResponse.Content.ReadAsStringAsync();
+ _logger.LogWarning("Geoapify reverse geocode returned {StatusCode} for ({Lat},{Lon}): {Body}",
+ (int)httpResponse.StatusCode, lat, lon, body);
+ activity?.SetTag("http.status_code", (int)httpResponse.StatusCode);
+ return null;
+ }
+ var response = await httpResponse.Content.ReadFromJsonAsync<GeoapifyResult>();
if (response == null) return null;
var result = MapToPlannerSearchResult(response.results[0]);