Files
nextcloud-workflow-deck-aut…/DEVELOPMENT.md
T
Patrick Niebeling e5b5f25748
Build package / xml-lint (push) Successful in 1m1s
Build package / php-lint (8.4) (push) Successful in 1m47s
Build package / php-lint (8.5) (push) Successful in 1m49s
Build package / unit-tests (push) Successful in 1m51s
Build package / package (push) Successful in 1m58s
Split the docs: README for users, DEVELOPMENT.md for developers
The README now explains setup, workflows, the mail options with Deck's
real menu names, and what happens when boards or stacks disappear -
without class names. Architecture, data model, tests, CI, release and
the time_sensitive troubleshooting move to DEVELOPMENT.md, fixing the
stale CI table, PHP version and Nextcloud version on the way.
DEVELOPMENT.md is excluded from the app package.
2026-09-30 11:43:53 +02:00

115 lines
5.6 KiB
Markdown

# Entwicklung
Informationen für Entwickler und Admins, die tiefer einsteigen. Die Nutzer-Doku steht in der [README](README.md). Ausführliche Hintergründe zu den Stolperfallen, also warum etwas genau so gebaut ist, stehen in [CLAUDE.md](CLAUDE.md).
## Aufbau
- **Keine HTTP/OCS-Aufrufe gegen Deck.** Lesen (Boards, Stapel, Karten, Board-Mitglieder) und das Verschieben laufen ausschließlich über Decks interne PHP-Klassen im selben Prozess. Sämtlicher Deck-Zugriff ist in [`lib/Service/DeckIntegrationService.php`](lib/Service/DeckIntegrationService.php) gebündelt.
- `OCA\Deck\*` ist keine stabile öffentliche API. Jeder Zugriff ist deshalb abgesichert: `class_exists()`-Checks, Prüfung ob Deck aktiviert ist, try/catch mit Logging.
- Nach größeren Deck-Updates lohnt sich ein Blick ins Nextcloud-Log.
- **Hintergrundjob:** [`RunWorkflowsJob`](lib/BackgroundJob/RunWorkflowsJob.php) ist ein einfacher `Job` ohne Intervall. Er läuft bei jedem Cron-Durchlauf und ruft [`WorkflowRunner`](lib/Service/WorkflowRunner.php) auf.
- **Rechte-Kontext:** Der Runner arbeitet die Workflows nach Eigentümer gruppiert ab und setzt Deck jeweils auf diesen Nutzer, per `DeckIntegrationService::beginUserContext()`. Decks Berechtigungsprüfungen lesen nämlich nicht die Session, sondern eine pro Prozess festgelegte Nutzer-ID.
- **E-Mail:** [`NotificationMailer`](lib/Service/NotificationMailer.php) verschickt über Nextclouds `IMailer`. Die Empfänger ermittelt `DeckIntegrationService::findNotificationRecipients()`, die Entscheidungsregel steckt in [`NotificationPolicy`](lib/Service/NotificationPolicy.php).
- **Oberfläche:** [`src/PersonalSettings.vue`](src/PersonalSettings.vue) (Vue 3, `@nextcloud/vue` 9) spricht über [`src/api.js`](src/api.js) mit dem OCS-Controller [`WorkflowController`](lib/Controller/WorkflowController.php).
## Datenmodell
Die Tabelle `wfda_workflows` enthält eine Zeile pro Workflow:
| Spalte | Bedeutung |
| --- | --- |
| `board_id`, `source_stack_id`, `target_stack_id` | Deck-IDs |
| `user_id` | Board-Eigentümer, in dessen Namen der Job läuft. Wird bei jedem Lauf aus Deck aktualisiert. |
| `notify_mode` | `off`, `owner` oder `board` |
| `enabled`, `last_run` | aktiv? / letzter Lauf |
Migrationen in [`lib/Migration/`](lib/Migration/):
- `Version1000…` legt die Tabelle an.
- `Version1001…` entfernt die früheren Filter-Spalten.
- `Version1002…` und `Version1003…` ersetzen `notify_email` durch `notify_mode`. Ein gesetztes Häkchen wird dabei zu `owner`.
Migrationen laufen nur, wenn die App-Version steigt.
## Lokales Setup
Voraussetzungen: PHP 8.4+, Composer, Node.js 24 mit npm.
```bash
composer install
npm install # nicht `npm ci`: Lockfiles werden bewusst nicht committet
npm run build # Produktions-Build
npm run watch # Entwicklung mit automatischem Rebuild
```
## Tests und Linting
```bash
composer run lint # php -l über lib/ und tests/
composer run cs:check # nextcloud/coding-standard (cs:fix korrigiert)
composer run test:unit # PHPUnit
```
Die Unit-Tests decken nur reine Logik ab, ohne Deck-Installation:
- Fälligkeitsprüfung (`WorkflowRunner::isOverdue()`)
- Empfängerregel (`NotificationPolicy::shouldNotify()`)
Die Deck-Anbindung lässt sich nur auf einer echten Nextcloud-35-Instanz mit Deck testen:
```bash
# Job-ID und letzten Lauf anzeigen
php occ background-job:list --class 'OCA\WorkflowDeckAutomation\BackgroundJob\RunWorkflowsJob'
# Sofort ausführen, ohne auf Cron zu warten
php occ background-job:execute <id> --force-execute
```
## Build, CI und Release
`make appstore` erzeugt `build/artifacts/appstore/workflow_deck_automation.tar.gz`.
Die einzige Pipeline ist [`.gitea/workflows/build-main.yml`](.gitea/workflows/build-main.yml):
| Job | Zweck |
| --- | --- |
| `php-lint` | `php -l` mit PHP 8.4 und 8.5 |
| `xml-lint` | prüft `appinfo/info.xml` gegen das Appstore-Schema |
| `unit-tests` | PHPUnit |
| `package` | Frontend-Build und `make appstore`. Läuft nur, wenn die Checks grün sind. |
Das Paket wird als Release veröffentlicht:
- Bei jedem Push auf `main` als Pre-Release **`latest-main`**, das jedes Mal neu erzeugt wird.
- Bei einem `v*`-Tag als reguläres Release.
- Bei Pull Requests wird nur gebaut, nicht veröffentlicht.
**Versionen** folgen dem Schema `<Nextcloud-Major>.<minor>.<patch>`, also aktuell `35.x.y`.
Ablauf für ein Release:
1. Version in `appinfo/info.xml` und `package.json` gleich anheben.
2. Auf `main` pushen und warten, bis die Pipeline grün ist.
3. `git tag -a vX.Y.Z -m "…" && git push origin vX.Y.Z`.
Einzelheiten, etwa zum Verschieben eines Tags nach einem fehlgeschlagenen Build, stehen in [CLAUDE.md](CLAUDE.md).
## Fehlersuche: Der Job läuft nur nachts oder gar nicht
Nextcloud überspringt „nicht zeitkritische“ Jobs außerhalb des Wartungsfensters (`maintenance_window_start` in der `config.php`). Bis einschließlich v0.1.0 war dieser Job als nicht zeitkritisch markiert. Diese Markierung bleibt in der Spalte `oc_jobs.time_sensitive` stehen, auch nach App-Updates.
Symptom: Der Job läuft nur im 4-Stunden-Wartungsfenster, oder `occ background-job:list` zeigt als letzten Lauf `1970-01-01`.
Einmalig korrigieren:
```sql
UPDATE oc_jobs SET time_sensitive = 0
WHERE class = 'OCA\\WorkflowDeckAutomation\\BackgroundJob\\RunWorkflowsJob';
```
Oder ohne Datenbankzugriff den Job löschen und durch Aus- und Einschalten der App neu registrieren:
```bash
php occ background-job:delete <id>
php occ app:disable workflow_deck_automation
php occ app:enable workflow_deck_automation
```
Die frühere `config.php`-Option `workflow_deck_automation.interval` (bis v0.1.0) wird ignoriert und kann entfernt werden.