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
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.
115 lines
5.6 KiB
Markdown
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.
|