main ← major_update
merged 06:17PM - 18 Feb 26 UTC
## Summary
This PR is a broad workflow plugin hardening and capability rele…ase that improves discovery UX, overdue handling, topic action clarity, admin editing safety, and test coverage.
It introduces a configurable overdue model with hierarchy (step -> workflow -> global), converts quick filters to SPA behavior, adds explicit overdue visibility in the workflow list, enriches topic workflow metadata for UI behavior, and fixes several correctness/maintainability issues.
## New Features
### 1. Overdue threshold hierarchy with disable semantics
- Added global site setting:
- `workflow_overdue_days_default` (`config/settings.yml`)
- Added optional workflow-level override:
- `workflows.overdue_days`
- Added optional step-level override:
- `workflow_steps.overdue_days`
- Resolution order:
- step `overdue_days` -> workflow `overdue_days` -> global setting
- `0` disables overdue behavior at that scope.
### 2. Overdue quick filter behavior
- Added dedicated quick-filter mode `overdue=1` that uses the hierarchy above.
- Legacy `overdue_days=N` filtering still works for explicit manual param filtering.
- Quick filter button now maps to semantic overdue mode rather than fixed 3-day value.
### 3. Workflow list overdue indicator column
- Added workflow topic list column to show overdue state.
- Added serialized topic-list attribute:
- `workflow_overdue`
- Added indicator styling and translations.
### 4. SPA quick filters (no full reload)
- Quick filters now use in-app Ember route query-param transitions.
- Added discovery query params for workflow filters.
- Preserved filter state in localStorage.
- Fixed stale state/UI refresh issues by deriving from reactive route URL.
- Added full toggle behavior and active-state highlighting for:
- My Categories
- Overdue
- Step filter (Step = X now toggles off when applied again).
### 5. Topic workflow banner/action enhancements
- Moved topic banner connector to `topic-above-post-stream`.
- Added workflow step action metadata with target step details.
- Added permission-aware UI state (`workflow_can_act`).
- Added step age (`workflow_step_entered_at`) display support.
- Added helper text for transition targets and blocked-action messaging.
### 6. Admin workflow editing improvements
- Workflow editor surfaces definition validation warnings:
- duplicate step positions
- orphan target steps
- missing option label translations
- Added admin inputs for overdue overrides:
- workflow-level overdue days
- step-level overdue days
### 7. Reliability and correctness fixes
- Added transition cooldown to prevent immediate duplicate actions.
- Transition log message now includes source and destination steps.
- Topic-created workflow state initialization now targets enabled workflows only.
- Midway-topic validator now checks only enabled workflows.
- Notification handler now limits arrival notifications to:
- first post only
- watchers of the topic’s category
- Fixed stats association use (`workflow_states`).
- Fixed admin route key/path assumptions in workflow step option routes.
- Fixed workflow step option position assignment bug.
- Updated seeded option slugs/names (`poor` -> `bad`, `previous` -> `back`).
## Technical Changes
### Data model / migration
- Added migration:
- `db/migrate/20260218103000_add_overdue_days_to_workflows_and_steps.rb`
- Added model validations on new fields (`>= 0`, integer, allow nil).
### Backend
- ListController workflow filtering now supports:
- `my_categories`
- `workflow_step_position`
- overdue via hierarchy (`overdue=1`) and explicit days fallback.
- `plugin.rb` adds:
- workflow action metadata
- overdue threshold resolution
- overdue boolean serialization
- can-act and step-entered-at serialization.
### Frontend
- Added connector:
- `assets/javascripts/discourse/connectors/discovery-list-container-top/workflow-quick-filters.gjs`
- Added connector:
- `assets/javascripts/discourse/connectors/topic-above-post-stream/workflow-topic-banner.gjs`
- Removed old connector:
- `assets/javascripts/discourse/connectors/topic-title/topic-title.hbs`
- Extended discovery columns via initializer:
- overdue column + registration of workflow query params.
### Localization and docs
- Added/updated client and server locale keys for:
- overdue setting/help text
- overdue indicator
- quick filter labels
- admin overdue override labels/help
- improved transition action descriptions.
- README restructured with:
- Introduction (+ Wikipedia links)
- Features
- Quickstart
- Setup
- Introductory Concepts
- Roadmap Themes
- Existing content preserved and reorganized.
- Plugin version updated:
- `plugin.rb`: `0.2.0`
## New Tests
### Request specs
- `workflow_overdue_thresholds_spec.rb`
- validates overdue hierarchy precedence and `0` disable behavior
- validates `workflow_overdue` payload values
- `workflow_list_filters_spec.rb`
- `workflow_action_controller_spec.rb`
- `workflow_topic_view_spec.rb`
- `admin/workflow_step_options_controller_spec.rb`
### System specs (+ page objects)
- `workflow_quick_filters_spec.rb`
- query-param filtering
- control-driven filtering
- no full page reload regression
- active-state/toggle behavior
- overdue column presence/indicator assertions
- `workflow_topic_banner_spec.rb`
- `page_objects/pages/workflow_discovery.rb`
- `page_objects/pages/workflow_topic.rb`
- serializer/warnings/slug stability/topic lifecycle/post notification/stats/route contract/option seed parity/transition coverage.
## Validation Run
- Full plugin specs pass:
- `bin/rspec plugins/discourse-workflow/spec`
- result: 36 examples, 0 failures
- Lint/format checks passed for touched files:
- Rubocop
- ESLint
- Ember template lint
- Stylelint
- Prettier checks for updated docs/config/locales
## Migration / rollout notes
- Run plugin migrations in dev/test
- Set `workflow_overdue_days_default` as desired (`0` disables global overdue).
- Existing explicit `overdue_days` query usage remains supported.