Alt-Bestand nie formatiert — isolierter Format-Lauf vor der myWeek-Query und
dem Woche-Nav-Tab.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Nachtarbeit über Mitternacht brach bisher den Check-Out ("Du bist heute
noch nicht locked in") und sperrte nach versehentlichem Feierabend den Tag.
- Tag = Kalendertag des Check-ins; eine über Mitternacht laufende Session
zaehlt zum Starttag, bis 06:00 des Folgetags (isWorkdaySealed)
- checkOut/today finden den offenen Eintrag statt stur "heute"
- reopen ("Arbeit fortsetzen") hebt einen Feierabend wieder auf
- applyWorkdayBoundary: nahtloser 6-Uhr-Schnitt (Auto-Checkout + Folge-Tag,
offene ToDos wandern mit)
- Reflexion/ToDo-Edit folgen der 6-Uhr-Grenze statt Mitternacht
- Cron apply-workday-boundaries fuer Team-Dashboard-Konsistenz
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Arbeitsantritt = bestehender Lock-in (setzt checkedInAt); neu dazu:
- Check-Out / Feierabend: dayEntry.checkedOutAt + Endpoint dayEntry.checkOut;
Heute-Seite zeigt „Arbeitsantritt HH:MM" und einen „Feierabend / Check-Out"-
Button, danach Antritt/Feierabend/Dauer.
- Kimai-Anbindung (config-gated, best-effort, nicht blockierend): lib/kimai.ts
mit clockIn/clockOut. Check-In startet ein Kimai-Timesheet, Check-Out stoppt
es; ID + Sync-Status auf dem dayEntry (kimaiTimesheetId, kimaiSynced).
No-Op solange KIMAI_BASE_URL/API_TOKEN/PROJECT_ID/ACTIVITY_ID nicht gesetzt.
Migration 0014 (checkedOutAt, kimaiTimesheetId, kimaiSynced). Env-Vars als
optional ergänzt + in .env.example dokumentiert.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Drive-by-Aufgaben ("btw, Yevgen-Security-Fix hab ich auch noch gemacht")
strukturiert erfassen statt nur im Freitext. Neues Feld todo.unplanned +
Endpoint dayEntry.addUnplanned: legt sofort ein erledigtes, als „ungeplant"
markiertes ToDo an.
- Schnell-Eingabe „Ungeplant erledigt" auf Heute (Mid-Day) und in der
Reflexion (End-of-Day-Recall).
- "ungeplant"-Badge in Heute, Reflexion und Historie.
- historyForDate liefert das unplanned-Flag mit.
- Reflexions-Freitext bleibt für die Tages-Story.
Migration 0012 (todo.unplanned).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Neue Seite /historie: pro vergangenem Tag sieht man, was jede/r gemacht hat —
Reflexion (Ampel/Trend/Text) + ToDos (erledigt/offen/verworfen), plus Liste
„ohne Eintrag". Datums-Navigation (vorheriger/nächster Werktag, Datum-Picker);
Default = vorheriger Werktag. Heutige Reflexionen bleiben privat (nur ToDos).
- Endpoint dayEntry.historyForDate({date?}) liefert Einträge + prev/next-Werktag.
- TopNav-Tab „Historie" (g i), Link „Ganze Historie →" im Dashboard-Feed.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Der Vortags-Feed verlangte published_at IS NOT NULL, gesetzt nur vom Cron
publish-day-entries. Auf Prod ist dieser Cron nicht eingeplant (keine crontab/
kein Scheduler) → published_at blieb bei allen echten Reflexionen null → Feed
immer leer (auf Dev sah's gut aus, weil der Seed published_at setzt).
Feed jetzt vom Cron entkoppelt: zeigt volle Reflexionen mit Datum < heute
(heutige bleiben privat bis morgen), sortiert nach Datum/Reflexionszeit.
Gilt für dashboard.overview.feed und dayEntry.feed.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Backend:
- Vortags-Feed (dashboard.overview + dayEntry.feed) sortierte aufsteigend
mit limit(50) → zeigte die ÄLTESTEN statt neuesten Einträge. Jetzt desc.
- deal.updateStage: wonValueEur wurde beim Gewinnen mit der Wahrscheinlichkeit
gewichtet → zu niedriger Won-Umsatz. Jetzt voller Auftragswert.
- Pflicht-Minimum „Status aktuell" wurde global (letzte Reflexion irgendwo)
statt pro Projekt berechnet. Jetzt je Projekt aus dem jüngsten Statusbericht.
- time.listToday/teamToday nutzten fixen +02:00-Offset → im Winter (CET) um
1h verschobene Tagesgrenze. Jetzt DST-sicher via AT TIME ZONE 'Europe/Berlin'.
Frontend:
- lead.tsx + projekt.tsx: Datumsanzeigen nutzten UTC (toISOString) → abends
Off-by-one. Jetzt Berlin-lokal formatiert.
- reflexion.tsx: Submit mappte nur den initialen ToDo-Snapshot → mitten am Tag
ergänzte ToDos verloren ihren Status. Jetzt über die aktuelle Liste.
- leads.tsx: CSV-Zeilenzähler konnte „-1" zeigen (Math.max).
- TimerPill: Label ohne Control (a11y-Lint-Error, war repo-weit rot) + unused
clsx-Import behoben → pnpm lint jetzt 0 Errors.
DB: seed.ts unbedingten updatedAt-Bump aller User entfernt (Debug-Rest).
README: vollständig auf aktuellen Stand gebracht (Leads/CRM, CSV-Import,
PM-Tiefe, Phasen/Status/Risiken/Stakeholder/Änderungen, Tabellen bis 0011,
tRPC-Router, staleTime 0, Auto-Deploy-Runner + Startup-Migrationen).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Nach dem Lock-in konnte man ToDos nur bearbeiten/abhaken, aber keine neuen
anlegen. Neuer Endpoint dayEntry.addTodo hängt ein einzelnes ToDo an den
heutigen Tageseintrag an (erlaubt solange der Eintrag vom heutigen
Berlin-Tag ist, auch nach der Reflexion). Inline-Feld „Neues ToDo
hinzufügen" in der EinstempeltView; aktualisiert Heute + Dashboard-Sichten.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ToDos in der Reflexion lassen sich per Klick auf den Titel korrigieren
(z. B. Tippfehler), Enter speichert / Escape bricht ab. Neuer Endpoint
dayEntry.editTodoTitle — nur eigene ToDos vom heutigen Berlin-Tag,
ändert den Titel in-place (Status/Reihenfolge/IDs bleiben).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Zeiterfassung
- Neue Tabelle time_entry mit started_at/ended_at/duration_seconds,
optional todo_id/bezug, category-Enum (focus/meeting/break/admin/learning/other),
description, day_entry_id-Verknüpfung. Partial-Unique-Index erzwingt
max. einen aktiven Timer pro User.
- tRPC time-Router: now, start (stoppt aktiven automatisch), stop,
listToday (Liste + Tagessumme), update, upsertManual (retroaktiv),
delete, teamToday (personenübergreifend mit byCategory + aktivem
Timer pro User).
- TopNav: persistente TimerPill links neben Streak. Quick-Picker mit
heutigen ToDos, Kategorie-Auswahl und Freitext-Start. Live-Sekundenzähler.
- /heute: TimelineSection mit Edit/Delete pro Eintrag, ToDo-Bindung
nachträglich änderbar, Block-nachtragen-Dialog. Pro ToDo-Zeile
▶-Start- und 🕐-Nachtrag-Button.
- /puls: TeamTimeSection mit aktiver Timer-Anzeige + Tagessumme +
Kategorie-Breakdown pro User (refresh alle 30s, Live-Tick jede Sekunde).
Visual
- Space Grotesk als Hausschrift (selbst-gehostet, latin + latin-ext)
- Keycap-Button-Stil (Gradient + Druckeffekt) für primary/secondary/destructive
- Neue Helper-Module: format-duration, time-categories
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>