Patrick Niebeling 184c39d829
Build package / php-lint (8.2) (push) Successful in 50s
Build package / php-lint (8.3) (push) Successful in 36s
Build package / php-lint (8.4) (push) Successful in 40s
Build package / xml-lint (push) Successful in 11s
Build package / unit-tests (push) Successful in 44s
Build package / package (push) Successful in 50s
Document that the time_sensitive column has to be reset once
Shipping the TIME_SENSITIVE change is not enough for instances that already
ran the job: getNext() filters on the time_sensitive column of oc_jobs, and
JobList::setLastRun() only ever sets it to TIME_INSENSITIVE -- there is no
else branch, and JobList::add() writes the column only when inserting, so
re-registering an existing job on app update or app:enable leaves the stamp
in place.

Document the one-off UPDATE (and the occ-only alternative) in the README
troubleshooting section and in CLAUDE.md.
2026-08-13 15:18:22 +02:00

Deck Workflow-Automatisierung

Nextcloud-App für Nextcloud Hub 26 Spring (Server 34.x), die überfällige Karten der Deck-App automatisch von einem Stapel in einen anderen verschiebt und optional eine E-Mail-Benachrichtigung verschickt.

Ersetzt das früher genutzte eigenständige PHP-Cron-Skript durch eine vollwertige App mit Oberfläche in den persönlichen Einstellungen — jeder Nutzer kann dort seine eigenen Regeln ("Workflows") anlegen, ohne Admin-Rechte oder Server-Zugriff zu benötigen.

Funktionsumfang

Pro Workflow lässt sich konfigurieren:

  • Quell-Board und Quell-Stapel
  • Ziel-Stapel, in den überfällige Karten verschoben werden
  • optionaler Filter auf zugewiesene Benutzer (Karte muss mindestens einem der gewählten Benutzer zugewiesen sein)
  • optionaler Filter auf Labels/Tags (Karte muss mindestens eines der gewählten Labels haben)
  • Checkbox: E-Mail-Benachrichtigung an den Workflow-Besitzer, sobald eine Karte verschoben wurde

Ein Nutzer kann beliebig viele Workflows anlegen, bearbeiten, deaktivieren oder löschen.

Architektur

  • Keine HTTP/OCS-Aufrufe gegen Deck. Alles Lesen (Boards, Stapel, Karten, Labels, zugewiesene Benutzer) 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 gebündelt.
  • Hintergrundjob statt Seitenaufruf. lib/BackgroundJob/RunWorkflowsJob.php ist ein TimedJob, der standardmäßig alle 5 Minuten läuft (abhängig vom Nextcloud-Cron-Intervall) und lib/Service/WorkflowRunner.php aufruft. Das Intervall ist über die config.php einstellbar, siehe unten.
  • Rechte-Kontext je Nutzer. Da Decks Berechtigungsprüfungen die aktuell eingeloggte Session lesen, ein Hintergrundjob aber standardmäßig keinen eingeloggten Nutzer hat und Regeln mehrerer Nutzer in einem einzigen Lauf auswerten muss, "verkörpert" der WorkflowRunner für die Dauer der jeweiligen Workflows kurzzeitig den entsprechenden Besitzer (IUserSession::setUser()), bevor die Deck-Klassen aufgerufen werden.
  • 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.

Wichtiger Hinweis zu Decks internen Klassen

OCA\Deck\* ist keine dokumentierte, stabile öffentliche API von Deck (keine @since-Markierungen, keine offizielle Zusicherung von Abwärtskompatibilität). Diese App verwendet sie trotzdem bewusst direkt, wie es die Vorgabe verlangt — jeder Zugriff läuft defensiv abgesichert über DeckIntegrationService (Prüfung, ob Deck aktiviert ist, class_exists()-Checks, try/catch mit Logging statt Absturz). Nach größeren Deck-Updates lohnt sich ein Blick ins Nextcloud-Log, falls Workflows plötzlich nicht mehr greifen.

Installation

  1. App in apps/workflow_deck_automation des Nextcloud-Servers ablegen (oder über den Appstore-Build aus der CI, siehe unten).
  2. In der Nextcloud-Administration unter Apps aktivieren.
  3. Die Deck-App muss installiert und für die jeweiligen Nutzer aktiviert sein.
  4. Sicherstellen, dass der Hintergrundjob-Modus auf Cron (empfohlen) steht, damit RunWorkflowsJob regelmäßig läuft.

Benutzung

Jeder Nutzer findet die Einstellungen unter Persönliche Einstellungen → Deck Workflow-Automatisierung. Dort können neue Workflows angelegt, bestehende bearbeitet oder gelöscht werden. Die Dropdowns für Board/Stapel/Label/Benutzer werden live aus Deck geladen. Zur Auswahl stehen nur aktive Boards — archivierte und im Papierkorb liegende Boards sowie gelöschte Stapel blendet Deck bzw. die App aus.

Konfiguration

Das Prüfintervall des Hintergrundjobs lässt sich in der config.php setzen (Wert in Sekunden):

'workflow_deck_automation.interval' => 300,
  • Standard ohne Eintrag: 300 (5 Minuten).
  • Minimum: 60 — kleinere Werte werden auf 60 Sekunden angehoben.
  • Die Änderung greift beim nächsten Cron-Durchlauf; ein occ-Befehl oder eine Neuinstallation der App ist nicht nötig.

Zu beachten: Das ist eine Untergrenze für den Abstand zwischen zwei Läufen, keine Garantie. Nextclouds Cron selbst läuft üblicherweise nur alle 5 Minuten — ein Intervall von 60 Sekunden führt also nur dann zu minütlichen Läufen, wenn der System-Cron entsprechend häufig ausgeführt wird.

Der Job läuft nur nachts bzw. gar nicht

Der Job ist als TIME_SENSITIVE deklariert und läuft damit rund um die Uhr. Nextcloud merkt sich die Zeitsensitivität aber zusätzlich in der Spalte time_sensitive der Tabelle oc_jobs, und JobList::setLastRun() setzt sie nur in eine Richtung — von „zeitkritisch" auf „unkritisch", nie zurück. Wer eine ältere Version dieser App installiert hatte (bis einschließlich v0.1.0 war der Job TIME_INSENSITIVE), hat diesen Stempel noch in der Datenbank. Er wird weder durch ein App-Update noch durch app:enable zurückgesetzt.

Symptom: Ist in der config.php ein maintenance_window_start gesetzt, läuft der Job nur in diesem 4-Stunden-Fenster und den Rest des Tages gar nicht.

Einmalig korrigieren:

UPDATE oc_jobs SET time_sensitive = 0
 WHERE class = 'OCA\\WorkflowDeckAutomation\\BackgroundJob\\RunWorkflowsJob';

Ohne Datenbankzugriff geht es auch über occ, indem der Job gelöscht und durch Aus-/Einschalten der App neu registriert wird:

php occ background-job:list --class 'OCA\WorkflowDeckAutomation\BackgroundJob\RunWorkflowsJob'
php occ background-job:delete <id>
php occ app:disable workflow_deck_automation
php occ app:enable workflow_deck_automation

Neuinstallationen sind nicht betroffen.

Entwicklung

Voraussetzungen: PHP 8.2+, Composer, Node.js 24+, npm 11+.

composer install
npm install
npm run build      # einmaliger Produktions-Build
npm run watch       # Entwicklung mit automatischem Rebuild

Tests & Linting

composer run lint       # php -l über lib/ und tests/
composer run cs:check   # nextcloud/coding-standard (php-cs-fixer)
composer run test:unit  # PHPUnit — reine Filter-Logik, benötigt keine Deck-Installation

Ein echter End-to-End-Test (Karte anlegen, Workflow konfigurieren, Hintergrundjob auslösen, Verschiebung + Mail prüfen) lässt sich nur gegen eine echte Nextcloud-34-Instanz mit installierter Deck-App durchführen, z. B. per:

# Job-ID und letzten Lauf anzeigen
php occ background-job:list --class 'OCA\WorkflowDeckAutomation\BackgroundJob\RunWorkflowsJob'

# Sofort ausführen, unabhängig vom Intervall
php occ background-job:execute <id> --force-execute

# Oder dauerhaft als Worker laufen lassen (Argument ist die Job-Klasse, keine App-ID)
php occ background-job:worker 'OCA\WorkflowDeckAutomation\BackgroundJob\RunWorkflowsJob'

Release-Paket bauen

make appstore

Erzeugt build/artifacts/appstore/workflow_deck_automation.tar.gz.

CI (Gitea Actions)

In .gitea/workflows/:

Workflow Zweck
lint-php.yml php -l über eine PHP-8.28.4-Matrix
lint-info-xml.yml validiert appinfo/info.xml gegen das Appstore-XML-Schema
phpunit.yml führt die PHPUnit-Tests aus (SQLite/rein logisch, kein DB-Service nötig)
build-main.yml baut Frontend + Appstore-Archiv und veröffentlicht es als Release-Asset — bei Push auf main als rollendes Pre-Release latest-main, bei Push eines v*-Tags als reguläres Release

Datenmodell

Workflows werden in der Tabelle wfda_workflows gespeichert (siehe lib/Migration/Version1000Date20260813120000.php): eine Zeile pro Workflow, mit user_id-Bezug, Board-/Stapel-IDs, JSON-kodierten Filterlisten sowie enabled/notify_email/last_run.

Lizenz

AGPL-3.0-or-later

S
Description
No description provided
Readme
452 KiB
v34.0.2
Latest
2026-08-25 13:48:32 +02:00
Languages
PHP 79.1%
Vue 17.4%
JavaScript 2.2%
Makefile 1.3%