Skip to content

fix: track and subscribe inline assignees when work items are created via the external API - #9450

Open
stella-nova wants to merge 2 commits into
makeplane:previewfrom
stella-nova:fix/create-issue-activity-assignees-key
Open

fix: track and subscribe inline assignees when work items are created via the external API#9450
stella-nova wants to merge 2 commits into
makeplane:previewfrom
stella-nova:fix/create-issue-activity-assignees-key

Conversation

@stella-nova

@stella-nova stella-nova commented Jul 20, 2026

Copy link
Copy Markdown

Description

create_issue_activity only runs track_assignees when the create payload contains assignee_ids (the web app field name). Work items created through the external REST API (/api/v1/...) carry assignees instead, so inline assignees on create produce no assignee activity and are never auto-subscribed to the work item — meaning they get no notification for the assignment or for any later change. Assigning in a separate PATCH afterwards works, because the update path maps both field names to track_assignees, and track_assignees itself already reads both keys via extract_ids(requested_data, "assignee_ids", "assignees"). Only the create gate misses the external API key.

This PR accepts both assignee_ids and assignees in the create gate in apps/api/plane/bgtasks/issue_activities_task.py.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)

Test Scenarios

Unit tests added in plane/tests/unit/bg_tasks/test_issue_activities_task.py: creating with assignee_ids, creating with assignees (both must track the assignee activity and create the IssueSubscriber), and creating without assignees (no activities collected, no subscription, the "created" activity still recorded). Ran against PostgreSQL: 3 passed. Verified red/green: on the unpatched task exactly the assignees test fails. ruff check clean.

References

Fixes #9449.

Summary by CodeRabbit

  • Bug Fixes
    • Issue creation now correctly tracks assignees and creates subscriptions when assignees are provided through either supported API format.
    • Issues created without assignees no longer generate unnecessary assignee activity or subscriptions.
    • Issue activity creation now handles missing, empty, or invalid assignment data safely.

…ssue creation

create_issue_activity only ran track_assignees when the payload contained
assignee_ids (the web app field name). Work items created through the external
REST API (/api/v1/...) carry assignees instead, so inline assignees on create
produced no assignee activity and were never auto-subscribed to the work item -
meaning they got no notification for the assignment or any later change.
track_assignees itself already reads both keys via extract_ids, as does the
update path (both field names are mapped); only the create gate was missing
the external API key.

Accept both assignee_ids and assignees in the create gate.

Unit tests added for both payload shapes and the no-assignees case.
@CLAassistant

CLAassistant commented Jul 20, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: cfd7e5c0-1b94-4929-b894-35201df2cfcd

📥 Commits

Reviewing files that changed from the base of the PR and between aba2118 and 81eb686.

📒 Files selected for processing (2)
  • apps/api/plane/bgtasks/issue_activities_task.py
  • apps/api/plane/tests/unit/bg_tasks/test_issue_activities_task.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/api/plane/bgtasks/issue_activities_task.py

Included review availability: Your plan includes up to 10 reviews per rolling hour; 9 remain after this review.


📝 Walkthrough

Walkthrough

The create activity task now supports both assignee_ids and assignees payloads. It also skips invalid payload types safely. Unit tests cover activity creation, assignee tracking, subscriptions, and invalid inputs.

Changes

Assignee activity tracking

Layer / File(s) Summary
Accept both assignee payload keys
apps/api/plane/bgtasks/issue_activities_task.py
The task validates requested_data before access and invokes assignee tracking for both assignee_ids and assignees.
Validate activity and subscription outcomes
apps/api/plane/tests/unit/bg_tasks/test_issue_activities_task.py
Fixtures and tests cover both payload keys, missing assignees, None, and non-dictionary payloads. Invalid or missing assignee data still records the created activity without assignee activities or subscriptions.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to 81eb6

This localized fix enables inline assignees created through the external API to receive assignment activity and subscriptions, with targeted tests covering the affected paths; no actionable merge-blocking risk remains after normal checks and review.

Suggested reviewers: dheeru0198, pablohashescobar

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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 fix for tracking and subscribing inline assignees created through the external API.
Description check ✅ Passed The description includes the change, bug-fix classification, test scenarios, validation results, and linked issue reference.
Linked Issues check ✅ Passed The changes satisfy issue #9449 by supporting assignees during creation, preserving activity tracking, subscriptions, and notifications.
Out of Scope Changes check ✅ Passed The implementation and tests remain within the linked issue scope and address payload safety required by the create path.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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
Contributor

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)
apps/api/plane/tests/unit/bg_tasks/test_issue_activities_task.py (1)

110-117: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Test the None payload scenario.

To prevent regressions and ensure the background task handles null payloads gracefully without crashing, consider adding a test case where requested_data is explicitly None.

💡 Proposed test case
    `@pytest.mark.django_db`
    def test_create_with_none_payload_creates_only_created_activity(self, workspace, project, issue, author):
        """Null payload: no crash, only 'created' activity is logged."""
        activities = self._run(issue, project, workspace, author, None)

        assert activities == []
        assert not IssueSubscriber.objects.filter(issue_id=issue.id).exists()
        assert IssueActivity.objects.filter(issue_id=issue.id, verb="created").exists()
🤖 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 `@apps/api/plane/tests/unit/bg_tasks/test_issue_activities_task.py` around
lines 110 - 117, Add a test alongside
test_create_without_assignees_only_creates_created_activity that calls _run with
requested_data=None, then assert it completes without error, returns no
additional activities, creates no IssueSubscriber record, and records only the
created IssueActivity.
🤖 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 `@apps/api/plane/bgtasks/issue_activities_task.py`:
- Line 581: Update the assignee-tracking condition around requested_data to
first verify that requested_data is a dictionary before calling .get(). When it
is None or parses as a JSON array or other non-dictionary type, skip assignee
tracking without raising an AttributeError.

---

Nitpick comments:
In `@apps/api/plane/tests/unit/bg_tasks/test_issue_activities_task.py`:
- Around line 110-117: Add a test alongside
test_create_without_assignees_only_creates_created_activity that calls _run with
requested_data=None, then assert it completes without error, returns no
additional activities, creates no IssueSubscriber record, and records only the
created IssueActivity.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: d7c696ee-8a38-4d59-b4c1-0cae7c81f18b

📥 Commits

Reviewing files that changed from the base of the PR and between 7cef741 and aba2118.

📒 Files selected for processing (2)
  • apps/api/plane/bgtasks/issue_activities_task.py
  • apps/api/plane/tests/unit/bg_tasks/test_issue_activities_task.py

Comment thread apps/api/plane/bgtasks/issue_activities_task.py Outdated
…ict payloads

The assignee gate called .get() directly on requested_data, which the line
above explicitly allows to be None (and which parses to a list when the
payload is a JSON array). Both cases raised AttributeError and crashed the
background task before the assignee tracking ever ran.

Check isinstance(requested_data, dict) before the .get() calls so an absent
or non-object payload simply skips assignee tracking.

Unit tests added for the None payload and the JSON-array payload; both fail
with AttributeError without the guard.

Addresses CodeRabbit review feedback on makeplane#9450.
@stella-nova

Copy link
Copy Markdown
Author

Addressed the CodeRabbit review feedback in 81eb686: create_issue_activity now checks isinstance(requested_data, dict) before the .get() calls, so a None payload (explicitly allowed by the preceding line) or a payload parsing to a JSON array skips assignee tracking instead of raising AttributeError. Added unit tests for both cases; they fail with AttributeError without the guard. Full file suite green (5 passed), ruff check/format clean.

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.

🐛 Bug: Work items created via the external API with inline assignees never subscribe or notify the assignees

2 participants