# Changelog All notable changes to this project are documented in this file. ## [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 `