Let workflows move cards by start date instead of due date
Build package / xml-lint (push) Successful in 3m32s
Build package / unit-tests (push) Successful in 4m49s
Build package / php-lint (8.5) (push) Successful in 4m52s
Build package / php-lint (8.4) (push) Successful in 4m56s
Build package / package (push) Successful in 2m28s
Build package / xml-lint (push) Successful in 3m32s
Build package / unit-tests (push) Successful in 4m49s
Build package / php-lint (8.5) (push) Successful in 4m52s
Build package / php-lint (8.4) (push) Successful in 4m56s
Build package / package (push) Successful in 2m28s
Each workflow now has a trigger date (due or start): the runner compares either the card's due date or its start date against now, read straight from Deck's Card entity. Mails and Nextcloud notifications say whether the card was overdue or reached its start date. Cards without the chosen date stay put. Deck only has a start date since 1.18 and Entity getters are magic, so DeckIntegrationService::supportsStartdate() checks the property; without it the form rejects start-date workflows and the runner skips them without disabling them. WorkflowRunner::isOverdue() becomes hasPassed(), as it now covers both dates. Existing workflows keep the due date (migration Version1005). Bumps to 35.4.0 so the migration runs.
This commit is contained in:
1 parent
5bd3181f10
commit
8268f1068d
18 files changed
+286
-71
No files matched your search
@@ -4,7 +4,7 @@ Leitfaden für Claude Code (claude.ai/code) in diesem Repository.
|
||||
|
||||
## Worum es geht
|
||||
|
||||
Nextcloud-App `workflow_deck_automation` (Namespace `WorkflowDeckAutomation`) für **Nextcloud 35** (`main`, `min-version="35" max-version="35"`). Jeder Nutzer legt in seinen persönlichen Einstellungen „Workflows“ an, die überfällige [Deck](https://github.com/nextcloud/deck)-Karten von einem Stack in einen anderen verschieben, optional mit Mail. Es gibt bewusst **keine Kartenfilter**: ein Workflow verschiebt *jede* überfällige Karte seines Quell-Stacks. Ein Hintergrund-`Job` wertet alle aktiven Workflows bei jedem Cron-Lauf aus.
|
||||
Nextcloud-App `workflow_deck_automation` (Namespace `WorkflowDeckAutomation`) für **Nextcloud 35** (`main`, `min-version="35" max-version="35"`). Jeder Nutzer legt in seinen persönlichen Einstellungen „Workflows“ an, die [Deck](https://github.com/nextcloud/deck)-Karten von einem Stack in einen anderen verschieben, sobald ihr Fälligkeits- oder Startdatum erreicht ist (`trigger_date`, pro Workflow), optional mit Mail. Es gibt bewusst **keine Kartenfilter**: ein Workflow verschiebt *jede* Karte seines Quell-Stacks, deren Datum erreicht ist. Ein Hintergrund-`Job` wertet alle aktiven Workflows bei jedem Cron-Lauf aus.
|
||||
|
||||
## Harte Vorgabe: keine HTTP/OCS-Aufrufe gegen Deck
|
||||
|
||||
@@ -25,7 +25,7 @@ Alle Lesezugriffe (Boards, Stacks, Karten) und das Verschieben laufen über Deck
|
||||
|
||||
**Regel:** Bevor ein weiterer `OCA\Deck\*`-Dienst im Runner genutzt wird, prüfen, ob er eine eingefrorene `$userId` trägt – der Fehler ist still und nutzerübergreifend. Bevorzugt Mapper (QBMapper ohne Nutzerzustand) oder Methoden mit explizitem uid-Parameter verwenden. Deshalb wird `BoardService::getUserBoards()` nicht verwendet.
|
||||
|
||||
Die Fälligkeitslogik `WorkflowRunner::isOverdue()` und die Empfängerregel `NotificationPolicy::shouldNotify()` sind bewusst `static` und seiteneffektfrei, also ohne Deck unit-testbar (`tests/Unit/Service/`). Das sind die einzigen getesteten Teile der App. Neue reine Logik in dieser Form halten.
|
||||
Der Datumsvergleich `WorkflowRunner::hasPassed()`, `TriggerDate` und die Empfängerregel `NotificationPolicy::shouldNotify()` sind bewusst `static` und seiteneffektfrei, also ohne Deck unit-testbar (`tests/Unit/Service/`). Das sind die einzigen getesteten Teile der App. Neue reine Logik in dieser Form halten.
|
||||
|
||||
## Workflows werden deaktiviert, wenn Board/Stack verschwinden
|
||||
|
||||
@@ -71,9 +71,17 @@ Wird ein Board in Deck übertragen, wandern seine Workflows mit.
|
||||
|
||||
Die App wird nur intern genutzt und spricht ausschließlich Deutsch. Oberfläche, Controller-Fehlermeldungen (erscheinen im Formular), Sektionsname, Mails und Nextcloud-Benachrichtigungen sind direkt auf Deutsch geschrieben. Es gibt kein `IL10N` und keinen `l10n/`-Ordner. Nextclouds eigene Mail-Fußzeile wird per `addFooter('', 'de')` ebenfalls deutsch, sonst würde sie im Cron der Instanz-Standardsprache folgen. Log-Meldungen bleiben englisch. Neue nutzersichtbare Texte auf Deutsch schreiben, mit „du“ wie im Rest der App.
|
||||
|
||||
## Fälligkeits- oder Startdatum löst das Verschieben aus
|
||||
|
||||
`trigger_date` (`TriggerDate::ALL`: `due`/`start`, Default und Migrationswert `due`, `Version1005…`) wählt pro Workflow, welches Kartendatum der Runner mit „jetzt“ vergleicht. Unbekannte Werte zählen als `due`. Karten ohne das gewählte Datum bleiben liegen.
|
||||
|
||||
- **`startdate` gibt es erst seit Deck 1.18.** `Card`-Getter sind magisch (`Entity::__call`), `method_exists()` sieht sie nicht und `getStartdate()` würde erst beim Aufruf werfen. Daher `DeckIntegrationService::supportsStartdate()` (`property_exists`). Der Runner liest `getStartdate()` nur bei `start` und überspringt solche Workflows ohne Deaktivierung, wenn Deck das Feld nicht kennt. Der Controller lehnt `start` dann ab.
|
||||
- **Texte:** `TriggerDate::describeReason()` liefert den Satzteil („ist überfällig“ / „hat ihr Startdatum erreicht“) für Mail und Notifier. `NotificationPusher` speichert `triggerDate` in den Subject-Parametern. Ältere Benachrichtigungen ohne den Schlüssel gelten als `due`.
|
||||
- **Empfänger:** Auch Startdatums-Workflows nutzen bei `notify_mode = board` Decks `notify-due`-Einstellung. Deck hat keine eigene für das Startdatum.
|
||||
|
||||
## Fälligkeit wird als UTC-Zeitpunkt verglichen
|
||||
|
||||
Decks `duedate` ist eine `DATETIME`-Spalte ohne Zeitzone mit UTC-Uhrzeit (Frontend sendet `toISOString()`). `Entity` baut daraus `new \DateTime($string)` in PHPs Standardzone, die Nextcloud auf UTC setzt. `WorkflowRunner::asStoredUtc()` legt die Uhrzeit trotzdem ausdrücklich auf UTC fest, damit das Ergebnis nicht von dieser Standardzone abhängt. Decks eigene Pfade `Card::getDaysUntilDue()` (tagesgenau) und `CardMapper::findOverdue()` (vergleicht mit dem `NOW()` der Datenbank, also Ortszeit) sind dafür ungeeignet und werden nicht verwendet.
|
||||
Decks `duedate` und `startdate` sind `DATETIME`-Spalten ohne Zeitzone mit UTC-Uhrzeit (Frontend sendet `toISOString()`). `Entity` baut daraus `new \DateTime($string)` in PHPs Standardzone, die Nextcloud auf UTC setzt. `WorkflowRunner::asStoredUtc()` legt die Uhrzeit trotzdem ausdrücklich auf UTC fest, damit das Ergebnis nicht von dieser Standardzone abhängt. Decks eigene Pfade `Card::getDaysUntilDue()` (tagesgenau) und `CardMapper::findOverdue()` (vergleicht mit dem `NOW()` der Datenbank, also Ortszeit) sind dafür ungeeignet und werden nicht verwendet.
|
||||
|
||||
## Kartenfilter wurden entfernt
|
||||
|
||||
|
||||
Reference in new issue
Block a user