58 Commits
Author SHA1 Message Date
dejanandClaude Fable 5 94faf5e41f Anwesenheit: Fallback-Anker erster Zeiteintrag bei Auto-Tagen
ci / quality (push) Failing after 38s
ci / build (push) Has been skipped
deploy / deploy (push) Successful in 1m1s
Auto-Tage vom 6-Uhr-Schnitt haben keinen echten Lock-in — statt die
Anwesenheit ganz auszublenden, ankert sie jetzt am ersten Zeiteintrag
des Tages. teamToday/listToday liefern presenceStartedAt/presenceEndedAt
(echter Check-in hat Vorrang); Team-Karte, Heute-Balken und "Zeit heute"
nutzen die neuen Felder.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 12:20:18 +02:00
dejanandClaude Fable 5 e049e0a88c Anwesenheit ignoriert Auto-Check-in vom 6-Uhr-Schnitt
ci / quality (push) Failing after 46s
ci / build (push) Has been skipped
deploy / deploy (push) Successful in 1m30s
Der 6-Uhr-Schnitt legt Folgetage mit checkedInAt=06:00 an — das ist kein
echter Lock-in, die Anwesenheitsanzeige lief dadurch fälschlich seit
06:00 mit (z. B. "6h 6m" mittags trotz spätem Arbeitsbeginn). Neues Flag
day_entry.auto_checked_in (Backfill: bestehende 06:00:00-Check-ins);
teamToday, Heute-Balken und "Zeit heute" zeigen Anwesenheit nur noch bei
echtem Check-in.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 12:13:57 +02:00
dejanandClaude Fable 5 e0fbc386fa Anwesenheit auch in "Zeit im Team heute" anzeigen
ci / quality (push) Failing after 30s
ci / build (push) Has been skipped
deploy / deploy (push) Successful in 53s
teamToday liefert pro Person checkedInAt/checkedOutAt aus dem heutigen
day_entry mit; die Team-Karte zeigt daneben "Anwesend: …" (live, bzw.
eingefroren nach Feierabend). Reine Anzeige, kein Eingriff ins Tracking.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 19:28:29 +02:00
dejanandClaude Fable 5 687325ad0d Anwesenheitszeit (Lock-in bis Feierabend) als reine Anzeige ergänzen
ci / quality (push) Failing after 36s
ci / build (push) Has been skipped
deploy / deploy (push) Successful in 1m19s
Neben der getrackten Task-Zeit zeigt der "Zeit heute"-Header jetzt
"Getrackt · Anwesend"; der Check-In/Out-Balken zeigt die Anwesenheit
live ("anwesend seit …") und nach Check-Out die finale Dauer. Kein
Eingriff ins Task-Tracking — Wert wird nur aus checkedInAt/checkedOutAt
berechnet.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 19:24:56 +02:00
Raffael SheikhandClaude Opus 4.8 a1cf6f3883 chore(format): Prettier über das gesamte Repo
ci / quality (push) Failing after 45s
ci / build (push) Has been skipped
deploy / deploy (push) Successful in 53s
Behebt die rote CI (format:check schlug an 36 Alt-Bestand-Dateien fehl:
migrations/meta-Snapshots, seed.ts, schemas/lead.ts, README u. a.) und erzwingt
nebenbei einen frischen web-Build beim Auto-Deploy (apps/web-Dateien geaendert
-> COPY-Layer invalidiert -> Vite baut neu).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 17:50:07 +02:00
Raffael SheikhandClaude Opus 4.8 b340b45110 Historie: nachträglich reflektieren bis 3 Tage nach dem Tag
ci / quality (push) Failing after 36s
ci / build (push) Has been skipped
deploy / deploy (push) Successful in 55s
Reflexion/ToDo-Bearbeitung war nur bis 06:00 des Folgetags moeglich. Jetzt
3-Tage-Nachfrist (isEditableWithinGrace) und ein Bearbeiten-Weg aus der Historie:

- werktag: isEditableWithinGrace(entryDate, now, 3) + Tests
- submitReflection/editTodoTitle: Sperre auf die 3-Tage-Nachfrist gelockert
- neue Query dayEntry.ownForDate(date): eigener Tageseintrag + editable-Flag
- reflexion.tsx liest ?date= und laedt vergangene Tage; Felder werden mit der
  bestehenden Reflexion vorbefuellt
- historie.tsx: "Bearbeiten"-Button am eigenen Eintrag (wenn <= 3 Tage)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 13:13:38 +02:00
Raffael SheikhandClaude Opus 4.8 6acf9977ec Historie: Task-Notizen + Link sichtbar, Navigation zu Tagen mit Einträgen
- Notizfeld pro Task in der Reflexion (optional, jeder Status) — nutzt das
  bestehende dropReason-Feld (Limit 200->500). Wird in der Historie bei JEDEM
  Status angezeigt (bisher nur bei "verworfen").
- Optionaler Tages-Link wird in der Historie jetzt angezeigt.
- Historie-Pfeile springen zum naechsten/vorherigen Tag MIT Eintraegen statt
  starr ueber Werktage — Wochenend-Arbeit (z. B. Sa 6.6.) ist nun erreichbar.
  Default-Tag = juengster Tag vor heute mit Eintrag.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 13:04:52 +02:00
Raffael SheikhandClaude Opus 4.8 6e7a910ed3 chore(format): Prettier auf historie.tsx anwenden
Alt-Bestand nie formatiert — isolierter Format-Lauf vor den Historie-Aenderungen.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 13:03:18 +02:00
Raffael SheikhandClaude Opus 4.8 62945201b1 Feature: Lessons-Learned-Vorlage beim Projekt-Abschluss
Der Abschluss verlangte eine URL + freie Vermerk-Textarea, half aber nicht beim
Strukturieren der Retro. Jetzt gefuehrte Felder (Ziel erreicht? / Aufwand vs.
Plan / was lief gut / was nicht), gespeichert als JSONB project.lessons_learned
(Migration 0018). Anzeige im Projekt-Detail als "Retrospektive"; Altprojekte
fallen auf den freien Abschlussvermerk zurueck.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 12:45:19 +02:00
Raffael SheikhandClaude Opus 4.8 7a7cc75dd6 Feature: „Meine Woche" — persönliche 7-Tage-Übersicht
Alle Bausteine waren da (Ampel/Trend, ToDo-Status, Anwesenheit), aber niemand
sah je seinen eigenen Verlauf. Neue Query dayEntry.myWeek + Route /meine-woche
(pro Tag Ampel, Antritt→Feierabend, ToDo-Zähler). Nav-Tab „Woche" + Shortcut g w.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 12:39:09 +02:00
Raffael SheikhandClaude Opus 4.8 4311eadf50 chore(format): Prettier auf day-entry.ts + TopNav.tsx anwenden
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>
2026-06-07 12:37:59 +02:00
Raffael SheikhandClaude Opus 4.8 a0a2392e3d Feature: Globale Schnellsuche (Cmd/Ctrl+K oder „/")
Keine Sprung-zu-Suche bei wachsender Projekt-/Lead-Zahl. Neuer search-Router
(ILIKE ueber Projekte, Leads, offene Blocker) + Command-Palette ueber die
Modal-Basis, getriggert per Cmd/Ctrl+K oder „/". Klick springt zum Ziel.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 12:34:25 +02:00
Raffael SheikhandClaude Opus 4.8 aad247dd4a Feature: Deal-Pipeline-UI (totes Deal-Backend reaktiviert)
Das vollstaendige Deal-Backend (list/kpis/updateStage) lag ohne UI brach;
Lead->Deal-Promotion war eine Sackgasse. Neue Route /pipeline: KPI-Header
(gewichtete Pipeline, offene Deals, gewonnen/Quartal) + Spalten je Stufe
(lead/erstgespraech/demo/angebot/abschluss), Stufenwechsel per Select
(deal.updateStage). Verlinkt von /leads. Kein Drag-Kanban (CONVENTIONS).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 12:27:54 +02:00
Raffael SheikhandClaude Opus 4.8 6a25383cbe chore(format): Prettier auf router.tsx anwenden
Alt-Bestand nie formatiert — isolierter Format-Lauf vor der Pipeline-Route.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 12:27:14 +02:00
Raffael SheikhandClaude Opus 4.8 23e850287c Feature: Fällige Lead-Wiedervorlagen auf der Leads-Seite
naechsterSchrittDatum wurde erfasst, aber nie als faellige Liste geb√ºndelt —
warme Leads gingen unter. Neue Query lead.dueFollowUps (aktive Leads mit
faelligem/ueberfaelligem naechsten Schritt) + "Faellige Wiedervorlagen"-Block
oben auf /leads.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 12:19:13 +02:00
Raffael SheikhandClaude Opus 4.8 7dd1f2fb20 Feature: Zeit-pro-Projekt-Auswertung im Projekt-Detail
time_entry erfasst bezugKind='project'+bezugId, aber niemand sah je, wie viel
Zeit ein Projekt frisst. Neue Query time.byProject (Gesamtsumme + pro Person);
neue "Getrackte Zeit"-Sektion im Projekt-Detail (blendet sich aus, wenn nichts
getrackt wurde).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 12:15:05 +02:00
Raffael SheikhandClaude Opus 4.8 ff0a15b94e UI: Touch-Sichtbarkeit der Hover-Aktionen
Edit/Delete/Start/Zeit-Buttons waren nur per group-hover sichtbar (opacity-0)
und damit auf Touch-Geraeten unerreichbar. Jetzt mobil dauerhaft sichtbar, ab
sm (Desktop) weiterhin Hover-Reveal.

- TimelineSection (Bearbeiten/Loeschen einer Zeit-Zeile)
- heute (Task starten/fortsetzen, Zeit nachtragen)
- reflexion (ToDo-Titel bearbeiten)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 11:50:54 +02:00
Raffael SheikhandClaude Opus 4.8 f600c9f187 UI: alle 8 Dialoge auf barrierearme Modal-Basis umgestellt
Bisher waren alle Overlay-Dialoge plain divs ohne role/Fokus-Trap/Escape.
Jetzt setzen sie auf <Modal> auf (role=dialog, aria-modal, Fokus-Trap +
-Rueckgabe, Escape, Body-Scroll-Lock, konsistenter X-Button, Scroll bei langem
Inhalt).

- Modal: X-Schliessen-Button + max-h-[90vh]/overflow-y-auto ergaenzt
- BlockerDialog, ManualDialog (Timeline)
- leads: CSV-Import + Neuer Lead
- bereich: Neues Projekt
- projekt: Gate-Review + Projekt abschliessen
- lead: Zu Deal machen

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 11:49:05 +02:00
Raffael SheikhandClaude Opus 4.8 30006e3b32 chore(format): Prettier auf B4-Zieldateien anwenden
Vorbereitung der Modal-Umstellung: TimelineSection/leads/bereich (Alt-Bestand
nie formatiert) + kleiner B3-Nachzug in projekt/lead. Reine Formatierung, damit
die folgenden Modal-Commits nur echte Aenderungen zeigen.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 11:38:40 +02:00
Raffael SheikhandClaude Opus 4.8 8b0df9cc4e UI: Fehler-States statt weißer Leerseiten bei Query-Fehlern
Dashboard/Projekt/Lead/Team/Historie rendern bei fehlgeschlagener Query nicht
mehr ein stilles `return null` (leere weisse Seite), sondern einen Hinweis mit
"Neu laden"-Button.

- Neue Komponente ErrorState (Meldung + optionaler Retry)
- 5 Routen: if (q.isError || !q.data) -> ErrorState mit q.refetch()

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 11:35:52 +02:00
Raffael SheikhandClaude Opus 4.8 90caa282ee UI: Bestätigungsdialog vor allen Löschungen (Projekt + Lead)
Bisher loeschten 8 Muelltonnen-Icons sofort und unwiderruflich, ganz ohne
Rueckfrage. Jetzt fragt jeder Loeschpfad ueber useConfirm() nach.

- projekt.tsx: Aenderung, Stakeholder, Risiko, Meilenstein
- lead.tsx: Kontakt, Touchpoint, offene Frage, Anhang

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 11:28:48 +02:00
Raffael SheikhandClaude Opus 4.8 33a740ca7e chore(format): Prettier auf heute/projekt/lead.tsx anwenden
Diese drei Dateien waren nicht prettier-konform (nie formatiert). Isolierter
Format-Lauf, damit der folgende Logik-Commit nur die echten Aenderungen zeigt.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 11:28:19 +02:00
Raffael SheikhandClaude Opus 4.8 00b611fa3b UI: Modal-Basis + Confirm-Infrastruktur + Feierabend-Tagesabschluss
Fundament für Paket B (UI/UX-Härtung):
- Modal: barrierearmer Basis-Dialog (role/aria-modal, Fokus-Trap, Escape,
  Fokus-Rückgabe, Body-Scroll-Lock, Portal). Basis für alle App-Dialoge.
- ConfirmProvider/useConfirm: imperative Bestaetigung (await confirm({...}))
  statt window.confirm(); wird als Naechstes an die Loeschpfade gehaengt.
- Feierabend-Dialog: Tagesabschluss mit Zusammenfassung (erledigt/offen/
  verworfen) + Hinweis auf offene/unreflektierte ToDos und fehlende Reflexion.
  Check-Out feuert erst nach Bestaetigung; bleibt reversibel.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 11:19:40 +02:00
Raffael SheikhandClaude Opus 4.8 39e259f3ac Arbeitstag-Grenze auf 6 Uhr + Feierabend reversibel
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>
2026-06-07 10:48:23 +02:00
dejanandClaude Opus 4.8 b39c67d1aa Zeit-heute-Liste aufsteigend sortieren (Vormittag → Abend)
ci / quality (push) Failing after 34s
ci / build (push) Has been skipped
deploy / deploy (push) Successful in 46s
Blöcke werden jetzt nach Startzeit aufsteigend angezeigt statt neueste
zuerst.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 21:08:35 +02:00
dejanandClaude Opus 4.8 3e61cd563d Status-Anzeige robust gegen leere/lahmende Verlauf-Query
ci / quality (push) Failing after 43s
ci / build (push) Has been skipped
deploy / deploy (push) Successful in 46s
Der aktuelle Projektstatus hing allein an der statusHistory-Query. Kam
die beim Laden mal leer oder fehlerhaft zurück, stand fälschlich "Noch
kein Status gesetzt", obwohl der statusCache (aus demselben byId-Load)
den Status hatte. Jetzt: Verlauf vorhanden -> volle Anzeige; sonst
Fallback auf statusCache-Badge; "Noch kein Status" nur wenn die Query
erfolgreich leer ist. Zusätzlich Lade-/Fehlerzustand.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 21:00:53 +02:00
dejanandClaude Opus 4.8 8b49641c3f Reflexionsfeld "Sonst noch was?" in "Fazit" umbenennen
ci / quality (push) Failing after 39s
ci / build (push) Has been skipped
deploy / deploy (push) Successful in 45s
Label + Platzhalter angepasst: jeder fasst im Fazit zusammen, was er
gemacht hat. Damit ergibt auch der Text in "Gestern im Team" Sinn.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 20:54:13 +02:00
dejanandClaude Opus 4.8 ba8e524261 Deadline nachträglich editierbar, Arbeitsmodus aus UI entfernen
ci / quality (push) Failing after 28s
ci / build (push) Has been skipped
deploy / deploy (push) Successful in 53s
Deadline lässt sich jetzt direkt im Projekt-Header bearbeiten (Inline-
Datepicker mit Freitag/Wochenende-Warnung), via project.update. Der
Arbeitsmodus (Kanban/Cycle) ist in ebw bedeutungslos und fliegt aus der
Projekterstellung und der Header-Zeile raus. DB-Spalte bleibt ungenutzt
bestehen (keine destruktive Migration nötig).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 20:52:16 +02:00
dejanandClaude Opus 4.8 684841ffb4 Projektlogo auch in Dashboard-Listen anzeigen
ci / quality (push) Failing after 43s
ci / build (push) Has been skipped
deploy / deploy (push) Successful in 53s
Logo erscheint jetzt zusätzlich bei "Anstehende Meilensteine" (neben dem
Projekt-Link) und bei "Pflicht-Minimum offen" (vor dem Namen). Dashboard-
Queries liefern dafür project.logoUrl mit.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 20:47:58 +02:00
dejanandClaude Opus 4.8 1206dc5e0f Projektlogo: quadratisches Logo hochladen & anzeigen
ci / quality (push) Failing after 42s
ci / build (push) Has been skipped
deploy / deploy (push) Successful in 53s
Logo kann bei der Projekterstellung und nachträglich im Projekt-Header
hochgeladen werden. Client-seitiger Center-Crop auf 256px WebP, gespeichert
als Data-URL in neuer Spalte project.logo_url (Migration 0016). Anzeige in
der Bereichs-Projektliste (Card) und im Detail-Header, mit Initialen-
Platzhalter wenn kein Logo gesetzt ist.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 20:44:58 +02:00
dejanandClaude Opus 4.8 77cb36cd72 Bereichs-Karten aus dem Dashboard entfernen
ci / quality (push) Failing after 34s
ci / build (push) Has been skipped
deploy / deploy (push) Successful in 45s
Die Bereiche (Entwicklung/Vertrieb/Marketing/Allgemein) raus aus dem
Dashboard. AmpelDot + Ampel-Typ wurden dadurch ungenutzt, ebenfalls
entfernt.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 20:32:31 +02:00
dejanandClaude Opus 4.8 1b186d8be6 Anstehende Meilensteine im Dashboard anzeigen
ci / quality (push) Failing after 38s
ci / build (push) Has been skipped
deploy / deploy (push) Successful in 52s
Projektübergreifende Liste offener/überfälliger Meilensteine mit Datum,
sortiert nach Fälligkeit. Überfällige rot markiert, relative Tagesangabe
("in 3 Tagen" / "überfällig"), direkt verlinkt aufs Projekt. Sitzt oben
zwischen Showstoppern und kritischen Modi.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 20:29:16 +02:00
dejanandClaude Opus 4.8 e46d107b2d Verlinkungen im Projekt-Detail editierbar machen
ci / quality (push) Failing after 43s
ci / build (push) Has been skipped
deploy / deploy (push) Successful in 51s
Risikoliste und Lessons Learned konnten bisher nur beim Anlegen bzw.
Abschluss gesetzt werden. Jetzt ist die ganze Verlinkungen-Karte über
"Bearbeiten" editierbar (Outline, Plane, Risikoliste, Lessons Learned).
Leeres Feld entfernt den Link, URLs werden serverseitig validiert.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 20:11:44 +02:00
dejanandClaude Opus 4.8 390a99bf5e chore: "Buch"-Erwähnungen aus UI & Kommentaren entfernen
ci / quality (push) Failing after 36s
ci / build (push) Has been skipped
deploy / deploy (push) Successful in 1m11s
User-sichtbare Hinweise (Meilenstein-Mindestanzahl, Stakeholder-Empty,
Freitags-Warnung) ohne Quellenangabe umformuliert; Dev-Kommentare von
"Buch Kap. X" auf "Leitfaden" geändert.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 19:49:39 +02:00
dejanandClaude Opus 4.8 7f9a4506c5 refactor(zeit): Pausen nicht mehr buchen — Lücken zwischen Tasks = Pause
ci / quality (push) Failing after 45s
ci / build (push) Has been skipped
deploy / deploy (push) Successful in 53s
Pause-Feature entfernt: kein Pause-Button, kein break-Buchen mehr. Man bucht
nur Tasks; stoppt man eine Task und es läuft keine andere, ist die Lücke
automatisch eine Pause — im Kalender/Tagesansicht schlicht leer. Tasks bleiben
pausierbar (Stop = Pause, erneut Start = Fortsetzen → mehrere Segmente auf
dieselbe Task, Lücke dazwischen leer). Wall-Clock zählt Lücken ohnehin nicht.

- time.pause-Endpoint entfernt; 'break' aus der angebotenen Kategorienliste
  raus (bleibt im Enum für Altdaten).
- TimerPill: Pause-Button + Pause-Panel-Grund entfernt; Stop/Start je Task bleibt
  (= pausieren/fortsetzen). Heute-ToDo-Zeile entsprechend beschriftet.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 18:56:54 +02:00
dejanandClaude Opus 4.8 5bbb4abffa feat(zeit): Check-In/Check-Out + Kimai-Sync-Naht (ENTWICKLUN-9)
ci / quality (push) Failing after 42s
ci / build (push) Has been skipped
deploy / deploy (push) Successful in 1m20s
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>
2026-06-06 18:46:18 +02:00
dejanandClaude Opus 4.8 9942cd8e88 feat(zeit): mehrere Timer parallel (ENTWICKLUN-6)
ci / quality (push) Failing after 44s
ci / build (push) Has been skipped
deploy / deploy (push) Successful in 53s
Mehrere Tasks gleichzeitig tracken. Unique-Index "ein aktiver Timer pro User"
entfernt (Migration 0013); time.start stoppt den laufenden nicht mehr, sondern
läuft parallel.

- time.now liefert jetzt ALLE laufenden Timer (Array) inkl. ToDo-Titel.
- time.stop({id}) stoppt einen bestimmten Timer; time.stopAll stoppt alle.
- time.pause stoppt ALLE laufenden Tasks und startet eine Pause (passt zum
  Pause-Ticket „alle laufenden Tasks pausiert").
- TimerPill: zeigt Anzahl laufender Timer; Panel listet alle mit Live-Zähler +
  einzelnem Stop, „Weiteren Task starten", Grund-Nachtrag für Pausen.
- Heute-ToDo-Zeile: Start/Stop pro ToDo unabhängig (Array-basiert).

Zusammenspiel: Team-Timeline zeigt parallele Stränge, „Gesamt"-Zeit zählt
Überlappung weiterhin nur einmal (Wall-Clock).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 18:28:48 +02:00
dejanandClaude Opus 4.8 66adc49e2c feat(heute): ungeplant Erledigtes nachtragen (ENTWICKLUN-7)
ci / quality (push) Failing after 43s
ci / build (push) Has been skipped
deploy / deploy (push) Successful in 53s
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>
2026-06-06 18:09:38 +02:00
dejanandClaude Opus 4.8 516b35bf15 feat(team-view): horizontale Team-Timeline (ENTWICKLUN-8)
ci / quality (push) Failing after 33s
ci / build (push) Has been skipped
deploy / deploy (push) Successful in 1m17s
Neue Seite /team (Tab „Team", g t): horizontale Tages-Timeline mit einer Spur
pro Person. Zeit-Blöcke werden nach Start/Ende auf einer Stundenachse
positioniert, eingefärbt nach Kategorie; überlappende Blöcke landen auf
parallelen Sub-Spuren ("parallele Zeitstränge"). Laufende Blöcke (heute) ticken
live und sind rot umrandet. Datums-Navigation (Tag vor/zurück, Picker, „Heute"),
Hover-Tooltip mit Label/Zeitraum/Dauer, Kategorie-Legende.

Endpoint time.teamTimeline({date?}) liefert pro Person die Roh-Einträge
(Start/Ende/Kategorie/Label); Achse & Sub-Spuren rechnet das Frontend.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 17:58:47 +02:00
dejanandClaude Opus 4.8 9bf20fbabd feat(historie): team-weite Tages-Historie (ENTWICKLUN-10)
ci / quality (push) Failing after 46s
ci / build (push) Has been skipped
deploy / deploy (push) Successful in 55s
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>
2026-06-06 17:46:49 +02:00
dejanandClaude Opus 4.8 8fd72bcb69 fix(zeit): über Mitternacht laufende Timer bleiben sichtbar (ENTWICKLUN-14)
ci / quality (push) Failing after 40s
ci / build (push) Has been skipped
deploy / deploy (push) Successful in 53s
Ein um 23:00 gestarteter, noch laufender Timer hatte Start-Datum = gestern und
fiel nach Mitternacht aus listToday/teamToday (Filter nach Start-Datum=heute) —
nur die TimerPill zeigte ihn noch.

- listToday/teamToday: Filter „overlapsToday" = heute gestartet ODER heute
  beendet (Mitternacht überschritten) ODER laufend → Eintrag bleibt sichtbar.
- Tages-Summen clampen den Anteil auf den heutigen Tag (berlinDayStartMs,
  DST-korrekt) → über Mitternacht gelaufene Blöcke werden nicht falsch zugezählt.
- ToDo-Titel werden tagesübergreifend serverseitig aufgelöst (time.now +
  listToday) → Task bleibt benannt, auch wenn das ToDo von gestern ist.
- Timeline zeigt das Start-Datum, wenn ein Eintrag nicht heute begonnen hat.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 17:29:47 +02:00
dejanandClaude Opus 4.8 040dd62735 fix(web): Stale-Chunk-Fehler nach Deploy automatisch abfangen
ci / quality (push) Failing after 39s
ci / build (push) Has been skipped
deploy / deploy (push) Successful in 57s
"Failed to fetch dynamically imported module" trat auf, wenn ein offener Tab
nach einem Deploy auf alte (gehashte, inzwischen gelöschte) Route-Chunks zeigt.
Jetzt:
- lazyWithReload() lädt bei fehlgeschlagenem Lazy-Import einmal automatisch neu
  (holt frische index.html); sessionStorage-Guard verhindert Reload-Schleifen.
- vite:preloadError-Event wird ebenfalls abgefangen (modulepreload-Fehler).
- errorElement (RouteError) ersetzt die Dev-Default-Fehlerseite durch eine
  saubere "Neu laden"-Ansicht als Fallback.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 17:15:01 +02:00
dejanandClaude Opus 4.8 02bd682fa5 feat(zeit): Pause-Button (ENTWICKLUN-15)
ci / quality (push) Failing after 35s
ci / build (push) Has been skipped
deploy / deploy (push) Successful in 46s
Pause-Button in der Timer-Pill (sichtbar im Leerlauf und während ein Task
läuft): ein Klick stoppt den laufenden Task und startet sofort eine Pause
(break-Eintrag) — bis man wieder eine Aufgabe aktiviert. Läuft eine Pause,
zeigt die Pill sie mit Live-Zähler; ein Panel erlaubt optional einen Grund
nachzutragen (z. B. Bürofahrt, Essen), „Weiter mit Aufgabe" oder „Pause
beenden". Grund ist optional — Pause kann einfach Pause sein.

Reine Frontend-Änderung (nutzt time.start mit category 'break'), keine Migration.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 17:11:23 +02:00
dejanandClaude Opus 4.8 22f79460b2 fix: Bug-Review-Fixes + README aktualisiert
ci / quality (push) Failing after 38s
ci / build (push) Has been skipped
deploy / deploy (push) Successful in 53s
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>
2026-06-06 17:00:03 +02:00
dejanandClaude Opus 4.8 19db774c4c feat(leads): Leads universell mit Projekten verknüpfen
ci / quality (push) Failing after 44s
ci / build (push) Has been skipped
deploy / deploy (push) Successful in 54s
Ein Projekt lebt in genau einem Heimat-Bereich und wird einmal angelegt;
Leads bekommen eine optionale Verknüpfung dorthin (lead.projectId), egal in
welchem Bereich das Projekt wohnt — kein redundantes Anlegen mehr.

- Migration 0011: lead.project_id (FK → project, ON DELETE SET NULL).
- Lead anlegen / CSV-Import / Lead-Detail: Projekt zuordnen; CSV ordnet alle
  importierten Leads einem Projekt zu.
- Projektseite: neue "Leads"-Sektion (Vertriebs-Sicht des Projekts).
- Vertrieb: "Projekte mit Vertriebsaktivität" — bereichsübergreifend alle
  Projekte mit verknüpften Leads (so erscheint ein Entwicklungsprojekt hier,
  WEIL es Leads hat). Rein interne Projekte ohne Leads tauchen nicht auf.
- Lead-Liste/Detail zeigen das verknüpfte Projekt.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 16:08:59 +02:00
dejanandClaude Opus 4.8 68480c1eb1 feat(heute): ToDos mitten am Tag hinzufügen
ci / quality (push) Failing after 33s
ci / build (push) Has been skipped
deploy / deploy (push) Successful in 52s
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>
2026-06-06 15:47:54 +02:00
dejanandClaude Opus 4.8 1f0c9efd59 fix(web): Daten nach Aktionen ohne Refresh aktuell
ci / build (push) Has been skipped
deploy / deploy (push) Successful in 47s
ci / quality (push) Failing after 42s
staleTime war 30 s → nach „Lock in" zeigte das Dashboard bis zu 30 s alte
Cache-Stände, erst ein Browser-Refresh half. Jetzt staleTime 0: Seiten
holen beim Aufrufen/Tab-Fokus frische Daten (kein Polling). Zusätzlich
invalidiert checkIn jetzt dashboard.overview, dayEntry.todayTeam und
todayPresence, damit ein offenes Dashboard sofort mitzieht.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 15:27:29 +02:00
dejanandClaude Opus 4.8 b7b54fcec5 fix(zeit): Gesamt-Zeit als Wall-Clock statt Summe paralleler Tasks
ci / quality (push) Failing after 1m8s
ci / build (push) Has been skipped
deploy / deploy (push) Successful in 1m55s
"Zeit im Team heute" (und "Zeit heute") summierten alle Task-Dauern —
wer 5 Tasks parallel trackt, hatte 10h statt 2h Anwesenheit. Gesamt wird
jetzt als Vereinigung überlappender Intervalle berechnet (unionSeconds).
Pro-Aufgabe/Kategorie bleibt separat als Summe erhalten und wird als
"getrackt X" angezeigt; der Verteilungsbalken nutzt diese Summe als Nenner.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 15:06:27 +02:00
dejanandClaude Opus 4.8 43eeabaea2 fix(bereich): Bereich-Dropdown im "Neues Projekt"-Dialog war leer
ci / quality (push) Failing after 45s
ci / build (push) Has been skipped
deploy / deploy (push) Successful in 53s
Zwei Ursachen behoben:
- Frontend: areaId/Default wurden nur beim Mount aus dem (noch ladenden)
  areas-Prop berechnet → kein Default, keine Platzhalter-Option. Jetzt via
  useEffect Default setzen sobald Areas geladen sind + Platzhalter-Option.
- Prod: Deploy seedet nicht → frische DB hatte keine Areas. Neue
  ensureBaseAreas() legt die Basis-Bereiche idempotent beim API-Start an
  (nach den Migrationen), analog zu runMigrations.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 19:28:59 +02:00
Raffael SheikhandClaude Opus 4.8 67e8916634 fix(web): Caddyfile ins Image backen — SPA statt Caddy-Default-Seite
ci / quality (push) Failing after 37s
ci / build (push) Has been skipped
deploy / deploy (push) Successful in 52s
Das web-Runtime-Image (caddy:2-alpine) hatte keine eigene Config, daher
lieferte Caddy seine Default-Welcome-Seite aus /usr/share/caddy statt der
gebauten SPA aus /srv ("Caddy works!"). Eigene Caddyfile (root /srv,
try_files SPA-Fallback) wird jetzt nach /etc/caddy/Caddyfile kopiert.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 19:02:27 +02:00