feat(preise): beobachtete preise und wertentwicklung je set

Auf der Set-Detailseite lassen sich Preise notieren: Betrag, Zustand,
Datum, wo gesehen und eine Notiz. Daraus entsteht eine Reihe statt
eines einzelnen Feldes, denn die interessante Frage ist nicht "was
kostet es", sondern "was hat es seit dem Kauf gemacht".

Als Ausgangswert dient die UVP, sonst die aelteste Beobachtung; der
aktuelle Wert ist die neueste. Fallen am selben Tag zwei Beobachtungen
an, gewinnt der Neupreis - das ist die Zahl, die man zum Ersetzen
zahlen wuerde. Die Statistik-Kachel in der Sammlung zeigt entsprechend
"Aktueller Wert", sobald irgendwo ein Preis notiert ist, sonst
unveraendert "Wert nach UVP".

Bewusst nicht dabei: die Anbindung des BrickLink-Preisfuehrers. Sie war
im Plan als optional vermerkt und braucht OAuth1 mit einer pro Nutzer
registrierten Anwendung - viel Apparat fuer eine Zahl, die sich in zehn
Sekunden eintippen laesst. Die Datenstruktur ist dafuer offen: das Feld
"Wo" nimmt jede Quelle auf.

13 Tests fuer die Rechenwege, inklusive Division durch null, fehlender
UVP und Rundung.

Refs Phase 3

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
unknown
2026-09-07 09:17:03 +02:00
co-authored by Claude Opus 5
parent 87131b8e70
commit 91fb66b13b
14 changed files with 2695 additions and 2 deletions
+6 -1
View File
@@ -56,7 +56,12 @@ export default async function SammlungPage({ searchParams }: { searchParams: Sea
const tiles = [
{ icon: Boxes, label: 'Sets', value: formatNumber(stats.setCount) },
{ icon: Layers, label: 'Teile gesamt', value: formatNumber(stats.pieceCount) },
{ icon: Euro, label: 'Wert nach UVP', value: formatEuro(stats.retailValueCents) },
{
icon: Euro,
// Notierte Preise gehen vor, sonst die UVP.
label: stats.currentValueCents === stats.retailValueCents ? 'Wert nach UVP' : 'Aktueller Wert',
value: formatEuro(stats.currentValueCents),
},
{ icon: PackageSearch, label: 'Fehlt noch', value: formatNumber(missing) },
] as const;