Add Deck workflow automation Nextcloud app
Lint info.xml / xml-lint (push) Successful in 30s
Lint PHP / php-lint (8.2) (push) Successful in 55s
Lint PHP / php-lint (8.3) (push) Successful in 44s
Lint PHP / php-lint (8.4) (push) Successful in 41s
PHPUnit / unit-tests (push) Failing after 41s

Ports the standalone due-date cron script into a proper Nextcloud 34
app with a personal-settings UI, per-user workflow configuration
(source/target stack, assigned-user and label filters, email
notification), a TimedJob background runner, and Gitea CI pipelines.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Patrick Niebeling
2026-08-13 10:13:05 +02:00
co-authored by Claude Sonnet 5
commit 300acde27e
34 changed files with 1918 additions and 0 deletions
+91
View File
@@ -0,0 +1,91 @@
# Deck Workflow-Automatisierung
Nextcloud-App für **Nextcloud Hub 26 Spring (Server 34.x)**, die überfällige Karten der [Deck](https://github.com/nextcloud/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`](lib/Service/DeckIntegrationService.php) gebündelt.
- **Hintergrundjob statt Seitenaufruf.** [`lib/BackgroundJob/RunWorkflowsJob.php`](lib/BackgroundJob/RunWorkflowsJob.php) ist ein `TimedJob`, der alle 5 Minuten läuft (abhängig vom Nextcloud-Cron-Intervall) und [`lib/Service/WorkflowRunner.php`](lib/Service/WorkflowRunner.php) aufruft.
- **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](https://apps.nextcloud.com/apps/deck) muss installiert und für die jeweiligen Nutzer aktiviert sein.
4. Sicherstellen, dass der [Hintergrundjob-Modus](https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/background_jobs_configuration.html) 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.
## Entwicklung
Voraussetzungen: PHP 8.2+, Composer, Node.js 24+, npm 11+.
```bash
composer install
npm install
npm run build # einmaliger Produktions-Build
npm run watch # Entwicklung mit automatischem Rebuild
```
### Tests & Linting
```bash
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:
```bash
php occ background-job:worker workflow_deck_automation
```
### Release-Paket bauen
```bash
make appstore
```
Erzeugt `build/artifacts/appstore/workflow_deck_automation.tar.gz`.
## CI (Gitea Actions)
In [`.gitea/workflows/`](.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-release.yml` | baut bei Push eines `v*`-Tags das Frontend und paketiert das Appstore-Archiv |
## Datenmodell
Workflows werden in der Tabelle `wfda_workflows` gespeichert (siehe [`lib/Migration/Version1000Date20260813120000.php`](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