- 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>