Notify board members about moved cards according to their Deck setting
Replaces the yes/no notify_email flag with notify_mode:
- off: no mail
- owner: only the board owner, as before (migrated from notify_email=1)
- board: everyone with access to the board, filtered by their own Deck
"Notifications" setting for it (board:<id>:notify-due: off /
assigned / all), mirroring Deck's NotificationHelper rules
Recipients are resolved via PermissionService::findUsers() (owner, ACL,
groups and circles expanded), AssignmentMapper::isUserAssigned() and
IConfig, none of which reads Deck's frozen $userId. If they cannot be
resolved, no mail is sent rather than one to the wrong people.
Moved cards are collected over the whole run and each recipient gets a
single digest mail afterwards, in their own language.
Bumps to 35.2.0 so the migrations run.
This commit is contained in:
1 parent
27717205cd
commit
578b235f08
14 files changed
+579
-100
No files matched your search
@@ -10,7 +10,12 @@ Pro Workflow lässt sich konfigurieren:
|
||||
|
||||
- Quell-Board und Quell-Stapel
|
||||
- Ziel-Stapel, in den **alle** überfälligen Karten des Quell-Stapels verschoben werden
|
||||
- Checkbox: E-Mail-Benachrichtigung an den Workflow-Besitzer, sobald eine Karte verschoben wurde
|
||||
- E-Mail-Benachrichtigung über verschobene Karten, in drei Stufen:
|
||||
- **Keine E-Mail**
|
||||
- **Nur an mich** – an den Board-Eigentümer, unabhängig von seinen Deck-Einstellungen
|
||||
- **An Board-Mitglieder laut Deck-Einstellung** – an alle, die das Board sehen dürfen (Eigentümer, freigegebene Nutzer, Mitglieder freigegebener Gruppen und Teams), gefiltert nach deren eigener Deck-Einstellung *Benachrichtigungen* für dieses Board: *Alle Karten* → immer, *Zugewiesene Karten* (Deck-Standard) → nur wenn man der Karte direkt oder über eine Gruppe/ein Team zugewiesen ist, *Keine* → nie. Der Eigentümer eines nicht geteilten Boards bekommt wie in Deck jede Karte, außer er hat *Keine* gewählt.
|
||||
|
||||
Pro Lauf des Hintergrundjobs bekommt jeder Empfänger höchstens **eine** Sammelmail mit allen für ihn verschobenen Karten, in seiner eingestellten Sprache.
|
||||
|
||||
Workflows lassen sich nur für Boards anlegen, deren Eigentümer man ist. Ein Workflow gehört dem jeweiligen Board-Eigentümer, nicht dem, der ihn angelegt hat: Wird ein Board in Deck übertragen, sieht und verwaltet ab sofort der neue Eigentümer seine Workflows, und der Hintergrundjob läuft in dessen Namen. Ein Nutzer kann beliebig viele Workflows anlegen, bearbeiten, deaktivieren oder löschen.
|
||||
|
||||
@@ -19,7 +24,7 @@ Workflows lassen sich nur für Boards anlegen, deren Eigentümer man ist. Ein Wo
|
||||
- **Keine HTTP/OCS-Aufrufe gegen Deck.** Alles Lesen (Boards, Stapel, Karten) und das Verschieben von Karten läuft ausschließlich über Decks eigene interne PHP-Klassen (`OCA\Deck\Service\CardService`, `StackService`, `BoardService`, `OCA\Deck\Db\CardMapper`, …), aufgelöst per Dependency Injection direkt im selben PHP-Prozess. Sämtlicher Deck-Zugriff ist in [`lib/Service/DeckIntegrationService.php`](lib/Service/DeckIntegrationService.php) gebündelt.
|
||||
- **Hintergrundjob statt Seitenaufruf.** [`lib/BackgroundJob/RunWorkflowsJob.php`](lib/BackgroundJob/RunWorkflowsJob.php) ist ein einfacher `Job` ohne eigenes Intervall: Er läuft bei jedem Cron-Durchlauf von Nextcloud (üblicherweise alle 5 Minuten) und ruft [`lib/Service/WorkflowRunner.php`](lib/Service/WorkflowRunner.php) auf.
|
||||
- **Rechte-Kontext je Nutzer.** Ein Hintergrundjob hat standardmäßig keinen eingeloggten Nutzer, muss aber die Regeln mehrerer Nutzer in einem einzigen Lauf auswerten. Der `WorkflowRunner` "verkörpert" deshalb für die Dauer der jeweiligen Workflows kurzzeitig den entsprechenden Besitzer. Dazu gehört mehr als `IUserSession::setUser()`: Decks Berechtigungsprüfungen lesen die Session gar nicht, sondern eine Benutzer-ID, die beim Bau des Deck-Containers einmal pro Prozess eingefroren wird. `DeckIntegrationService::beginUserContext()` setzt diesen Wert für die Dauer der Verkörperung auf den Workflow-Besitzer und stellt ihn danach wieder her; schlägt das fehl, wird der Nutzer in diesem Lauf übersprungen, statt unter fremden Rechten zu arbeiten.
|
||||
- **E-Mail** läuft über Nextclouds eigenen `IMailer` (nutzt also den in der Nextcloud-Administration hinterlegten Mailserver) und geht an die im Profil des Workflow-Besitzers hinterlegte Adresse.
|
||||
- **E-Mail** läuft über Nextclouds eigenen `IMailer` (nutzt also den in der Nextcloud-Administration hinterlegten Mailserver) und geht an die im Profil der jeweiligen Empfänger hinterlegte Adresse. Die Empfänger und ihre Deck-Einstellungen ermittelt die App ebenfalls über Decks interne Klassen bzw. die Nutzereinstellung `deck` / `board:<id>:notify-due`.
|
||||
|
||||
### Wichtiger Hinweis zu Decks internen Klassen
|
||||
|
||||
@@ -42,7 +47,7 @@ Ein Workflow verweist per ID auf ein Board und zwei Stapel. Wird eines davon in
|
||||
|
||||
- **Beim Speichern** werden Board und Stapel geprüft; ein Workflow auf nicht mehr existierende Ziele lässt sich gar nicht erst anlegen.
|
||||
- **In der Übersicht** wird ein betroffener Workflow rot markiert („Board nicht mehr vorhanden", „Quell-Stapel nicht mehr vorhanden" …).
|
||||
- **Im Hintergrundjob** wird der Workflow automatisch deaktiviert und der Besitzer einmalig per E-Mail informiert — unabhängig davon, ob für den Workflow „E-Mail senden" aktiviert ist, denn hier geht es nicht um verschobene Karten, sondern darum, dass die Automatisierung nicht mehr läuft. Danach bleibt es still: Ein deaktivierter Workflow wird nicht erneut ausgewertet.
|
||||
- **Im Hintergrundjob** wird der Workflow automatisch deaktiviert und der Besitzer einmalig per E-Mail informiert — unabhängig von der E-Mail-Einstellung des Workflows, denn hier geht es nicht um verschobene Karten, sondern darum, dass die Automatisierung nicht mehr läuft. Danach bleibt es still: Ein deaktivierter Workflow wird nicht erneut ausgewertet.
|
||||
|
||||
Ist Deck vorübergehend nicht erreichbar, wird **nicht** deaktiviert — der Job überspringt den Workflow und versucht es beim nächsten Lauf erneut. Archivierte Boards lösen die Deaktivierung ebenfalls nicht aus, sie sind nur in den Auswahlfeldern ausgeblendet.
|
||||
|
||||
@@ -129,7 +134,7 @@ In [`.gitea/workflows/`](.gitea/workflows/):
|
||||
|
||||
## Datenmodell
|
||||
|
||||
Workflows werden in der Tabelle `wfda_workflows` gespeichert (siehe [`lib/Migration/Version1000Date20260813120000.php`](lib/Migration/Version1000Date20260813120000.php)): eine Zeile pro Workflow, mit Board-/Stapel-IDs, `user_id` (der Board-Eigentümer, in dessen Namen der Job läuft — wird bei jedem Lauf aus Deck aktualisiert) sowie `enabled`/`notify_email`/`last_run`. Die früheren Filter-Spalten `filter_user_ids`/`filter_label_ids` entfernt [`Version1001Date20260930120000`](lib/Migration/Version1001Date20260930120000.php).
|
||||
Workflows werden in der Tabelle `wfda_workflows` gespeichert (siehe [`lib/Migration/Version1000Date20260813120000.php`](lib/Migration/Version1000Date20260813120000.php)): eine Zeile pro Workflow, mit Board-/Stapel-IDs, `user_id` (der Board-Eigentümer, in dessen Namen der Job läuft — wird bei jedem Lauf aus Deck aktualisiert) sowie `enabled`/`notify_mode`/`last_run`. Die früheren Filter-Spalten `filter_user_ids`/`filter_label_ids` entfernt [`Version1001Date20260930120000`](lib/Migration/Version1001Date20260930120000.php). [`Version1002Date20261001120000`](lib/Migration/Version1002Date20261001120000.php) ersetzt das frühere Ja/Nein-Feld `notify_email` durch `notify_mode` (`off`/`owner`/`board`; gesetztes Häkchen → `owner`), [`Version1003Date20261001120100`](lib/Migration/Version1003Date20261001120100.php) entfernt die alte Spalte.
|
||||
|
||||
## Lizenz
|
||||
|
||||
|
||||
Reference in new issue
Block a user