The job was registered but never executed: `background-job:list` kept
showing last_run = 1970-01-01. It was marked TIME_INSENSITIVE, and
OC\Core\Service\CronService::runCli() reads `maintenance_window_start` and
calls jobList->getNext($onlyTimeSensitive = true) whenever the current UTC
hour is outside [start, start+4] -- so with a maintenance window configured,
time-insensitive jobs are skipped for the other 20 hours of the day.
A job whose entire purpose is a 5-minute (now configurable down to 60s)
reaction time is time-sensitive by definition.
Also fix the occ invocation in README.md and CLAUDE.md: background-job:worker
takes job classes, not an app id, so the documented
`background-job:worker workflow_deck_automation` matched nothing.
- Boards: BoardService::getUserBoards() defaults to $includeArchived = true,
and that flag also gates the `deleted_at = 0` condition, so archived and
trashed boards showed up in the dropdown. Request the filtered query
instead, with a fallback to the no-arg call if the signature ever changes.
Stacks need nothing: StackMapper::findAll() always filters deleted_at.
- Each stack dropdown now hides whatever the other one holds, so source and
target can no longer be set to the same stack. The save-time check stays
as the backstop for rows stored before this rule.
- RunWorkflowsJob reads its interval from config.php
('workflow_deck_automation.interval', seconds, default 300, clamped to a
60s minimum). TimedJob re-reads the interval on every cron pass, so a
changed value takes effect without any occ command.
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>