fix(streak): Feiertage, Wochenend-Edge & Lookback-Deckel
- Feiertage: isWerktag berücksichtigt jetzt die 9 bundesweiten gesetzlichen Feiertage (Oster-Computus + feste Tage) → ein Feiertag bricht die Streak nicht mehr (zählt wie ein Wochenende neutral). Landesspezifische Feiertage bewusst (noch) nicht enthalten. - Wochenend-Edge: Reflexion an Sa/So setzte die angezeigte Streak auf 0 (Schleife brach am Nicht-Werktag ab). Jetzt wird übersprungen statt gebrochen. - Lookback von 120 auf 400 Tage erhöht, damit lange Streaks nicht abgeschnitten werden. - Streak-Zähllogik in reine, getestete countStreakDays() ausgelagert (8 Streak- + 5 Feiertags-Tests). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
1f0c9efd59
commit
bcae44eeb3
7 files changed
+256
-47
No files matched your search
@@ -0,0 +1,47 @@
|
||||
import { isWerktag, previousWerktag } from './werktag.js';
|
||||
|
||||
/**
|
||||
* Zählt aufeinanderfolgende Werktage (Mo-Fr, ohne Feiertage) mit voller
|
||||
* Reflexion, rückwärts ab `today`.
|
||||
*
|
||||
* Regeln:
|
||||
* - Nur Tage in `fullDates` (status = 'full') zählen.
|
||||
* - Tage in `absenceDates` (Urlaub/Krank/…) sind neutral: überspringen, nicht
|
||||
* zählen, nicht brechen.
|
||||
* - Wochenenden und Feiertage sind keine Werktage → übersprungen.
|
||||
* - Heute ist Schonfrist: ist heute noch nicht voll, wird ab dem vorherigen
|
||||
* Werktag gezählt (die laufende Streak bleibt über den Tag erhalten).
|
||||
* - Bricht beim ersten Werktag, der weder voll noch Abwesenheit ist.
|
||||
*/
|
||||
export function countStreakDays(opts: {
|
||||
today: string;
|
||||
fullDates: Set<string>;
|
||||
absenceDates: Set<string>;
|
||||
}): number {
|
||||
const { today, fullDates, absenceDates } = opts;
|
||||
let cursor = today;
|
||||
let streak = 0;
|
||||
|
||||
// Heute noch nicht reflektiert → ab vorherigem Werktag zählen.
|
||||
if (!fullDates.has(cursor)) cursor = previousWerktag(today);
|
||||
|
||||
while (true) {
|
||||
// Nicht-Werktag (z. B. an einem Wochenende/Feiertag reflektiert) überspringen,
|
||||
// statt die Streak fälschlich abzubrechen.
|
||||
if (!isWerktag(cursor)) {
|
||||
cursor = previousWerktag(cursor);
|
||||
continue;
|
||||
}
|
||||
if (absenceDates.has(cursor)) {
|
||||
cursor = previousWerktag(cursor);
|
||||
continue;
|
||||
}
|
||||
if (fullDates.has(cursor)) {
|
||||
streak++;
|
||||
cursor = previousWerktag(cursor);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return streak;
|
||||
}
|
||||
Reference in new issue
Block a user