mirror of
https://github.com/R0m1k3/LogiFlow.git
synced 2026-10-11 17:27:31 +02:00
fix(meteo): fall back to nearest cached data when the history API fails
The dashboard widget lost the previous-year temperature and the difference: when the day's previous-year row is not yet cached and the Visual Crossing history call fails (quota exhausted, outage, or a plan without history access), the route silently returned previousYear: null and the widget hid the comparison. The weather cache accumulates one previous-year row per day, so the route now falls back to the nearest cached previous-year entry within 7 days of the weekday-aligned target date, keeping the comparison on screen through API failures. The exact API error remains logged server-side (🌤️ [ERROR] / [FETCH-HISTORY]) for diagnosis. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FHdE9nEh8zHhQNGpCgrtYe
This commit is contained in:
2 files changed
+31
No files matched your search
@@ -5723,6 +5723,16 @@ RÉSUMÉ DU SCAN
|
||||
}
|
||||
}
|
||||
|
||||
// Repli : si l'API historique a échoué (quota épuisé, panne, plan sans
|
||||
// accès à l'historique), reprendre la ligne en cache la plus proche de
|
||||
// la date cible plutôt que de faire disparaître la comparaison N-1
|
||||
if (!previousYearData) {
|
||||
previousYearData = await storage.getNearestWeatherData(previousYearDate, false, 7);
|
||||
if (previousYearData) {
|
||||
console.log(`🌤️ [FALLBACK] Using nearest cached previous-year data (${previousYearData.date}) for target ${previousYearDate}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Toujours retourner une réponse même si seule l'année actuelle est disponible
|
||||
const response = {
|
||||
currentYear: currentYearData ? {
|
||||
|
||||
@@ -274,6 +274,7 @@ export interface IStorage {
|
||||
createWeatherData(data: InsertWeatherData): Promise<WeatherData>;
|
||||
updateWeatherData(id: number, data: Partial<InsertWeatherData>): Promise<WeatherData>;
|
||||
deleteOldWeatherData(daysToKeep: number): Promise<void>;
|
||||
getNearestWeatherData(date: string, isCurrentYear: boolean, maxDistanceDays: number): Promise<WeatherData | undefined>;
|
||||
clearWeatherCache(): Promise<void>;
|
||||
|
||||
// Historique des mails fournisseurs (rapprochement)
|
||||
@@ -2923,6 +2924,22 @@ export class DatabaseStorage implements IStorage {
|
||||
return weatherInfo;
|
||||
}
|
||||
|
||||
// Repli : ligne en cache la plus proche de la date demandée (à N jours près).
|
||||
// Utilisé quand l'API météo historique échoue (quota, panne) pour continuer
|
||||
// d'afficher la comparaison avec l'année dernière.
|
||||
async getNearestWeatherData(date: string, isCurrentYear: boolean, maxDistanceDays: number): Promise<WeatherData | undefined> {
|
||||
const [data] = await db
|
||||
.select()
|
||||
.from(weatherData)
|
||||
.where(and(
|
||||
eq(weatherData.isCurrentYear, isCurrentYear),
|
||||
sql`ABS(${weatherData.date} - ${date}::date) <= ${maxDistanceDays}`
|
||||
))
|
||||
.orderBy(sql`ABS(${weatherData.date} - ${date}::date)`)
|
||||
.limit(1);
|
||||
return data;
|
||||
}
|
||||
|
||||
async updateWeatherData(id: number, data: Partial<InsertWeatherData>): Promise<WeatherData> {
|
||||
const [weatherInfo] = await db
|
||||
.update(weatherData)
|
||||
@@ -5240,6 +5257,10 @@ export class MemStorage implements IStorage {
|
||||
return undefined; // Will trigger API calls
|
||||
}
|
||||
|
||||
async getNearestWeatherData(date: string, isCurrentYear: boolean, maxDistanceDays: number): Promise<WeatherData | undefined> {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
async createWeatherData(data: InsertWeatherData): Promise<WeatherData> {
|
||||
return {
|
||||
id: 1,
|
||||
|
||||
Reference in new issue
Block a user