typescript.ignoreBuildErrors steht jetzt auf false. Ein erfolgreicher Build ist damit wieder ein Beleg dafuer, dass der Code uebersetzbar ist. Die Ursache der 30-Minuten-Laufzeit war nicht die Groesse von WeeklyView.tsx, wie ich vermutet hatte, sondern das include-Muster **/* in tsconfig.json. Auf src/**/* eingegrenzt laeuft der volle Typecheck in 19 Sekunden. Die sieben gefundenen Fehler: - notion-calendar.ts rief notion.databases.query() auf. Die Methode gibt es in @notionhq/client v5 nicht mehr -- die Notion-Anbindung war zur Laufzeit schlicht kaputt und niemandem aufgefallen. Migriert auf dataSources.query(), aber mangels Notion-Zugang ungetestet. Gespeicherte Verbindungen enthalten alte database_ids und muessen neu eingerichtet werden. - WeeklyView.tsx importierte isAllDayEvent noch aus format statt date-utils -- mein eigener Fehler aus v1.118.0, der ohne scharfen Typecheck durchgerutscht war. - Export-Helfer lagen in einer route.ts, wo Next.js nur Route-Handler erlaubt; SettingsSidebar importierte sie von dort und zog einen Server-Handler in den Client-Graphen. Jetzt in src/lib/export-fields.ts. - push-notifications.ts: BufferSource-Cast fuer applicationServerKey. - web-push hat keine Typen; lokale Deklaration statt neuer Abhaengigkeit. Verifiziert: npm run build Exit 0 mit scharfem Typecheck, 63 Unit-Tests gruen. v1.118.1 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
340 lines
18 KiB
Markdown
340 lines
18 KiB
Markdown
# Changelog
|
|
|
|
All notable changes to this project are documented in this file.
|
|
|
|
## [1.118.1] - 2026-09-07
|
|
|
|
### Fixed
|
|
- **Der Build prüft wieder Typen.** `typescript.ignoreBuildErrors` steht auf `false`.
|
|
Damit ist ein erfolgreicher Build endlich wieder ein Beleg dafür, dass der Code
|
|
übersetzbar ist — bisher war er es nicht.
|
|
- **Notion-Anbindung war defekt.** Der Code rief `notion.databases.query()` auf; in
|
|
`@notionhq/client` v5 gibt es diese Methode nicht mehr, der Aufruf lief zur Laufzeit in
|
|
ein "is not a function". Umgestellt auf `dataSources.query()`, die Suche filtert jetzt
|
|
auf `data_source`. **Ungetestet** (kein Notion-Zugang), und gespeicherte Verbindungen
|
|
enthalten alte `database_id`s — betroffene Nutzer müssen Notion neu verbinden.
|
|
- `WeeklyView.tsx` importierte `isAllDayEvent` weiterhin aus `format`, obwohl die Funktion
|
|
in v1.118.0 nach `date-utils` gewandert war. Wäre zur Laufzeit gescheitert.
|
|
- Export-Helfer (`EXPORT_FIELDS`, `isoWeek`, `weekLabel`, `csvCell` …) liegen jetzt in
|
|
`src/lib/export-fields.ts`. Next.js erlaubt in einer `route.ts` nur Route-Handler als
|
|
Exporte; zudem importierte `SettingsSidebar` sie direkt aus der Route und zog damit
|
|
einen Server-Handler in den Client-Graphen.
|
|
- `push-notifications.ts`: `applicationServerKey` braucht seit TypeScript 5.7 einen Cast
|
|
auf `BufferSource`.
|
|
- Typdeklaration für `web-push` in `src/types/web-push.d.ts` ergänzt — als lokale Datei
|
|
statt als Abhängigkeit, weil `npm install` im Projektordner nicht läuft.
|
|
|
|
### Changed
|
|
- `tsconfig.json`: `include` von `**/*` auf `src/**/*` eingegrenzt. **Das war die Ursache
|
|
dafür, dass der Typecheck über 30 Minuten lief** — nicht die Größe von `WeeklyView.tsx`,
|
|
wie zuvor vermutet. Der vollständige Lauf dauert jetzt **19 Sekunden**.
|
|
|
|
## [1.118.0] - 2026-09-07
|
|
|
|
### Added
|
|
- **63 Unit-Tests** in `tests/unit/` für die ausgelagerten reinen Funktionen. Sie laufen in
|
|
rund 170 ms über Nodes eingebauten Test-Runner — ohne Browser, ohne Datenbank, ohne neue
|
|
Abhängigkeit. `npm test` führt sie aus, `npm run test:e2e` startet weiterhin Playwright.
|
|
Geprüft werden ISO-Kalenderwochen, Wochenstart-Berechnung, das Zeitraster, die
|
|
12/24-Stunden-Anzeige, der Round-Trip zwischen `formatDateToISO` und `parseCalendarDate`
|
|
sowie Farbinvertierung und Spaltenbegrenzung.
|
|
|
|
### Fixed
|
|
- `isAllDayEvent` rief `parseCalendarDate` auf, ohne es zu importieren — beim Auslagern aus
|
|
`WeeklyView.tsx` in v1.117.7 übersehen. Der Build meldete nichts, weil
|
|
`typescript.ignoreBuildErrors` noch aktiv ist; zur Laufzeit hätte der erste ganztägige
|
|
Termin mit Uhrzeit einen `ReferenceError` ausgelöst. Die Funktion liegt jetzt in
|
|
`date-utils.ts`, wo sie thematisch hingehört.
|
|
- `resolveViewDays` nutzte `clampViewDays` ohne Import — derselbe Fehler beim selben Schnitt.
|
|
`clampViewDays` und `MAX_VIEW_DAYS` sind nach `device-settings.ts` gewandert; `DaysSelector`
|
|
re-exportiert sie, bestehende Importe bleiben gültig.
|
|
|
|
Beide Fehler sind genau die Sorte, die `typescript.ignoreBuildErrors` verdeckt — und beide
|
|
wären von den neuen Tests sofort gefunden worden.
|
|
|
|
## [1.117.7] - 2026-09-07
|
|
|
|
### Changed
|
|
- Geräteabhängige Einstellungen nach `src/lib/weekly/device-settings.ts` (Cookie-Helfer und
|
|
die vier Schlüssellisten, die bewusst nur im Cookie und nicht in der Datenbank landen).
|
|
- Darstellungs-Helfer nach `src/lib/weekly/format.ts` (`stripHtml`, `invertColor`,
|
|
`isAllDayEvent`, `getSomedaySlotCount`).
|
|
- `WeeklyView.tsx`: 11.655 → 11.556 Zeilen. Mit `npm run build` verifiziert (Exit 0).
|
|
|
|
Damit sind die reinen Funktionen ohne Komponenten-State heraus — insgesamt 11.906 → 11.556
|
|
Zeilen (rund 3 %). Der Rest ist die Komponente selbst und braucht echtes Props-Design statt
|
|
Verschieben.
|
|
|
|
## [1.117.6] - 2026-09-07
|
|
|
|
### Changed
|
|
- Datums-, Wochen- und Zeitraster-Helfer nach `src/lib/weekly/date-utils.ts` verschoben
|
|
(13 reine Funktionen ohne Komponenten-State: `getStartOfWeek`, `getDayName`,
|
|
`getTimeSlots`, `formatHour`, `getWeekNumber`, `formatCustomHeader` und weitere).
|
|
`WeeklyView.tsx`: 11.830 → 11.655 Zeilen. Mit `npm run build` verifiziert (Exit 0).
|
|
|
|
### Notes
|
|
- `getWeekNumber` existiert im Projekt **dreimal** — hier, in `WeekPrintModal.tsx` und in
|
|
`app/api/user/export-week-view/route.ts`. Die Duplikate zu ersetzen steht in TODO.md;
|
|
vorher müssen die drei Implementierungen auf Gleichheit geprüft werden.
|
|
|
|
## [1.117.5] - 2026-09-07
|
|
|
|
### Changed
|
|
- Die gemeinsamen Datentypen der Wochenansicht liegen jetzt in `src/lib/weekly/types.ts`
|
|
(`Task`, `CalendarEvent`, `SomedayList`, `ViewStyle`, `KanbanStage`, `CellDuration`,
|
|
`RecurringTaskException`). `SettingsSidebar` und `GridTaskBlock` importierten sie bisher
|
|
aus `WeeklyView.tsx` und zogen sich damit die gesamte 11.900-Zeilen-Komponente in ihren
|
|
Abhängigkeitsgraphen. `WeeklyView.tsx` re-exportiert die Typen weiterhin, bestehende
|
|
Importe funktionieren also unverändert.
|
|
- Erster Schritt der Aufteilung von `WeeklyView.tsx`: 11.906 → 11.830 Zeilen.
|
|
Mit `npm run build` verifiziert (Exit 0, 36 Seiten, `/tasks` unverändert bei 265 kB).
|
|
|
|
## [1.117.4] - 2026-09-07
|
|
|
|
### Fixed
|
|
- Der Build meldet wieder ESLint-Fehler: `eslint.ignoreDuringBuilds` steht auf `false`.
|
|
Es waren nur **zwei** echte Errors im gesamten Projekt (`let json` statt `const json` in
|
|
`SettingsSidebar.tsx`), beide behoben. `next lint` endet jetzt mit Exit 0.
|
|
Die 695 Warnungen — 470-mal `no-explicit-any`, 209 ungenutzte Variablen, 11 unvollständige
|
|
Hook-Abhängigkeiten — blockieren den Build nicht und werden fortlaufend abgebaut.
|
|
|
|
## [1.117.3] - 2026-09-06
|
|
|
|
### Security
|
|
- `.env.production.save` und `.env.local` aus dem Arbeitsverzeichnis gelöscht — mit `shred`
|
|
überschrieben, damit die Werte nicht aus freiem Speicher rekonstruierbar bleiben. Beide
|
|
waren identische Kopien derselben Zugangsdaten.
|
|
- Klartext-Werte in `deployment-notes.md` und `INFRASTRUCTURE_REQUIREMENTS.md` durch
|
|
Platzhalter ersetzt (je drei Vorkommen: DB-Passwort, `NEXTAUTH_SECRET`, SMTP-Passwort).
|
|
Die Dateien bleiben als Dokumentation lesbar.
|
|
- Damit liegt außerhalb der Git-Historie kein Zugangsdatum mehr im Projekt.
|
|
|
|
## [1.117.2] - 2026-09-06
|
|
|
|
### Security
|
|
- Weitere Dateien mit echten Zugangsdaten aus dem Git-Index genommen (lokal bleiben sie
|
|
erhalten): `deployment-notes.md` und `INFRASTRUCTURE_REQUIREMENTS.md` — letztere führt das
|
|
Datenbank-Passwort sogar unverschleiert als `**Password**: …` auf. Ebenfalls entfernt:
|
|
`.env.production.save`, der ursprüngliche Fund.
|
|
- Passwort aus `tests/debug/db-connection-test.spec.ts` entfernt; dort stand eine vollständige
|
|
Connection-URL samt echter IP.
|
|
- `.gitignore` greift jetzt auf `.env*` statt auf eine Liste fester Namen. Die alte Regel
|
|
listete `.env.production`, weshalb `.env.production.save` durchs Raster fiel.
|
|
|
|
### Changed
|
|
- `TODO.md`: Die Rotation des Datenbank-Passworts ist in einen neuen Block F verschoben —
|
|
bewusst zurückgestellt. Die Datenbank hört auf einer privaten LAN-Adresse, und bei
|
|
selbst gehostetem Supabase steckt dasselbe Passwort an mehreren Stellen, was einen
|
|
halben Wechsel gefährlich macht. Enthält jetzt einen Prüfbefehl, mit dem sich ohne
|
|
Klartext-Ausgabe feststellen lässt, ob eines der geleakten Passwörter noch aktiv ist.
|
|
|
|
## [1.117.1] - 2026-09-06
|
|
|
|
### Fixed
|
|
- `docs/secret-rotation.md`, Schritt 2: Die Anleitung ging von *Supabase Cloud* mit
|
|
Dashboard und "Reset database password"-Knopf aus. Tatsächlich läuft Supabase
|
|
**selbst gehostet per Docker auf einem eigenen LXC** (siehe `scripts/supabase-setup.sh`) —
|
|
es gibt kein Cloud-Dashboard. Korrigiert samt Ports (6543 Pooler, 5432 direkt,
|
|
8000 API, 8001 Studio) und dem tatsächlichen Weg über `POSTGRES_PASSWORD` plus
|
|
`ALTER USER`, inklusive Backup-Schritt.
|
|
|
|
## [1.117.0] - 2026-09-06
|
|
|
|
### Security
|
|
- Rate-Limiting für alle Auth-Endpunkte: `signup` (5/15 Min), `resend-verification`
|
|
(3/15 Min), `verify-email` (10/15 Min) und `reset-password` (5/15 Min), je Client-IP.
|
|
Bisher waren sie unbegrenzt aufrufbar — beliebig viele Mails über den eigenen
|
|
SMTP-Zugang, beliebig viele Rateversuche auf Verifizierungscodes.
|
|
- Passwort-Reset-Token wird nur noch als SHA-256-Hash gespeichert. Bisher lag er im
|
|
Klartext in der Datenbank: Lesezugriff auf die DB genügte, um fremde Konten zu übernehmen.
|
|
- Tote Mock-Login-Route `src/app/api/auth/login/route.ts` entfernt. Sie verglich gegen ein
|
|
hartcodiertes Fake-Passwort, erzeugte ein bedeutungsloses `mock-jwt-token-…` und war
|
|
über die Middleware-Ausnahme für `/api/auth/*` ohne Anmeldung erreichbar. Kein
|
|
Login-Bypass, aber sie protokollierte jede probierte E-Mail-Adresse.
|
|
- Passwort-Reset nutzt jetzt bcrypt-Kosten 12 statt 10 — gleicher Wert wie beim Signup.
|
|
|
|
### Fixed
|
|
- `npm test` lief ins Leere: Das Skript rief `jest` auf, obwohl es weder eine Jest-Config
|
|
noch einen einzigen Jest-Test gibt. Zeigt jetzt auf Playwright; `jest`, `ts-jest` und
|
|
`@types/jest` sind entfernt (letzteres kollidiert mit den Playwright-Globals).
|
|
- Falscher `sonar.projectKey` im GitHub-Workflow — er hätte in ein zweites, leeres
|
|
SonarQube-Projekt geschrieben statt in das bestehende.
|
|
|
|
### Changed
|
|
- Die zwölf Wegwerf-Skripte aus der Fehlersuche (`login-debug`, `css-debug-test`, …) liegen
|
|
jetzt unter `tests/debug/` und sind per `testIgnore` aus dem normalen Testlauf genommen.
|
|
Aktiv bleiben die drei echten Testdateien. Erreichbar über `npm run test:debug`.
|
|
|
|
### Added
|
|
- `TODO.md`: abhakbare Liste aus dem Repository-Audit.
|
|
- `docs/secret-rotation.md`: Anleitung zum Austausch der Zugangsdaten, ohne dass ein Wert
|
|
auf dem Bildschirm erscheint.
|
|
- `scripts/quality-check.sh`: bündelt `npm audit`, Typecheck, Lint und den SonarQube-Scan
|
|
für den nächtlichen Lauf. `npm audit` fehlte bisher komplett.
|
|
|
|
## [1.116.4] - 2026-09-06
|
|
|
|
### Fixed
|
|
- Improved calendar event text contrast while retaining the calendar-colored background.
|
|
|
|
## [1.116.3] - 2026-09-05
|
|
|
|
### Added
|
|
- Calendar events can now be reassigned to another editable calendar from the event editor.
|
|
- Moving an event updates the source and target calendar caches.
|
|
|
|
### Changed
|
|
- Calendar event backgrounds now use the calendar color with a lighter, readable contrast.
|
|
- Google event-specific colors no longer override the selected calendar's color.
|
|
|
|
## [1.116.2] - 2026-09-05
|
|
|
|
### Fixed
|
|
- The remove action now applies to saved local location suggestions only.
|
|
OpenStreetMap search results remain available, while removed saved locations
|
|
are deleted from the user's stored location list.
|
|
|
|
## [1.116.1] - 2026-09-05
|
|
|
|
### Fixed
|
|
- Display preferences such as the number of visible days now remain device-specific.
|
|
Automatic profile saving no longer sends browser-only settings back to the shared account.
|
|
- An explicitly selected day count now survives mobile reloads and orientation changes.
|
|
- Cancelled or superseded location autocomplete requests no longer update the event form.
|
|
- Photon autocomplete requests now have a five-second timeout and input length limit.
|
|
|
|
## [1.116.0] - 2026-09-04
|
|
|
|
### Added
|
|
- Added a two-day reminder preset for calendar events.
|
|
- Added optional address and business autocomplete using Photon/OpenStreetMap,
|
|
with debounced server-side search and OpenStreetMap attribution.
|
|
- Users can keep their original location text or explicitly select a suggested result.
|
|
|
|
## [1.115.3] - 2026-09-03
|
|
|
|
### Fixed
|
|
- Drag & drop in views wider than 7 days: the drop target was keyed by weekday
|
|
(`date.getDay()`), which is only unique inside a 7-day window. In a 21-day view every
|
|
column sharing the weekday of the hovered one lit up as a drop target — three mirrored
|
|
highlights, one per Tuesday. Now keyed by the local date.
|
|
- Same bug, worse half: `handleDrop` resolved the target date with
|
|
`visibleDays.find(d => d.getDay() === dayOfWeek)`, so dropping a task on the second or
|
|
third Tuesday of a wide view silently scheduled it on the *first* Tuesday. The drop now
|
|
uses the column's own date. Tasks dragged in a >7-day view before this fix may sit on the
|
|
wrong date.
|
|
- The inline "click an empty slot to add a task" input had the same weekday key, so clicking
|
|
one slot opened an input in every column with that weekday.
|
|
|
|
## [1.115.2] - 2026-09-03
|
|
|
|
### Changed
|
|
- `scripts/update-app.sh` is now the single update path, used both for a manual deploy and
|
|
for the boot run; `my-weekly-todo-update.service` points at it. There were two
|
|
near-identical scripts and they drifted — the `npm ci` fix from 1.114.1 only ever landed
|
|
in update-app.sh, so the boot path kept running `npm install`. `scripts/boot-update.sh`
|
|
is now a shim that calls it, kept only so a not-yet-recopied unit file still works.
|
|
- The update log moved from `/var/log/app-boot-update.log` to
|
|
`/var/log/my-weekly-todo-update.log`.
|
|
|
|
### Added
|
|
- `update-app.sh` skips the rebuild when `HEAD` already matches `origin/main` and
|
|
`.next/standalone/server.js` exists, so a reboot no longer costs a full rebuild. Pass
|
|
`--force` to rebuild anyway.
|
|
- `update-app.sh` takes a `flock` single-instance lock, so a boot run and a manual run can
|
|
no longer install into the same tree at once — which is how node_modules ended up in a
|
|
state npm could not clean up.
|
|
- `update-app.sh` runs `prisma migrate deploy` and `prisma generate` (previously only the
|
|
boot script did), and copies `.env` into the standalone output.
|
|
|
|
### Fixed
|
|
- `update-app.sh` no longer fails at boot trying to restart a PM2 process that does not
|
|
exist yet. It restarts only when the PM2 daemon is actually running, and otherwise leaves
|
|
the start to `pm2-root.service`, which is ordered after this unit. It deliberately does
|
|
not probe with `pm2 describe`, since any pm2 command spawns a daemon that would race the
|
|
real service.
|
|
|
|
## [1.115.1] - 2026-09-03
|
|
|
|
### Fixed
|
|
- `scripts/boot-update.sh` (the "update on reboot" unit): every command was piped into `tee`,
|
|
so `set -e` only ever saw tee's exit status. A failed `npm install` or `npm run build` did
|
|
not stop the script and did not fail the systemd unit — it logged "Boot update finished"
|
|
and left a half-built tree. Now uses `set -euo pipefail`, logs through a single `exec`
|
|
redirect, and traps ERR.
|
|
- `scripts/boot-update.sh`: switched from `npm install` to `npm ci`. Same fix update-app.sh
|
|
got in 1.114.1 — `npm install` rewrites package-lock.json, leaving the tree dirty so the
|
|
*next* `git pull` aborts.
|
|
- `scripts/boot-update.sh`: body wrapped in a function so bash parses it in one go. The
|
|
script lives inside the checkout it pulls, so `git pull` rewriting it mid-run made bash
|
|
resume at a stale file offset.
|
|
- `scripts/boot-update.sh`: set `GIT_TERMINAL_PROMPT=0` so a git credential prompt fails
|
|
fast instead of hanging the unit at boot, where there is no tty.
|
|
- `scripts/my-weekly-todo-update.service`: raised `TimeoutStartSec` from 300 to 1800.
|
|
`npm ci` + `prisma generate` + `next build` takes far longer than 5 minutes in the
|
|
container; systemd SIGTERMed the oneshot unit mid-install, which left a `node_modules`
|
|
tree npm could no longer remove (`ENOTEMPTY: rmdir node_modules/date-fns/isEqual`).
|
|
- `package-lock.json`: version resynced with `package.json` (missed in the 1.115.0 commit).
|
|
|
|
## [1.115.0] - 2026-09-03
|
|
|
|
### Added
|
|
- Day columns: a "Custom" option next to the 1/2/3/5/7 presets, where any number of days from
|
|
1 to 31 can be typed (e.g. 14, 21, 28). The chosen value shows up as its own chip beside the
|
|
presets and is available in every place the day count can be set — sidebar, both settings
|
|
flyouts, the desktop toolbar and the header overflow menu.
|
|
|
|
### Fixed
|
|
- Day grid and all-day grid only had CSS for `cols-1/2/3/5/7`, so any other day count silently
|
|
fell back to a 5-column layout. Both grids now derive `grid-template-columns` from the actual
|
|
day count.
|
|
|
|
## [1.114.2] - 2026-09-01
|
|
|
|
### Fixed
|
|
- Deploy script: copy `public/` and `.next/static/` into `.next/standalone/` after the build.
|
|
`next.config.js` sets `output: 'standalone'`, and Next.js does not copy those itself. Without
|
|
the copy every deploy left the old chunk hashes in the standalone tree, so the browser's
|
|
requests for the new chunks 404'd, React never hydrated, and the app hung on "Loading
|
|
session..." — while the API kept returning 200, which made it look like an auth problem.
|
|
|
|
## [1.114.1] - 2026-09-01
|
|
|
|
### Added
|
|
- `scripts/update-app.sh`: the production deploy script, now version-controlled instead of
|
|
living only on the server. Hardened with `set -euo pipefail` (a failed `git pull` used to
|
|
still trigger a rebuild and PM2 restart on unchanged code) and switched from `npm install`
|
|
to `npm ci` (npm install rewrote package-lock.json, leaving the tree dirty so the next
|
|
pull aborted).
|
|
|
|
## [1.114.0] - 2026-09-01
|
|
|
|
### Added
|
|
- Focus Mode: "SKIP" button to move on to the next task of the day without completing the
|
|
current one. Skipped tasks are remembered until Focus Mode is closed, and the timer
|
|
resets for each new task. The button is disabled when no other task is left for today.
|
|
|
|
### Changed
|
|
- Styling settings: removed the standalone "Element Colors" and "Weekend Colors" sections —
|
|
those controls now live only in the CSS Variables panel (added there in 1.113.1).
|
|
- Styling settings: larger, borderless color swatches and bigger labels in the CSS Variables
|
|
panel.
|
|
|
|
## [1.113.1] - 2026-07-08
|
|
|
|
### Changed
|
|
- CSS Variables panel: added the existing "Today Highlight", "Past Days", "Saturday" and
|
|
"Sunday" color controls as their own groups (bound to the same profile fields as the
|
|
standalone Element/Weekend Colors sections, so both stay in sync).
|
|
- CSS Variables panel: every row now shows the color swatch before its label.
|
|
|
|
## [1.113.0] - 2026-07-08
|
|
|
|
### Added
|
|
- Styling settings: "CSS Variables" panel with a color picker and description for every
|
|
customizable color token in `globals.css` (base colors, settings sidebar, design token
|
|
aliases, event colors, all-day chips).
|
|
- Styling settings: "Custom CSS" textarea to inject a personal stylesheet that loads after
|
|
the app's default styles and can override any rule.
|