Handle workflows whose board or stack was deleted
Build package / php-lint (8.2) (push) Successful in 49s
Build package / php-lint (8.3) (push) Successful in 45s
Build package / php-lint (8.4) (push) Successful in 44s
Build package / xml-lint (push) Successful in 13s
Build package / unit-tests (push) Successful in 45s
Build package / package (push) Successful in 1m3s
Build package / php-lint (8.2) (push) Successful in 49s
Build package / php-lint (8.3) (push) Successful in 45s
Build package / php-lint (8.4) (push) Successful in 44s
Build package / xml-lint (push) Successful in 13s
Build package / unit-tests (push) Successful in 45s
Build package / package (push) Successful in 1m3s
Deleting a board or stack left the workflow row pointing at nothing: Deck keeps the orphaned cards readable until its DeleteCron purges them, so the run kept failing on the move every few minutes, silently and forever. - The controller now rejects boards and stacks that do not exist (or are not the user's) on create and update, so no new broken row can be stored. - The settings list marks affected workflows in red instead of showing a row that looks healthy. - The background job disables such a workflow and mails its owner once. The mail ignores the notifyEmail flag: that one is about moved cards, this is a notice that the automation stopped. It stays a one-off because a disabled workflow is no longer picked up. The check deliberately goes through StackService::findAll() rather than BoardService::getUserBoards(): Deck injects the current user into BoardService as a string frozen at construction, so in the job -- one process, many users, a cached BoardService -- it would answer for the wrong user or for none, and every workflow on the instance would have been disabled. findStackIds() returns null only for a genuinely missing or forbidden board and throws for anything else, so a Deck outage skips the workflow instead of killing it.
This commit is contained in:
@@ -59,7 +59,7 @@ class WorkflowController extends OCSController {
|
||||
bool $notifyEmail = false,
|
||||
bool $enabled = true,
|
||||
): DataResponse {
|
||||
$this->validate($title, $sourceStackId, $targetStackId);
|
||||
$this->validate($title, $boardId, $sourceStackId, $targetStackId);
|
||||
|
||||
$workflow = new Workflow();
|
||||
$workflow->setUserId($this->currentUserId());
|
||||
@@ -85,7 +85,7 @@ class WorkflowController extends OCSController {
|
||||
bool $notifyEmail = false,
|
||||
bool $enabled = true,
|
||||
): DataResponse {
|
||||
$this->validate($title, $sourceStackId, $targetStackId);
|
||||
$this->validate($title, $boardId, $sourceStackId, $targetStackId);
|
||||
|
||||
try {
|
||||
$workflow = $this->workflowMapper->findForUser($id, $this->currentUserId());
|
||||
@@ -147,13 +147,35 @@ class WorkflowController extends OCSController {
|
||||
}
|
||||
}
|
||||
|
||||
private function validate(string $title, int $sourceStackId, int $targetStackId): void {
|
||||
private function validate(string $title, int $boardId, int $sourceStackId, int $targetStackId): void {
|
||||
if (trim($title) === '') {
|
||||
throw new OCSBadRequestException('Title must not be empty');
|
||||
}
|
||||
if ($sourceStackId === $targetStackId) {
|
||||
throw new OCSBadRequestException('Source and target stack must differ');
|
||||
}
|
||||
|
||||
// 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.
|
||||
// assertDeck() ran first, so an empty list here means "not there",
|
||||
// not "Deck is unreachable".
|
||||
$this->assertDeck();
|
||||
|
||||
$boardIds = array_map(
|
||||
static fn (array $board) => (int)$board['id'],
|
||||
$this->deckService->listBoardsForCurrentUser(),
|
||||
);
|
||||
if (!in_array($boardId, $boardIds, true)) {
|
||||
throw new OCSBadRequestException('The selected board does not exist or is not accessible');
|
||||
}
|
||||
|
||||
$stackIds = array_map(
|
||||
static fn (array $stack) => (int)$stack['id'],
|
||||
$this->deckService->listStacks($boardId),
|
||||
);
|
||||
if (!in_array($sourceStackId, $stackIds, true) || !in_array($targetStackId, $stackIds, true)) {
|
||||
throw new OCSBadRequestException('The selected stack does not exist on this board');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user