Skip to content

MM-69627: Add beta task requirements for checklist items - #2381

Open
asaadmahmood wants to merge 1 commit into
masterfrom
MM-69627-task-requirements
Open

MM-69627: Add beta task requirements for checklist items#2381
asaadmahmood wants to merge 1 commit into
masterfrom
MM-69627-task-requirements

Conversation

@asaadmahmood

Copy link
Copy Markdown
Contributor

Summary

  • Adds task requirements so playbook authors can define required text fields on checklist items, collect values when checking off a task during a run, and review saved values in a collapsed accordion.
  • Gates the feature behind a System Console Beta Features setting (Task requirements).
  • Includes server validation on checkoff-to-closed, GraphQL/type updates, and unit tests for beta config, accordion, and fill modal.

Jira: https://mattermost.atlassian.net/browse/MM-69627

Test plan

  • Enable System Console → Plugins → Playbooks → Beta Features → Task requirements
  • In a playbook editor, open a task’s More menu and add one or more requirements; confirm labels appear in the accordion
  • Edit and remove requirements; confirm playbook save persists them
  • Start a run, check off a task with requirements; confirm fill modal appears
  • Save with partial values keeps the task open and shows values under the task
  • Save and mark complete requires all fields and marks the task complete when filled
  • With beta feature disabled, confirm Add/Edit requirements UI is hidden and checkoff does not require values
  • Run make check-style and relevant unit tests (go test + webapp jest for requirements/beta)

Made with Cursor

Allow playbook authors to define required text fields on tasks, collect
values at checkoff during a run, and gate the feature behind System Console
beta settings.

Co-authored-by: Cursor <cursoragent@cursor.com>
@mattermost-build

Copy link
Copy Markdown
Contributor

Test check 2e67666 — action needed

PR adds good tests for 5 of 7 new components/behaviours, but EditRequirementsModal (a non-trivial form component) has no tests, and the critical server-side validation in ModifyCheckedState (enforcing all requirement values before close) is entirely untested.
Add unit tests for EditRequirementsModal covering add/remove/save logic, and add server-side unit tests for ModifyCheckedState covering the empty-value rejection path, beta-flag-disabled bypass, and requirements-only-save (no state change) path.

More details (truncated)
Test Files Detected
Category Count Files
Unit 5 server/app/task_requirements_test.go, server/config/beta_features_test.go, webapp/src/components/backstage/beta_features_setting.test.tsx, webapp/src/components/checklist_item/fill_requirements_modal.test.tsx, webapp/src/components/checklist_item/requirements_accordion.test.tsx
Integration 0
E2E 0
Stub update 1 server/app/permissions_service_test.go (interface signature update only)
Modified 1 webapp/src/components/checklist_item/checklist_item.test.tsx (mock added)
Analysis

Well-covered areas:

  1. Beta config (IsTaskRequirementsEnabled, BetaFeaturesConfig, serialize)server/config/beta_features_test.go covers disabled-by-default, enabled path, and serialisation.
  2. GetChecklistItemUpdates with requirementsserver/app/task_requirements_test.go covers changed and unchanged requirement values triggering (or not triggering) update entries.
  3. BetaFeaturesSetting componentbeta_features_setting.test.tsx covers collapsed rendering and expand-then-toggle interaction.
  4. FillRequirementsModalfill_requirements_modal.test.tsx covers partial save, save-and-complete with validation errors, and successful save-and-complete.
  5. RequirementsAccordionrequirements_accordion.test.tsx covers empty list (null render), Complete button visibility when no values filled, and Edit button visibility when any field is filled.

Notable gaps:

  1. EditRequirementsModal — no tests at all. This is a new, interactive form component with non-trivial logic: initialising from existing requirements vs. starting fresh, adding/removing draft fields, the removeField guard that keeps at least one empty row, and the handleSave that preserves existing values for retained IDs. None of this is tested.

  2. ModifyCheckedState server validation — no unit tests. The most important new server-side business rule is that all requirement values must be non-empty when newState == ChecklistItemStateClosed and the beta flag is on. There are no tests exercising:

    • Rejection when any requirement value is empty (the error path returning ErrMalformedPlaybookRun).
    • Saving requirement values without changing state (requirementsChanged path).
    • Idempotency when state and requirements are both unchanged.
    • Behaviour when t

...truncated. View full analysis details

Suggestions

  1. Add unit tests for EditRequirementsModal (e.g., edit_requirements_modal.test.tsx): test initial empty state adds one blank row, adding another field, removing a field, the "keep at least one row" guard, canSave logic (requires at least one label when not editing), and that handleSave preserves existing values for unchanged IDs.
  2. Add unit/integration tests for ModifyCheckedState with requirements in server/app/playbook_run_service_test.go (or a new file):
    • Calling with ChecklistItemStateClosed, requirements present, one empty value → expect ErrMalformedPlaybookRun when beta flag enabled.
    • Same scenario with beta flag disabled → expect success.
    • Calling with non-nil RequirementValues but no state change → expect values persisted, no timeline event created.
    • Calling with all values filled → expect success and timeline event created.
  3. Add a test for CheckBoxButton reverting on cancelled: true in inputs.tsx.

To override, comment /test-analysis-override <reason> after verifying tests are adequate or not required.

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds task requirements to playbook checklist data, GraphQL contracts, beta-feature settings, run-state APIs, server validation, and the web checklist interface for defining, viewing, editing, and completing requirements.

Changes

Task requirements

Layer / File(s) Summary
Contracts and beta configuration
client/playbook.go, client/settings.go, server/app/playbook.go, server/api/schema.graphqls, server/config/*, server/api/settings.go, webapp/src/types/settings.ts
Adds requirement data types and fields, GraphQL input/output definitions, beta-feature configuration, configuration serialization, and global settings propagation.
Run state and requirement value updates
server/app/playbook_run.go, server/app/playbook_run_service.go, server/api/playbook_runs.go, server/app/permissions_service_test.go, server/app/task_requirements_test.go
Accepts requirement values during checklist state changes, validates completion values when enabled, tracks requirement changes, and limits persistence and timeline events to actual state changes.
Beta feature administration
plugin.json, webapp/src/components/backstage/beta_features_setting.tsx, webapp/src/components/backstage/beta_features_setting.test.tsx, webapp/src/index.tsx, webapp/src/selectors.ts, webapp/src/client.ts
Registers the BetaFeatures console setting, exposes the task-requirements selector, and includes requirement values in checklist state requests.
Checklist requirement editing and completion
webapp/src/components/checklist_item/*, webapp/src/components/checklist/*, webapp/src/graphql/playbook.graphql, webapp/src/types/playbook.ts
Loads and preserves requirements, provides accordion and modal interfaces for editing and filling values, intercepts completion when values are required, and tests the new UI behaviours.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Admin
  participant BetaFeaturesSetting
  participant GlobalSettings
  participant ChecklistItem
  participant FillRequirementsModal
  participant PlaybookRunAPI
  Admin->>BetaFeaturesSetting: enable task_requirements
  BetaFeaturesSetting->>GlobalSettings: save BetaFeatures
  GlobalSettings->>ChecklistItem: expose enabled setting
  ChecklistItem->>FillRequirementsModal: request requirement values
  FillRequirementsModal->>PlaybookRunAPI: submit state and requirement_values
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.11% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding beta-gated task requirements for checklist items.
Description check ✅ Passed The description matches the changeset and covers the feature, gating, validation, and tests.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch MM-69627-task-requirements

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
webapp/src/components/checklist_item/checklist_item.test.tsx (1)

35-37: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Cover the beta-enabled checklist flow.

This fixed false mock prevents this suite from testing requirement modal interception and value submission. Add a true selector case covering checkbox completion and onChange(Closed, values).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@webapp/src/components/checklist_item/checklist_item.test.tsx` around lines 35
- 37, Update the useAppSelector mock in the checklist item test suite to support
a beta-enabled true case, then add coverage for checkbox completion that
verifies requirement modal interception and invokes onChange with Closed and the
submitted values. Preserve the existing false-selector coverage.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@webapp/src/components/checklist_item/fill_requirements_modal.tsx`:
- Around line 19-20: Update fill_requirements_modal.tsx at lines 19-20 and 62-72
so the save callbacks return and await the asynchronous update result, retaining
the modal when the save fails. In checklist_item.tsx lines 733-742, return the
onChange promise and only close/reset the modal after the response succeeds.

---

Nitpick comments:
In `@webapp/src/components/checklist_item/checklist_item.test.tsx`:
- Around line 35-37: Update the useAppSelector mock in the checklist item test
suite to support a beta-enabled true case, then add coverage for checkbox
completion that verifies requirement modal interception and invokes onChange
with Closed and the submitted values. Preserve the existing false-selector
coverage.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 1142e82e-1196-4f72-83b8-204a033ec04f

📥 Commits

Reviewing files that changed from the base of the PR and between 8adcf41 and 2e67666.

⛔ Files ignored due to path filters (2)
  • webapp/src/graphql/generated/gql.ts is excluded by !**/generated/**
  • webapp/src/graphql/generated/graphql.ts is excluded by !**/generated/**
📒 Files selected for processing (35)
  • client/playbook.go
  • client/settings.go
  • plugin.json
  • server/api/graphql_playbook.go
  • server/api/playbook_runs.go
  • server/api/schema.graphqls
  • server/api/settings.go
  • server/app/permissions_service_test.go
  • server/app/playbook.go
  • server/app/playbook_run.go
  • server/app/playbook_run_service.go
  • server/app/task_requirements_test.go
  • server/config/beta_features_test.go
  • server/config/config.go
  • server/config/configuration.go
  • server/config/service.go
  • webapp/src/client.ts
  • webapp/src/components/backstage/beta_features_setting.test.tsx
  • webapp/src/components/backstage/beta_features_setting.tsx
  • webapp/src/components/checklist/checklist_list.tsx
  • webapp/src/components/checklist_item/checklist_item.test.tsx
  • webapp/src/components/checklist_item/checklist_item.tsx
  • webapp/src/components/checklist_item/checklist_item_draggable.tsx
  • webapp/src/components/checklist_item/edit_requirements_modal.tsx
  • webapp/src/components/checklist_item/fill_requirements_modal.test.tsx
  • webapp/src/components/checklist_item/fill_requirements_modal.tsx
  • webapp/src/components/checklist_item/hover_menu.tsx
  • webapp/src/components/checklist_item/inputs.tsx
  • webapp/src/components/checklist_item/requirements_accordion.test.tsx
  • webapp/src/components/checklist_item/requirements_accordion.tsx
  • webapp/src/graphql/playbook.graphql
  • webapp/src/index.tsx
  • webapp/src/selectors.ts
  • webapp/src/types/playbook.ts
  • webapp/src/types/settings.ts

Comment on lines +19 to +20
onSave: (values: Record<string, string>) => void;
onSaveAndComplete: (values: Record<string, string>) => void;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Propagate requirement-save errors before dismissing the modal. The callback contract discards the result of setChecklistItemState, while the parent closes immediately; failed saves silently lose the user’s work.

  • webapp/src/components/checklist_item/fill_requirements_modal.tsx#L19-L20: type save callbacks to return the asynchronous update result.
  • webapp/src/components/checklist_item/fill_requirements_modal.tsx#L62-L72: await that result and keep the modal available on failure.
  • webapp/src/components/checklist_item/checklist_item.tsx#L733-L742: return the onChange promise and close/reset only after a successful response.
📍 Affects 2 files
  • webapp/src/components/checklist_item/fill_requirements_modal.tsx#L19-L20 (this comment)
  • webapp/src/components/checklist_item/fill_requirements_modal.tsx#L62-L72
  • webapp/src/components/checklist_item/checklist_item.tsx#L733-L742
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@webapp/src/components/checklist_item/fill_requirements_modal.tsx` around
lines 19 - 20, Update fill_requirements_modal.tsx at lines 19-20 and 62-72 so
the save callbacks return and await the asynchronous update result, retaining
the modal when the save fails. In checklist_item.tsx lines 733-742, return the
onChange promise and only close/reset the modal after the response succeeds.

@Willyfrog Willyfrog left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not doing a full review, I was just curious on the accordion element. I left a comment on it

);
};

const Accordion = styled.div`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really like this, but I wonder if this shouldn't be done by Mattermost's main repo and make it available for plugins

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally in the future we can just have it as a common component and export it. But I don't want this to pause this update.

@asaadmahmood
asaadmahmood requested a review from Willyfrog July 29, 2026 10:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants