From 475b1d5c08e82518e9cab40c41505ebd217b49ae Mon Sep 17 00:00:00 2001 From: Florian Wilde Date: Sat, 12 Sep 2026 04:51:38 +0200 Subject: [PATCH] docs: Handbuchseite, README und Fahrplan fuer M6 Der Wartungsplaner steht als offener Punkt drin, nicht als Haken. Co-Authored-By: Claude Opus 5 --- CHANGELOG.md | 41 +++++++++ README.md | 49 ++++++++++- ROADMAP.md | 25 ++++-- docs/handbuch/README.md | 9 +- docs/handbuch/integrationen.md | 151 +++++++++++++++++++++++++++++++++ 5 files changed, 263 insertions(+), 12 deletions(-) create mode 100644 docs/handbuch/integrationen.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 73f382a..a4b325d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,47 @@ die Versionierung [Semantic Versioning](https://semver.org/lang/de/). ## [Unveröffentlicht] +### Hinzugefügt + +- **Zammad** (nur `firma`): Tickets, auf die der Suchausdruck passt, werden zu + Aufgaben — mit Verweis ins Ticket. Wird ein Ticket dort geschlossen, hakt + der Planer die Aufgabe ab. +- **Telegram** (nur `daheim`): Eine Nachricht an den Bot wird zur Aufgabe. + Meldungen gehen denselben Weg zurück, mit einem Knopf zum Abhaken. Ein Chat + meldet sich über einen Einmalcode an, der zehn Minuten gilt. +- **Telegram als dritter Meldeweg** neben Push und E-Mail. +- **Spiegel** zwischen den Instanzen: `firma` schickt Belegungen ohne Titel + und die einzeln dafür markierten Aufgaben, `daheim` empfängt. Gespiegelte + Belegung erscheint in der Wochenansicht als „Dienstlich belegt" und zählt + gegen die Tageskapazität. +- Seite **Integrationen**: je Integration Zustand, letzter Erfolg, letzter + Fehler und ein Knopf, der einen Lauf sofort anstößt. +- Handbuchseite zu den Integrationen. + +### Geändert + +- Was aus einem Fund wird, entscheidet für alle Integrationen dieselbe + Stelle. Geführt werden nur Titel, Notiz, Verweis und Fälligkeit — Bereich, + Projekt, Priorität und geschätzter Aufwand gehören der Planung und werden + nie von außen überschrieben. +- Eine klemmende Integration meldet sich wie ein klemmender Kalender: erst + nach dem dritten Fehlversuch in Folge. +- Die Demo-Instanz für die Bilder spricht nicht mehr nach außen. + +### Sicherheit + +- Wer dem Telegram-Bot schreibt, ohne verbunden zu sein, bekommt **keine + Antwort** — auch keine Fehlermeldung. Sonst ließe sich herausfinden, dass + es diesen Planer gibt. +- Jede Sendung des Spiegels trägt eine Signatur über den Rumpf und ist nach + fünf Minuten wertlos. Der Empfänger antwortet auf jeden Fehlschlag gleich: + falsches Geheimnis, verstellte Uhr und Unsinn im Inhalt sind von außen + nicht zu unterscheiden. +- Der Signaturvergleich läuft in gleichbleibender Zeit. +- Aufgaben verlassen die Instanz nur mit ausdrücklicher Freigabe je Aufgabe. + Ein Schalter für einen ganzen Bereich würde zu leicht Kundennamen nach + Hause schicken. + ## [0.5.0] – 2026-09-11 ### Hinzugefügt diff --git a/README.md b/README.md index 8fe37b7..8056d0e 100644 --- a/README.md +++ b/README.md @@ -33,8 +33,12 @@ wird. Bereich, wie voll der heutige Tag schon ist - **Wochenplanung** per Ziehen und Ablegen: Aufgaben werden zu echten Kalenderterminen, Verschiebungen im Kalender kommen zurück -- **Benachrichtigungen** per Web-Push und E-Mail: Tagesüberblick, fällige - Aufgaben, Vorlauf vor einem Zeitblock — mit Ruhezeiten und ab Werk still +- **Benachrichtigungen** per Web-Push, E-Mail und Telegram: Tagesüberblick, + fällige Aufgaben, Vorlauf vor einem Zeitblock — mit Ruhezeiten und ab Werk + still +- **Integrationen**: Zammad-Tickets werden zu Aufgaben, Telegram erfasst und + hakt ab, und der Spiegel bringt dienstliche Belegung nach Hause — ohne + Titel - Anmeldung über einen OIDC-Anbieter, über Passkeys oder mit E-Mail und Passwort — je Instanz einzeln zuschaltbar - Rollen `Benutzer` und `Verwaltung`; jede schreibende Aktion wird @@ -45,7 +49,7 @@ wird. ### Geplant -Integrationen, Schnellerfassung vom Handy und ein MCP-Server. +Schnellerfassung vom Handy, eine öffentliche API und ein MCP-Server. Siehe [ROADMAP.md](ROADMAP.md). ## Bildergalerie @@ -63,6 +67,7 @@ Siehe [ROADMAP.md](ROADMAP.md). | Bereiche | ![Bereiche, hell](docs/bilder/bereiche-hell-schreibtisch.png) | ![Bereiche, dunkel](docs/bilder/bereiche-dunkel-schreibtisch.png) | | Einstellungen | ![Einstellungen, hell](docs/bilder/einstellungen-hell-schreibtisch.png) | ![Einstellungen, dunkel](docs/bilder/einstellungen-dunkel-schreibtisch.png) | | Meldungen | ![Benachrichtigungen, hell](docs/bilder/benachrichtigungen-hell-schreibtisch.png) | ![Benachrichtigungen, dunkel](docs/bilder/benachrichtigungen-dunkel-schreibtisch.png) | +| Integrationen | ![Integrationen, hell](docs/bilder/integrationen-hell-schreibtisch.png) | ![Integrationen, dunkel](docs/bilder/integrationen-dunkel-schreibtisch.png) | | Protokoll | ![Protokoll, hell](docs/bilder/protokoll-hell-schreibtisch.png) | ![Protokoll, dunkel](docs/bilder/protokoll-dunkel-schreibtisch.png) | Alle Bilder entstehen mit `npm run screenshots` in einer Wegwerf-Instanz mit @@ -171,6 +176,44 @@ Klartextadresse nicht. Was der Planer wann meldet, steht im [Handbuch](docs/handbuch/benachrichtigungen.md). +### Integrationen + +Welche Integration eine Instanz überhaupt darf, entscheidet `INSTANZ` — nicht +die Konfiguration. Ein Zammad-Token in der Instanz `daheim` bleibt wirkungslos. + +| Variable | Standard | Bedeutung | +| ------------------- | ------------------- | ---------------------------------------------------------------- | +| `ZAMMAD_URL` | _(leer)_ | Adresse der Zammad-Instanz, nur `firma` | +| `ZAMMAD_TOKEN` | _(leer)_ | Token aus **Profil → Token-Zugriff** | +| `ZAMMAD_ABFRAGE` | `owner_id:me AND …` | Suchausdruck; was darauf passt, wird zur Aufgabe | +| `TELEGRAM_TOKEN` | _(leer)_ | Bot-Token von [@BotFather](https://t.me/BotFather), nur `daheim` | +| `SPIEGEL_GEHEIMNIS` | _(leer)_ | Gemeinsames Geheimnis beider Instanzen | +| `SPIEGEL_ZIEL` | _(leer)_ | Adresse der empfangenden Instanz; nur auf der sendenden Seite | + +**Zammad** liest nur. Ein Ticket schließt man im Ticketsystem — sonst weiß die +Kollegin nicht, warum es plötzlich zu ist. Umgekehrt schließt der Planer eine +Aufgabe, sobald Zammad das Ticket als erledigt meldet. + +**Telegram** braucht keinen Webhook und damit keine von außen erreichbare +Adresse. Welche Chats mitreden dürfen, wird in der Anwendung unter +**Integrationen** gekoppelt: Knopf drücken, Code an den Bot schicken, fertig. +Nachrichten aus unbekannten Chats werden verworfen, ohne zu antworten. + +**Der Spiegel** geht in eine Richtung: `firma` sendet, `daheim` empfängt. +Hinüber gehen Belegungen **ohne Titel** — daheim ist zu sehen, _dass_ die Zeit +weg ist, nicht woran gearbeitet wird — und jene Aufgaben, die einzeln zum +Spiegeln markiert wurden. Jede Sendung ist mit dem gemeinsamen Geheimnis +signiert und älter als fünf Minuten wertlos. + +Das Geheimnis erzeugst du wie das Sitzungsgeheimnis: + +```bash +openssl rand -base64 32 +``` + +Was der Alltag damit anfängt, steht im +[Handbuch](docs/handbuch/integrationen.md). + ### Einrichtung und Sonstiges | Variable | Standard | Bedeutung | diff --git a/ROADMAP.md b/ROADMAP.md index 05b5db6..4b4f711 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -10,7 +10,7 @@ grünen Prüfungen, aktueller Dokumentation und einem Eintrag im DEVLOG. | [M3](#m3--kalender-lesen) | Kalender lesen | erledigt | | [M4](#m4--wochenplanung-und-zeitblöcke) | Wochenplanung und Zeitblöcke | erledigt | | [M5](#m5--benachrichtigungen) | Benachrichtigungen | erledigt | -| [M6](#m6--integrationen) | Integrationen | geplant | +| [M6](#m6--integrationen) | Integrationen | erledigt | | [M7](#m7--schnellerfassung-und-api) | Schnellerfassung und API | geplant | | [M8](#m8--mcp) | MCP | geplant | @@ -112,10 +112,25 @@ Erinnerung an einen Zeitblock, der längst begonnen hat, hilft niemandem. ## M6 – Integrationen -- [ ] Zammad und Wartungsplaner-API (nur `firma`) -- [ ] Telegram (nur `daheim`) -- [ ] Spiegel: `firma` sendet, `daheim` empfängt -- [ ] Jede Integration upsertet über `[quelle, quelleRef]` +**Erledigt am 12.09.2026 mit Version 0.6.0.** + +**Ziel:** Aufgaben dort abholen, wo sie entstehen — ohne dass die Planung +darunter leidet, die hier passiert. + +- [x] Gemeinsame Aufnahmestelle: jede Integration liefert nur Funde +- [x] Zammad (nur `firma`), lesend +- [ ] **Wartungsplaner-API** — Schnittstelle steht noch nicht fest +- [x] Telegram (nur `daheim`): erfassen, melden, abhaken +- [x] Spiegel: `firma` sendet, `daheim` empfängt +- [x] Jede Integration upsertet über `[quelle, quelleRef]` + +**Offen geblieben:** Der **Wartungsplaner** ist nicht angebunden. Die +Aufnahmestelle steht bereit und die Seite „Integrationen" führt ihn als +sichtbare Lücke; es fehlt allein das Abholen, und dafür muss erst feststehen, +was das Produkt an Schnittstelle hergibt. + +**Bewusst offen gelassen:** Zammad wird nur gelesen. Ein Ticket schließt man +im Ticketsystem — sonst weiß die Kollegin nicht, warum es plötzlich zu ist. ## M7 – Schnellerfassung und API diff --git a/docs/handbuch/README.md b/docs/handbuch/README.md index f3b7b5c..ba80942 100644 --- a/docs/handbuch/README.md +++ b/docs/handbuch/README.md @@ -20,12 +20,14 @@ Anleitung für den Alltag mit dem Planer. Eine Seite je Thema. verbinden, Belegung verstehen 7. **[Wochenplanung](woche.md)** – Aufgaben per Ziehen und Ablegen in den Kalender legen -8. **[Benachrichtigungen](benachrichtigungen.md)** – Push und E-Mail - einrichten, Ruhezeiten setzen +8. **[Benachrichtigungen](benachrichtigungen.md)** – Push, E-Mail und + Telegram einrichten, Ruhezeiten setzen +9. **[Integrationen](integrationen.md)** – Zammad, Telegram und der Spiegel + zwischen Firma und Daheim ## Verwaltung -9. **[Protokoll](protokoll.md)** – nachsehen, wer wann was geändert hat +10. **[Protokoll](protokoll.md)** – nachsehen, wer wann was geändert hat ## Was noch kommt @@ -33,7 +35,6 @@ Diese Seiten entstehen mit den nächsten Meilensteinen: | Thema | Meilenstein | | ------------------------------- | ----------- | -| Integrationen | M6 | | Schnellerfassung vom Handy, API | M7 | | MCP | M8 | diff --git a/docs/handbuch/integrationen.md b/docs/handbuch/integrationen.md new file mode 100644 index 0000000..e2f0624 --- /dev/null +++ b/docs/handbuch/integrationen.md @@ -0,0 +1,151 @@ +# Integrationen + +Was von außen hereinkommt — und was diese Instanz hinausgibt. Du findest den +Überblick im Menü unter **Integrationen**. + +![Die Seite Integrationen](../bilder/integrationen-hell-schreibtisch.png) + +Welche Integration es überhaupt gibt, hängt an der Instanz und ist nicht +verhandelbar: + +| | Firma | Daheim | +| -------------- | ------ | -------- | +| Zammad | ja | nein | +| Wartungsplaner | ja | nein | +| Telegram | nein | ja | +| Spiegel | sendet | empfängt | + +Eine Integration, die deine Instanz nicht vorsieht, lässt sich auch mit +vollständiger Konfiguration nicht anschalten. Das steckt in der Anwendung, +nicht in einer Einstellung, die sich versehentlich verstellen ließe. + +## Was jede Integration mit deinen Aufgaben darf + +Für alle gilt dieselbe Regel — und die ist wichtiger als jedes Detail +darunter: + +| Führt das Ursprungssystem | Führst du | +| --------------------------------- | ------------------------------------------------ | +| Titel, Notiz, Verweis, Fälligkeit | Bereich, Projekt, Priorität, geschätzter Aufwand | + +Wer ein Ticket in einen Bereich einsortiert und den Aufwand schätzt, muss +sich darauf verlassen können, dass der nächste Abgleich das nicht wegräumt. +Umgekehrt: Ändert sich drüben der Titel, zieht er hier mit. + +Dieselbe Sache ergibt nie eine zweite Aufgabe. Der Planer merkt sich zu jeder +Aufgabe, woher sie kam und unter welcher Kennung. + +## Zammad + +Tickets, auf die der Suchausdruck passt, werden zu Aufgaben. Voreingestellt +sind die dir zugewiesenen offenen Tickets; der Ausdruck steht in der +Konfiguration (`ZAMMAD_ABFRAGE`) und versteht Zammads Suchsyntax. + +- Der Titel wird `#Nummer Betreff`, der Verweis führt direkt ins Ticket. +- Ein Ticket, das Zammad als geschlossen meldet, hakt der Planer ab. +- **Geschrieben wird nach Zammad nichts.** Ein Ticket schließt man im + Ticketsystem — sonst weiß die Kollegin nicht, warum es plötzlich zu ist. + +Der Token gehört einem Benutzer und sieht genau das, was dieser Benutzer +sehen darf. Der Planer umgeht keine Rechte. + +## Wartungsplaner + +Noch nicht angebunden. Die Aufnahmestelle steht bereit — es fehlt allein das +Abholen, und dafür muss die Schnittstelle feststehen. Auf der Seite +**Integrationen** ist der Punkt als offene Lücke sichtbar, damit er nicht in +Vergessenheit gerät. + +## Telegram + +Drei Dinge in einem Kanal. + +### Chat verbinden + +1. Unter **Integrationen** auf **Chat verbinden**. +2. Der achtstellige Code erscheint. Er gilt **zehn Minuten** und genau + **einmal**. +3. Schick ihn dem Bot — als Nachricht oder als `/start ABCD2345`. +4. Der Bot bestätigt, und der Chat erscheint in der Liste. + +> **Warum der Umweg?** Wer nicht in der Liste steht, bekommt vom Bot keine +> Antwort — auch keine Fehlermeldung. Sonst könnte jeder, der die Kennung des +> Bots kennt, herausfinden, dass es dich gibt. Der Code ist der Beweis, dass +> jemand mit Zugang zur Anwendung diesen Chat wirklich will. + +### Erfassen + +Jede Nachricht an den Bot wird eine Aufgabe. Lange Texte werden gekürzt; der +Rest landet in der Notiz und geht nicht verloren. Die Aufgabe hat keinen +Bereich — sie liegt also in der **Inbox** und will einsortiert werden. + +### Melden und abhaken + +Ist Telegram in den [Benachrichtigungen](benachrichtigungen.md) als Weg +eingeschaltet, kommen Meldungen auch hier an. Geht es um genau eine Aufgabe, +hängt darunter ein Knopf **✓ Erledigt** — ein Druck, und sie ist abgehakt, +ohne die Anwendung zu öffnen. + +Mehr kann der Knopf nicht. Löschen oder Verschieben aus einem Chat heraus +wäre zu leicht versehentlich getroffen. + +Je Chat lässt sich einzeln einstellen, ob er Meldungen bekommt: Das Glöckchen +in der Liste schaltet um. + +## Der Spiegel + +Die Firma schickt nach Hause, nicht umgekehrt. Zwei Dinge gehen hinüber. + +**Belegungen.** Wann dienstlich Zeit verplant ist — ohne Titel, ohne Aufgabe, +ohne Kunde. Daheim erscheinen sie in der Wochenansicht als gestreifte Balken +mit der Aufschrift „Dienstlich belegt" und zählen gegen die Tageskapazität. +So kollidiert die private Planung nicht mit der dienstlichen, und trotzdem +verlässt kein Firmeninhalt die Firma. + +**Markierte Aufgaben.** Nur was du an der Aufgabe ausdrücklich zum Spiegeln +freigibst, geht mit Titel hinüber. Das ist eine Einzelentscheidung je +Aufgabe, kein Schalter für alles: Wer versehentlich einen ganzen Bereich +spiegelt, schickt Kundennamen nach Hause. + +Was der Sender nicht mehr schickt, verschwindet auch drüben. Wird ein +Zeitblock in der Firma ausgeplant, ist die Sperre daheim beim nächsten Lauf +weg — sonst stünde dort für immer eine Blockade, die es längst nicht mehr +gibt. + +## Wann läuft was + +| Integration | Takt | +| ----------- | --------------- | +| Telegram | alle 2 Minuten | +| Zammad | alle 15 Minuten | +| Spiegel | alle 15 Minuten | + +Wer dem Bot etwas schickt, erwartet die Aufgabe gleich in der Liste. In +Zammad ändert sich dagegen nichts im Minutentakt. + +Warten muss man trotzdem nicht: Auf der Seite **Integrationen** stößt +**Jetzt abrufen** einen Lauf von Hand an. Das lohnt vor allem direkt nach dem +Einrichten — sonst wüsstest du erst beim nächsten Takt, ob die Zugangsdaten +stimmen. + +## Wenn etwas klemmt + +Unter jeder Integration steht, wann sie zuletzt geglückt ist und woran sie +zuletzt gescheitert ist. Nach dem dritten Fehlschlag hintereinander gilt sie +als **gestört** — und dann meldet sich der Planer auch, sofern du den Anlass +„Ein Kalender lässt sich nicht abgleichen" eingeschaltet hast. + +Erst nach dem dritten Mal: Ein Netz hustet, ein Anbieter hat Wartung. Beim +ersten Fehlschlag zu melden hieße, dich für Dinge zu wecken, die sich von +selbst erledigen. + +| Symptom | Ursache | +| ---------------------------------------- | --------------------------------------------------------------------------------- | +| „Nicht eingerichtet" trotz Konfiguration | Die Instanz sieht diese Integration nicht vor | +| Zammad findet nichts | Der Suchausdruck passt auf kein Ticket — in Zammad selbst probieren | +| Der Bot antwortet nicht | Der Chat ist nicht verbunden, oder der Code war abgelaufen | +| Der Spiegel wird abgelehnt | Verschiedene Geheimnisse, oder die Uhren laufen mehr als fünf Minuten auseinander | + +--- + +Zurück zum [Handbuch](README.md).