- #21: Add missing await in removeChoiceIfPresent() to prevent user appearing in two restaurants - #15: Add 1-hour TTL for menu refetching to avoid scraping on every page load - #9: Block stats API and UI navigation for future dates - #14: Add restaurant warnings (missing soup/prices, stale data) with warning icon - #12: Pre-fill restaurant/departure dropdowns from existing choices on page refresh - #10: Add voting statistics endpoint and table on stats page
55 lines
1.9 KiB
TypeScript
55 lines
1.9 KiB
TypeScript
import { DailyStats, LunchChoice, WeeklyStats } from "../../types/gen/types.gen";
|
|
import { getStatsMock } from "./mock";
|
|
import { getClientData } from "./service";
|
|
import getStorage from "./storage";
|
|
|
|
const storage = getStorage();
|
|
|
|
/**
|
|
* Vypočte a vrátí statistiky jednotlivých možností pro předaný rozsah dat.
|
|
*
|
|
* @param startDate počáteční datum
|
|
* @param endDate koncové datum
|
|
* @returns statistiky pro zadaný rozsah dat
|
|
*/
|
|
export async function getStats(startDate: string, endDate: string): Promise<WeeklyStats> {
|
|
if (process.env.MOCK_DATA === 'true') {
|
|
return getStatsMock();
|
|
}
|
|
const start = new Date(startDate);
|
|
const end = new Date(endDate);
|
|
|
|
// Dočasná validace, aby to někdo ručně neshodil
|
|
const daysDiff = ((end as any) - (start as any)) / (1000 * 60 * 60 * 24);
|
|
if (daysDiff > 4) {
|
|
throw Error('Neplatný rozsah');
|
|
}
|
|
|
|
const today = new Date();
|
|
today.setHours(23, 59, 59, 999);
|
|
if (end > today) {
|
|
throw Error('Nelze načíst statistiky pro budoucí datum');
|
|
}
|
|
|
|
const result = [];
|
|
for (const date = start; date <= end; date.setDate(date.getDate() + 1)) {
|
|
const locationsStats: DailyStats = {
|
|
// TODO vytáhnout do utils funkce
|
|
date: `${String(date.getDate()).padStart(2, "0")}.${String(date.getMonth() + 1).padStart(2, "0")}.`,
|
|
locations: {}
|
|
}
|
|
const data = await getClientData(date);
|
|
if (data?.choices) {
|
|
Object.keys(data.choices).forEach(locationKey => {
|
|
if (!locationsStats.locations) {
|
|
locationsStats.locations = {}
|
|
}
|
|
// TODO dořešit, tohle je zmatek a té hlášce Sonaru nerozumím
|
|
locationsStats.locations[locationKey as LunchChoice] = Object.keys(data.choices[locationKey as LunchChoice]!).length;
|
|
})
|
|
}
|
|
result.push(locationsStats);
|
|
}
|
|
return result as WeeklyStats;
|
|
}
|