feat: souhrn historie cen od začátku
CI / Generate TypeScript types (push) Successful in 10s
CI / Server unit tests (push) Successful in 26s
CI / Build server (push) Successful in 28s
CI / Build client (push) Successful in 41s
CI / Playwright E2E tests (push) Successful in 1m49s
CI / Build and push Docker image (push) Successful in 48s
CI / Notify (push) Successful in 1s

This commit is contained in:
batmanisko committed 2026-09-23 15:55:43 +02:00
1 parent e281615cc3
commit e7c4ba09ff
3 files changed
+124 -4

No files matched your search

+50
View File
@@ -0,0 +1,50 @@
import type { StorePriceHistoryEntry } from "../../../types";
export type SinceStart = {
/** Od kdy se počítá (první známá verze) */
since: string,
changed: { name: string, start: number, current: number }[],
added: { name: string, price?: number }[],
removed: { name: string, price?: number }[],
};
/**
* Souhrn „od začátku": počáteční cena položky = „before" její nejstarší změny,
* aktuální = „after" nejnovější. Položka přidaná a později zase odebraná se vynechá.
*/
export function computeSinceStart(entries: StorePriceHistoryEntry[]): SinceStart | undefined {
if (entries.length === 0) return undefined;
const chronological = [...entries].reverse();
const items = new Map<string, { name: string, start?: number, current?: number, addedLater: boolean, removed: boolean }>();
for (const entry of chronological) {
for (const c of entry.changes) {
const key = c.name.trim().toLowerCase();
let item = items.get(key);
if (!item) {
item = { name: c.name, start: c.before, addedLater: c.before == null, removed: false };
items.set(key, item);
}
item.name = c.name;
item.current = c.after;
item.removed = c.after == null;
}
}
const result: SinceStart = { since: chronological[0].at, changed: [], added: [], removed: [] };
for (const item of items.values()) {
if (item.addedLater && item.removed) continue;
if (item.addedLater) result.added.push({ name: item.name, price: item.current });
else if (item.removed) result.removed.push({ name: item.name, price: item.start });
else if (item.start != null && item.current != null && item.start !== item.current) {
result.changed.push({ name: item.name, start: item.start, current: item.current });
}
}
// Největší změny nahoře
result.changed.sort((a, b) => Math.abs(b.current - b.start) - Math.abs(a.current - a.start));
return result;
}
/** Český plurál: 1 změna, 2–4 změny, 5+ změn. */
export function plural(n: number, one: string, few: string, many: string): string {
const form = n === 1 ? one : n >= 2 && n <= 4 ? few : many;
return `${n} ${form}`;
}