# Changelog All notable changes to this project are documented in this file. ## [1.129.0] - 2026-09-14 ### Added - **Neue "Überfällig"-Übersicht** für Aufgaben, die in der Vergangenheit geplant und nicht erledigt wurden. Bislang wandern nur Aufgaben mit aktiviertem Rolling-Schalter (oder bei global aktiviertem Auto-Rolling) automatisch auf heute — alles andere blieb für immer auf seinem ursprünglichen Datum stehen und verschwand aus dem Blick, sobald man in der Wochenansicht weitergeklickt hat. - Neuer Menüpunkt "Überfällig" mit Anzahl-Badge, direkt neben "Wiederkehrend" in allen bestehenden Menü-Varianten (linke/obere Randleiste, mobile Leiste, Kopfzeile). - Dialog gruppiert nach dem ursprünglich geplanten Tag (älteste zuerst), pro Aufgabe Checkbox zum Erledigen und ein Knopf zum Verschieben auf heute, dazu "Alle auf heute verschieben". - Reine Erkennungs-/Gruppierungslogik in `src/lib/weekly/overdue.ts` (10 Unit-Tests), Darstellung in `src/components/OverdueTasksManager.tsx` — nutzt `LinkifiedText` (v1.128.0), Titel mit URLs bleiben also auch hier anklickbar. - Verschieben/Erledigen läuft über die bestehenden `moveTaskToSlot`/`toggleTask`-Pfade, keine neue API, keine neue Persistenzlogik. Verifiziert nicht nur mit Unit-Tests: lokale Instanz mit Wegwerf-Postgres (Docker) aufgesetzt, drei überfällige Aufgaben geseedet (eine davon mit URL im Titel), per Playwright eingeloggt und die Übersicht geöffnet — Badge, Gruppierung und Link-Rendering per Screenshot geprüft. Danach real geklickt: eine Aufgabe per Checkbox erledigt, eine per Knopf auf heute verschoben, die restlichen zwei per Sammelknopf — alle drei Änderungen per Datenbankabfrage bestätigt. Zusätzlich: Typecheck, Lint (0 Fehler), 118 Unit-Tests (10 neu), Produktions-Build. ## [1.128.0] - 2026-09-14 ### Fixed - **Eine im Aufgabentitel getippte URL war kein Link, sondern nur Text** — ein Klick darauf hat je nach Ansicht die Aufgabe durchgestrichen (Tagesraster) oder den Bearbeiten-Modus geöffnet (Kanban/Someday/Liste/Priorität), statt den Link zu öffnen. Neue reine Erkennungsfunktion `splitTextAndUrls` (`src/lib/weekly/format.ts`, 8 Unit-Tests) zerlegt den Titel in Text- und URL-Abschnitte; die neue Komponente `LinkifiedText` (`src/components/weekly/LinkifiedText.tsx`) rendert URL-Abschnitte als echten Link mit `stopPropagation`, damit ein Klick darauf ausschließlich den Link öffnet. Eingebaut in `GridTaskBlock.tsx`, `weekly/TaskItem.tsx` und `PriorityView.tsx` — überall dort, wo ein Aufgabentitel als reiner Text stand. Keine Änderung an Daten, API oder dem separaten `task.url`-Feld. Verifiziert: Typecheck, Lint (0 Fehler), 108 Unit-Tests (8 neu), Produktions-Build. ## [1.127.0] - 2026-09-14 ### Added - **Aufgaben lassen sich jetzt auch auf Touch-Geräten zwischen Zeitslots verschieben.** Bisher funktionierte das nur am Desktop, weil `WeeklyView.tsx` ausschließlich natives HTML5-Drag nutzte, das auf Touch-Geräten nicht feuert (siehe v1.126.0). Neuer Long-Press-Mechanismus in `GridTaskBlock`/`WeeklyView.tsx` (200 ms Halten, danach Ziehen), technisch dieselbe Zwei-Phasen-Architektur wie der bereits bestehende Touch-Long-Press für „Termin per Ziehen anlegen". Ruft am Ende dasselbe `handleDrop` wie der Desktop-Pfad auf — keine eigene Entscheidungslogik, keine geänderte API-Payload. Verifiziert nicht nur mit Unit-Tests, sondern gegen eine echte, lokal laufende Instanz mit eigener Wegwerf-Datenbank: ein per Playwright simulierter Touch-Drag (echte `TouchEvent`-Objekte, 200 ms Halten, schrittweise Bewegung, Loslassen) hat eine Aufgabe tatsächlich auf einen neuen Zeitslot verschoben, in der Datenbank nachgeprüft. Derselbe Test mit `dragTo()` (Maus/Desktop) bestätigt, dass der bestehende Pfad unverändert funktioniert. Zusätzlich: Typecheck, Lint (0 Fehler), 100 Unit-Tests, Produktions-Build. ## [1.126.0] - 2026-09-13 ### Changed - Erster Refactoring-Schnitt aus `TODO-CODESCENE-FORTSETZUNG-2026-09-12.md`: die fachliche Drop-Entscheidung aus `WeeklyView.tsx`s `handleDrop` (Ziel-Slot-Suche bei Belegung, Unterschied Subtask-Beförderung/Someday-Verschieben/normales Verschieben) ist jetzt eine reine, isoliert getestete Funktion `decideTaskDrop` in `src/lib/weekly/drag-drop.ts`. `handleDrop` liest nur noch Eingaben, ruft die Entscheidung auf und führt exakt die bisherigen Seiteneffekte aus (kein geändertes `fetch`, kein geändertes optimistisches UI-Update, keine geänderte API-Payload). - 15 neue Unit-Tests decken die Entscheidung ab: freier/belegter/geschützter Slot, Drop ohne Slot mit/ohne vorhandene Startzeit, Subtask-Beförderung, Someday-Provider-Vererbung, externe Sync-Bedingung, virtuelle wiederkehrende Instanzen (Server materialisiert sie weiterhin unverändert). ### Bekannter, nicht behobener Befund - Aufgaben lassen sich per Drag-and-Drop zwischen Zeitslots **nur auf dem Desktop** verschieben — `WeeklyView.tsx` nutzt dafür ausschließlich natives HTML5-Drag (`draggable`/ `onDragStart`/`onDrop`), das auf Touch-Geräten nicht feuert. Kein separater Touch-Mechanismus existiert; `react-dnd`/`react-dnd-html5-backend` sind installiert, aber nirgends importiert. `decideTaskDrop` kennt "Drag" gar nicht (nur Quelle/Ziel als Daten) und könnte von einem künftigen Touch-Mechanismus unverändert wiederverwendet werden — das Bauen dieses Mechanismus selbst ist ein eigenes Feature-Vorhaben, nicht Teil dieses Refactorings. Verifiziert: Typecheck, Lint (0 Fehler), 100 Unit-Tests (85 → 100, 15 neu), Produktions-Build — alle grün. Kein Playwright-E2E-Lauf für Drag-and-Drop (existiert im Repo bislang nicht, siehe `TODO-CODESCENE-FORTSETZUNG-2026-09-12.md`). ## [1.125.4] - 2026-09-13 ### Changed - `.gitignore`: `TODO.md` ausgeschlossen — persönliche Arbeitsliste, nicht Teil des Repos. ## [1.125.3] - 2026-09-12 ### Fixed - `SONAR_TOKEN`/`SONAR_HOST_URL` sind jetzt als GitHub-Secret/-Variable gesetzt (frisches Token vom Besitzer erhalten, gleichzeitig `~/.sonar-token` auf dem Spark wiederhergestellt — der nächtliche lokale Scan lief seit mindestens 09.09. fehl). Der Sonar-Schritt im Workflow authentifiziert jetzt erfolgreich, scheiterte im ersten echten Testlauf aber an einem neuen, unabhängigen Problem: der Standard-Node-Heap der JS/TS-Analyse-Bridge (~2,2 GB) reicht auf dem GitHub-Hosted-Runner für dieses Repo nicht — dieselbe Fehlerklasse wie der `next build`-OOM-Absturz von v1.119.3/v1.119.4. Behoben mit `-Dsonar.javascript.node.maxspace=4096`. ## [1.125.2] - 2026-09-12 ### Fixed - v1.125.1s `if: ${{ secrets.SONAR_TOKEN != '' }}` machte den Workflow bei GitHub selbst ungültig (0-Sekunden-Fehlschlag ohne Job-Log, "likely failed because of a workflow file issue") — live im Actions-Lauf verifiziert, nicht nur vermutet. Ersetzt durch reines `continue-on-error: true` auf dem Sonar-Schritt, ohne Bedingung. Erreicht dasselbe Ziel (fehlendes Secret reißt den Workflow nicht mit runter) ohne den ungültigen Ausdruck. ## [1.125.1] - 2026-09-12 ### Fixed - **`.github/workflows/sonarqube.yml` war seit dem 02.09. dauerhaft rot** — nicht mehr wegen Typecheck/Lint (die sind seit Block C1 grün), sondern weil `SONAR_TOKEN` als Repo-Secret nie gesetzt wurde. Der Sonar-Schritt läuft jetzt nur noch, wenn das Secret existiert, und ist zusätzlich `continue-on-error`, damit ein nicht erreichbarer selbst gehosteter SonarQube-Server nicht den ganzen Workflow mit runterreißt. Ergänzt: ein Unit-Test-Schritt (`npm run test:unit`), der bislang trotz des Workflow-Namens „Test and SonarQube" komplett fehlte. - **Der lokale nächtliche SonarQube-Scan auf dem Spark lief seit mindestens dem 09.09. jede Nacht fehl** (`ERROR: no readable token at ~/.sonar-token` — die Datei war schlicht weg), unbemerkt mangels Alarmierung. Kein Code-Fix hierfür möglich: braucht ein frisches Sonar-Token vom Besitzer (Login unter https://sq.martin-bierschenk.de), um sowohl `~/.sonar-token` auf dem Spark als auch das GitHub-Secret wiederherzustellen. ## [1.125.0] - 2026-09-12 ### Security - **Content-Security-Policy ergänzt, vorerst als `Content-Security-Policy-Report-Only`.** Blockiert nichts, meldet aber jeden Verstoß an den neuen Endpunkt `POST /api/csp-report` (loggt über `console.error`/PM2). Die Whitelist ist aus dem tatsächlichen Code abgeleitet: `fonts.googleapis.com`/`fonts.gstatic.com` für zur Laufzeit nachgeladene Schriftarten (`FontPicker.tsx`, `WeeklyView.tsx`), `'unsafe-inline'` für Next.js' App-Router-Hydration und den einen `dangerouslySetInnerHTML`-Block. Kein `