Erklärt nicht nur, wo man zieht, sondern warum der Kalender immer gewinnt, warum sich das nicht aufschaukelt und was das Warnzeichen im Block bedeutet. Dazu der ehrliche Abschnitt "Was noch nicht geht": die Dauer lässt sich nicht am Balken ziehen, und ein Zeitblock landet immer im ersten verbundenen Kalender. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
6.8 KiB
6.8 KiB
Änderungen
Alle nennenswerten Änderungen an diesem Projekt stehen hier. Das Format folgt Keep a Changelog, die Versionierung Semantic Versioning.
[Unveröffentlicht]
Hinzugefügt
- Wochenansicht mit Ziehen und Ablegen: Aufgaben aus der linken Spalte in ein Zeitfenster ziehen legt einen Zeitblock an und schreibt ihn in den Kalender. Die Dauer kommt aus dem geschätzten Aufwand der Aufgabe.
- Zeitblöcke verschieben und ausplanen; der Kalendertermin zieht mit.
- Rückweg: Wird ein Zeitblock im Kalender verschoben, übernimmt der Planer das beim nächsten Abgleich. Wird er dort gelöscht, verschwindet auch der Zeitblock — die Aufgabe bleibt und fällt zurück auf offen.
- Kapazität und Belegung je Wochentag über jeder Spalte; überbuchte Tage werden rot, sperren aber nichts.
- Eine eingeplante Aufgabe wechselt selbsttätig von Offen auf Geplant und wieder zurück, wenn nichts mehr für sie geplant ist.
- Handbuchseite zur Wochenplanung.
Sicherheit
- Schleifenschutz über
hash = sha256(startISO|endeISO): Der Planer schreibt nur bei eigener Änderung und übernimmt aus dem Kalender nur, wenn der Fingerabdruck abweicht. Ohne das würden App und Kalender einander endlos hinterherschreiben. - Jeder Schreibzugriff auf einen bestehenden Termin geht mit
If-Matchheraus. Bei HTTP 412 gewinnt der Kalender: der Planer schreibt nicht, verwirft seinen Fingerabdruck und überlässt dem nächsten Abgleich, den fremden Stand zu holen. - Zeitblöcke gehören dem Benutzer über sein Kalenderkonto; die Kennung geht in jede where-Bedingung, nicht in einen nachträglichen Vergleich.
[0.3.0] – 2026-09-10
Hinzugefügt
- Kalenderkonten für Microsoft 365 (Graph) und Google verbinden, umbenennen,
von Hand abgleichen und trennen. Google gibt es nur in der Instanz
daheim; infirmaliefert die Route 404. - Termine werden örtlich gespiegelt: 7 Tage zurück bis 90 Tage voraus. Gelesen werden nur Beginn, Ende, Betreff, ganztägig und "zeigt an als" — keine Teilnehmer, Beschreibungen, Anhänge oder Orte.
- Die Startseite zeigt je Bereich, wie voll der heutige Tag ist: Termine aus allen verbundenen Kalendern gegen die Tageskapazität.
- Hintergrundjobs: alle 15 Minuten abgleichen, nachts alte Termine und abgelaufene WebAuthn-Herausforderungen entfernen.
- Handbuchseite zu den Kalenderkonten, Einrichtungsanleitung für Entra ID und die Google Cloud Console in der README.
Sicherheit
- Zugangs- und Aktualisierungstoken liegen verschlüsselt in der Datenbank (AES-256-GCM, Schlüssel aus AUTH_SECRET abgeleitet). Wer eine Sicherung in die Hände bekommt, kann damit ohne AUTH_SECRET nichts anfangen.
- Der Zustandswert im OAuth-Ablauf ist signiert und trägt die Benutzerkennung; ohne das ließe sich ein fremdes Kalenderkonto an ein beliebiges Konto hängen. Er verfällt nach 30 Minuten.
- Fehlermeldungen nennen nie den Antwortkörper des Token-Endpunkts — der enthält das Client-Secret oft im Echo.
- Protokolliert werden beim Abgleich nur Zahlen, nie Kontonamen oder Termininhalte.
[0.2.0] – 2026-09-10
Hinzugefügt
- Aufgaben mit Typ, Status, Priorität, Aufwand, Fälligkeit und Herkunft; Projekte als Klammer darum.
- Schnellerfassung mit einem einzigen Feld auf der Startseite und in der Inbox.
- Inbox: alles ohne Bereich sammelt sich dort und wird später einsortiert. Die Zahl im Menü zeigt, wie viel noch liegt.
- Aufgabenliste mit Filtern nach Suche, Bereich, Status, Art und Projekt. Die Filter stehen in der Adresse und lassen sich als Lesezeichen ablegen.
- Ideen als eigene Ansicht, ohne Termin und ohne Aufwand; per Klick wird daraus eine Aufgabe.
- Projekte mit Arbeitspaketen, Meilensteinen und Fortschritt.
- Die Startseite zeigt, was überfällig, heute oder morgen fällig ist.
- Handbuchseiten zu Aufgaben, Ideen und Projekten.
Geändert
- Die Startseite zählt nicht mehr nur Bereiche auf, sondern stellt voran, was jetzt dran ist.
Sicherheit
- Statuswechsel folgen festen Übergängen: Abgeschlossenes wird erst wieder geöffnet. Ein abweichender Wert im Formular führt zu einer Meldung, nicht zu einem stillen Zustandssprung.
- Angegebene Bereiche und Projekte werden vor dem Speichern geprüft; ein erfundener Verweis gibt eine Meldung statt eines Datenbankfehlers.
[0.1.0] – 2026-09-10
Hinzugefügt
- Projektgerüst mit Next 16 (App Router,
output: "standalone"), React 19, TypeScript strict, Tailwind 4 und shadcn-Primitiven. npm run pruefenbündelt Prettier, ESLint,tsc --noEmit, Vitest und ShellCheck. ShellCheck läuft über das Docker-Abbild, wenn es lokal fehlt.- Datenmodell für Benutzer mit Rolle, OIDC-Konten, Passkeys, Bereiche und Audit-Einträge; PostgreSQL 16 über Prisma 7 mit pg-Treiberadapter.
- Anmeldung über einen generischen OIDC-Anbieter, über Passkeys (SimpleWebAuthn) und wahlweise über E-Mail und Passwort.
- Rollen
BENUTZERundADMIN. Jede schreibende Aktion prüft die Rolle serverseitig in der Seite und noch einmal in der Server Action. - Audit-Protokoll für jede schreibende Aktion, mit Protokollseite für die Verwaltung. Details werden vor dem Speichern gesäubert.
- Instanzsteuerung über
INSTANZ=firma|daheim. Was eine Instanz nicht darf, liefert dort 404 und lädt seine Konfiguration gar nicht erst. - Bereiche mit Farbe, Arbeitsfenster und Tageskapazität je Wochentag.
- Zeitrechnung durchgehend in Europe/Berlin, mit Tagesgrenzen, Wochenbeginn am Montag und deutschen Anzeigeformaten.
/api/healthmit Status, Version, Instanz und Erreichbarkeit der Datenbank.- Hell und Dunkel, Navigation mit Rollenfilter, Oberfläche auf Deutsch.
- Dockerfile in drei Stufen und Compose-Stapel mit eigenem Migrationsdienst.
backup.sh(pg_dump im Custom-Format,.envund Uploads),update.sh(mit Rückrollpfad),scripts/release.shundscripts/zeit.sh.- Tests: Unit mit Vitest, Integrationstest und Migrationstest gegen eine echte Datenbank, E2E-Rauchtest mit Playwright.
npm run screenshotsnimmt die Handbuchbilder in einer Wegwerf-Instanz mit ausschließlich erfundenen Daten auf.- README, Schnellstart, Handbuch, ROADMAP und DEVLOG.
Sicherheit
- Anmeldung, Passwort und Passkey antworten bei Fehlschlag immer gleich, damit sich nicht abfragen lässt, wer ein Konto hat.
- Sitzungen als JWT, aber Rolle und Sperrstatus werden bei jeder Anfrage frisch aus der Datenbank gelesen — eine Sperre wirkt sofort.
- Die WebAuthn-Herausforderung wird nach einem Versuch verworfen, gleich ob er geglückt ist.
- Der Demo-Seed verweigert den Dienst ohne
DEMO_MODUS=true. allowDangerousEmailAccountLinkingist bewusst aktiv: je Instanz gibt es genau einen vertrauenswürdigen OIDC-Anbieter, der die Adresse selbst prüft.