Notify board members about moved cards according to their Deck setting
Build package / unit-tests (push) Failing after 20s
Build package / xml-lint (push) Successful in 46s
Build package / php-lint (8.4) (push) Successful in 1m30s
Build package / php-lint (8.5) (push) Successful in 1m36s
Build package / package (push) Skipped

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:
Patrick Niebeling committed 2026-09-30 10:31:45 +02:00
1 parent 27717205cd
commit 578b235f08
14 files changed
+579 -100

No files matched your search

+13 -9
View File
@@ -8,6 +8,7 @@ use OCA\WorkflowDeckAutomation\Db\Workflow;
use OCA\WorkflowDeckAutomation\Db\WorkflowMapper;
use OCA\WorkflowDeckAutomation\Service\DeckIntegrationService;
use OCA\WorkflowDeckAutomation\Service\DeckUnavailableException;
use OCA\WorkflowDeckAutomation\Service\NotificationPolicy;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\Attribute\NoAdminRequired;
@@ -55,14 +56,14 @@ class WorkflowController extends OCSController {
int $boardId,
int $sourceStackId,
int $targetStackId,
bool $notifyEmail = false,
string $notifyMode = NotificationPolicy::MODE_OFF,
bool $enabled = true,
): DataResponse {
$this->validate($title, $boardId, $sourceStackId, $targetStackId);
$this->validate($title, $boardId, $sourceStackId, $targetStackId, $notifyMode);
$workflow = new Workflow();
$workflow->setUserId($this->currentUserId());
$this->applyFields($workflow, $title, $boardId, $sourceStackId, $targetStackId, $notifyEmail, $enabled);
$this->applyFields($workflow, $title, $boardId, $sourceStackId, $targetStackId, $notifyMode, $enabled);
$workflow = $this->workflowMapper->insert($workflow);
return new DataResponse($workflow->jsonSerialize(), Http::STATUS_CREATED);
@@ -75,16 +76,16 @@ class WorkflowController extends OCSController {
int $boardId,
int $sourceStackId,
int $targetStackId,
bool $notifyEmail = false,
string $notifyMode = NotificationPolicy::MODE_OFF,
bool $enabled = true,
): DataResponse {
$workflow = $this->findOwnWorkflow($id);
$this->validate($title, $boardId, $sourceStackId, $targetStackId);
$this->validate($title, $boardId, $sourceStackId, $targetStackId, $notifyMode);
// Kept in step with the board owner so the job runs as, and mails,
// the right user; validate() made sure the editor owns the board.
$workflow->setUserId($this->currentUserId());
$this->applyFields($workflow, $title, $boardId, $sourceStackId, $targetStackId, $notifyEmail, $enabled);
$this->applyFields($workflow, $title, $boardId, $sourceStackId, $targetStackId, $notifyMode, $enabled);
$workflow = $this->workflowMapper->update($workflow);
return new DataResponse($workflow->jsonSerialize());
@@ -155,13 +156,16 @@ class WorkflowController extends OCSController {
}
}
private function validate(string $title, int $boardId, int $sourceStackId, int $targetStackId): void {
private function validate(string $title, int $boardId, int $sourceStackId, int $targetStackId, string $notifyMode): void {
if (trim($title) === '') {
throw new OCSBadRequestException('Title must not be empty');
}
if ($sourceStackId === $targetStackId) {
throw new OCSBadRequestException('Source and target stack must differ');
}
if (!NotificationPolicy::isValidMode($notifyMode)) {
throw new OCSBadRequestException('Notification mode must be one of: ' . implode(', ', NotificationPolicy::MODES));
}
// Reject references to boards or stacks that are gone (or were never
// the user's) instead of storing a workflow that can only fail later.
@@ -198,14 +202,14 @@ class WorkflowController extends OCSController {
int $boardId,
int $sourceStackId,
int $targetStackId,
bool $notifyEmail,
string $notifyMode,
bool $enabled,
): void {
$workflow->setTitle($title);
$workflow->setBoardId($boardId);
$workflow->setSourceStackId($sourceStackId);
$workflow->setTargetStackId($targetStackId);
$workflow->setNotifyEmail($notifyEmail);
$workflow->setNotifyMode($notifyMode);
$workflow->setEnabled($enabled);
}
}