fix: activity tracking description#8268
Conversation
…ue activity tracking
… during partial updates
…ng-description' into fix-activity-tracking-description
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. WalkthroughEditor transactions mark unique-id-only edits, the editor hook surfaces this as isMigrationUpdate, UI components propagate it through DescriptionInput submit, frontend sends Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Editor as RichTextEditor
participant Hook as use-editor
participant Component as DescriptionInput
participant API as Frontend API Client
participant Backend as Intake/Issue Handler
User->>Editor: Edit description (unique-id-only change)
Editor->>Editor: tr.setMeta("uniqueIdOnlyChange", true)
Editor->>Hook: onUpdate(editor, transaction)
Hook->>Hook: read transaction.getMeta("uniqueIdOnlyChange")
Hook->>Component: onChange(json, html, {isMigrationUpdate: true})
Component->>Component: setValue("isMigrationUpdate", true)
Component->>Component: Debounced save or submit
Component->>API: PATCH /issue (description_html, skip_activity: "true")
API->>Backend: Deliver payload
Backend->>Backend: skip_activity = request.data.get("skip_activity")
Backend->>Backend: is_description_update = presence of description_html
alt skip_activity AND is_description_update
Backend->>Backend: Do not enqueue activity or description-version tasks
else
Backend->>Backend: Enqueue normal activity and version tasks
end
Backend->>API: Return updated resource
API->>Component: Success response
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
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. Comment |
There was a problem hiding this comment.
Pull request overview
This pull request aims to prevent activity logs from being generated for migration-only updates to issue descriptions (specifically when unique IDs are added to editor content). The implementation tracks migration updates through the editor's transaction metadata and passes this information to the backend to conditionally skip activity logging.
Critical Issues Found: The PR contains several critical bugs that prevent it from working as intended:
- Parameter name mismatch between frontend (
no_activity) and backend (skip_activity) - Invalid TypeScript syntax in the editor type definition
- Logic errors in both backend views using OR instead of AND, which will cause incorrect behavior
Key Changes
- Added
isMigrationUpdateflag propagation from editor to API calls - Modified backend views to conditionally skip activity logging based on
skip_activityflag - Updated editor onChange signature to include migration update metadata
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/editor/src/core/types/editor.ts | Added optional third parameter to onChange callback for migration metadata (has syntax error) |
| packages/editor/src/core/hooks/use-editor.ts | Detects migration updates via transaction metadata and passes to onChange |
| packages/editor/src/core/extensions/unique-id/utils.ts | Sets metadata flag to identify unique-id-only changes |
| apps/web/core/components/editor/rich-text/description-input/root.tsx | Captures and forwards isMigrationUpdate flag through form handling |
| apps/web/core/components/issues/peek-overview/issue-detail.tsx | Passes migration flag to API with incorrect parameter name |
| apps/web/core/components/issues/issue-detail/main-content.tsx | Passes migration flag to API with incorrect parameter name |
| apps/web/core/components/inbox/content/issue-root.tsx | Passes migration flag to API with incorrect parameter name |
| apps/api/plane/app/views/issue/base.py | Conditionally skips activity logging (has logic error) |
| apps/api/plane/app/views/intake/base.py | Conditionally skips activity logging (has logic error) |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (!issue.id || !issue.project_id) return; | ||
| await issueOperations.update(workspaceSlug, issue.project_id, issue.id, { | ||
| description_html: value, | ||
| ...(isMigrationUpdate ? { no_activity: "true" } : {}), |
There was a problem hiding this comment.
Parameter name mismatch: the frontend sends no_activity but the backend expects skip_activity (see apps/api/plane/app/views/intake/base.py:325). This will cause the migration updates to still generate activity logs, defeating the purpose of this fix.
Change to:
...(isMigrationUpdate ? { skip_activity: true } : {}),| ...(isMigrationUpdate ? { no_activity: "true" } : {}), | |
| ...(isMigrationUpdate ? { skip_activity: true } : {}), |
| user_id=request.user.id, | ||
| ) | ||
|
|
||
| if not skip_activity or not is_description_update: |
There was a problem hiding this comment.
Logic error: the condition if not skip_activity or not is_description_update: uses OR when it should use AND. This will cause activity logging to occur for ALL non-description updates, even when skip_activity=True. The intention is to skip activity ONLY when both conditions are true (skip_activity AND is_description_update).
Change to:
if not (skip_activity and is_description_update):| if not skip_activity or not is_description_update: | |
| if not (skip_activity and is_description_update): |
| issue_id=str(pk), | ||
| user_id=request.user.id, | ||
| ) | ||
| if not skip_activity or not is_description_update: |
There was a problem hiding this comment.
Logic error: the condition if not skip_activity or not is_description_update: uses OR when it should use AND. This will cause activity logging to occur for ALL non-description updates, even when skip_activity=True. The intention is to skip activity ONLY when both conditions are true (skip_activity AND is_description_update).
Change to:
if not (skip_activity and is_description_update):| if not skip_activity or not is_description_update: | |
| if not (skip_activity and is_description_update): |
| onAssetChange?: (assets: TEditorAsset[]) => void; | ||
| onEditorFocus?: () => void; | ||
| onChange?: (json: object, html: string) => void; | ||
| onChange?: (json: object, html: string, { isMigrationUpdate }?: { isMigrationUpdate?: boolean }) => void; |
There was a problem hiding this comment.
Invalid TypeScript syntax for optional parameter. The destructured parameter syntax is incorrect. The correct syntax for an optional third parameter should be:
onChange?: (json: object, html: string, options?: { isMigrationUpdate?: boolean }) => void;The current syntax { isMigrationUpdate }?: { isMigrationUpdate?: boolean } is not valid TypeScript.
| onChange?: (json: object, html: string, { isMigrationUpdate }?: { isMigrationUpdate?: boolean }) => void; | |
| onChange?: (json: object, html: string, options?: { isMigrationUpdate?: boolean }) => void; |
| if (!issue.id || !issue.project_id) return; | ||
| await issueOperations.update(workspaceSlug, issue.project_id, issue.id, { | ||
| description_html: value, | ||
| ...(isMigrationUpdate ? { no_activity: "true" } : {}), |
There was a problem hiding this comment.
Parameter name mismatch: the frontend sends no_activity but the backend expects skip_activity (see apps/api/plane/app/views/issue/base.py:615). This will cause the migration updates to still generate activity logs, defeating the purpose of this fix.
Change to:
...(isMigrationUpdate ? { skip_activity: true } : {}),| ...(isMigrationUpdate ? { no_activity: "true" } : {}), | |
| ...(isMigrationUpdate ? { skip_activity: true } : {}), |
| if (!issue.id || !issue.project_id) return; | ||
| await issueOperations.update(workspaceSlug, issue.project_id, issue.id, { | ||
| description_html: value, | ||
| ...(isMigrationUpdate ? { no_activity: "true" } : {}), |
There was a problem hiding this comment.
Parameter name mismatch: the frontend sends no_activity but the backend expects skip_activity (see apps/api/plane/app/views/issue/base.py:615). This will cause the migration updates to still generate activity logs, defeating the purpose of this fix.
Change to:
...(isMigrationUpdate ? { skip_activity: true } : {}),| ...(isMigrationUpdate ? { no_activity: "true" } : {}), | |
| ...(isMigrationUpdate ? { skip_activity: true } : {}), |
There was a problem hiding this comment.
Actionable comments posted: 4
♻️ Duplicate comments (1)
apps/web/core/components/inbox/content/issue-root.tsx (1)
204-209: Keep payload semantics consistent with other description updatesThis
onSubmitchange mirrors the peek‑overview implementation: it forwardsisMigrationUpdateand conditionally addsno_activity: "true"to the update payload, which keeps behavior consistent across inbox and regular issue flows.Same as the other call site, please verify that
no_activityand its"true"value match what the backend expects for suppressing activity logs; if there’s already a canonical flag in use, this should align with it.
🧹 Nitpick comments (4)
apps/api/plane/app/views/intake/base.py (1)
325-326: Consider using.get()instead of.pop()forskip_activityto avoid side effects.Using
.pop()removes theskip_activitykey fromrequest.data, which could cause issues if the request data is accessed elsewhere in the codebase. Unless the removal is intentional (e.g., to prevent the field from being saved to the database), prefer.get()for reading values without modification.Apply this diff:
- skip_activity = request.data.pop("skip_activity", False) + skip_activity = request.data.get("skip_activity", False)apps/api/plane/app/views/issue/base.py (1)
615-616: Consider using.get()instead of.pop()forskip_activityto avoid side effects.Using
.pop()removes theskip_activitykey fromrequest.data, which could cause issues if the request data is accessed elsewhere. Unless the removal is intentional (e.g., to prevent the field from being saved to the database), prefer.get()for reading values without modification.Apply this diff:
- skip_activity = request.data.pop("skip_activity", False) + skip_activity = request.data.get("skip_activity", False)packages/editor/src/core/extensions/unique-id/utils.ts (1)
32-35: Good use of transaction metadata; consider guarding on actual changesTagging unique‑ID‑only transactions via
tr.setMeta("uniqueIdOnlyChange", true)is a clean way to drive the migration flag downstream.You might optionally tighten this a bit:
- Only mark the transaction (and dispatch) when there are actual ID updates, e.g.:
if (nodesWithoutId.length === 0) return; nodesWithoutId.forEach(...); tr.setMeta("addToHistory", false); tr.setMeta("uniqueIdOnlyChange", true); view.dispatch(tr);
- If this meta key will be shared elsewhere, consider extracting
"uniqueIdOnlyChange"to a shared constant to avoid typos.Both are non‑blocking polish items.
apps/web/core/components/editor/rich-text/description-input/root.tsx (1)
22-26: End‑to‑end migration flag plumbing through DescriptionInput looks soundThe way
isMigrationUpdateis introduced and propagated here is internally consistent:
TFormDataanduseFormdefault values initializeisMigrationUpdate: false, and the reset effect also clears it, so entities don’t inherit a staletrueflag.handleDescriptionFormSubmitcorrectly forwardsformData.isMigrationUpdateas the second argument toonSubmit, matching the updated prop type.- The
RichTextEditoronChangehandler updates the form field withoptions?.isMigrationUpdate ?? false, ensuring that autosave and unmount saves see the correct migration status for each transaction.This cleanly bridges the editor‑level meta into your submit pipeline without altering existing behavior for normal edits.
One optional future‑proofing idea: if you anticipate more flags later, you might eventually switch the second argument of
onSubmitto a small options object (e.g.{ isMigrationUpdate?: boolean }) to keep the call sites self‑describing, but that’s not necessary for this PR.Also applies to: 60-61, 109-113, 124-129, 135-135, 141-152, 215-218
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (9)
apps/api/plane/app/views/intake/base.py(2 hunks)apps/api/plane/app/views/issue/base.py(2 hunks)apps/web/core/components/editor/rich-text/description-input/root.tsx(6 hunks)apps/web/core/components/inbox/content/issue-root.tsx(1 hunks)apps/web/core/components/issues/issue-detail/main-content.tsx(1 hunks)apps/web/core/components/issues/peek-overview/issue-detail.tsx(1 hunks)packages/editor/src/core/extensions/unique-id/utils.ts(1 hunks)packages/editor/src/core/hooks/use-editor.ts(1 hunks)packages/editor/src/core/types/editor.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,mts,cts}
📄 CodeRabbit inference engine (.github/instructions/typescript.instructions.md)
**/*.{ts,tsx,mts,cts}: Useconsttype parameters for more precise literal inference in TypeScript 5.0+
Use thesatisfiesoperator to validate types without widening them
Leverage inferred type predicates to reduce the need for explicitisreturn types in filter/check functions
UseNoInfer<T>utility to block inference for specific type arguments when they should be determined by other arguments
Utilize narrowing inswitch(true)blocks for control flow analysis (TypeScript 5.3+)
Rely on narrowing from direct boolean comparisons for type guards
Trust preserved narrowing in closures when variables aren't modified after the check (TypeScript 5.4+)
Use constant indices to narrow object/array properties (TypeScript 5.5+)
Use standard ECMAScript decorators (Stage 3) instead of legacyexperimentalDecorators
Useusingdeclarations for explicit resource management with Disposable pattern instead of manual cleanup (TypeScript 5.2+)
Usewith { type: "json" }for import attributes; avoid deprecatedassertsyntax (TypeScript 5.3/5.8+)
Useimport typeexplicitly when importing types to ensure they are erased during compilation, respectingverbatimModuleSyntaxflag
Use.ts,.mts,.ctsextensions inimport typestatements (TypeScript 5.2+)
Useimport type { Type } from "mod" with { "resolution-mode": "import" }for specific module resolution contexts (TypeScript 5.3+)
Use new iterator methods (map, filter, etc.) if targeting modern environments (TypeScript 5.6+)
Utilize newSetmethods likeunion,intersection, etc., when available (TypeScript 5.5+)
UseObject.groupBy/Map.groupBystandard methods for grouping instead of external libraries (TypeScript 5.4+)
UsePromise.withResolvers()for creating promises with exposed resolve/reject functions (TypeScript 5.7+)
Use copying array methods (toSorted,toSpliced,with) for immutable array operations (TypeScript 5.2+)
Avoid accessing instance fields viasuperin classes (TypeScript 5....
Files:
packages/editor/src/core/extensions/unique-id/utils.tsapps/web/core/components/issues/issue-detail/main-content.tsxpackages/editor/src/core/types/editor.tspackages/editor/src/core/hooks/use-editor.tsapps/web/core/components/inbox/content/issue-root.tsxapps/web/core/components/editor/rich-text/description-input/root.tsxapps/web/core/components/issues/peek-overview/issue-detail.tsx
🧠 Learnings (2)
📚 Learning: 2025-06-16T07:23:39.497Z
Learnt from: vamsikrishnamathala
Repo: makeplane/plane PR: 7214
File: web/core/store/issue/helpers/base-issues.store.ts:117-117
Timestamp: 2025-06-16T07:23:39.497Z
Learning: In the updateIssueDates method of BaseIssuesStore (web/core/store/issue/helpers/base-issues.store.ts), the projectId parameter is intentionally made optional to support override implementations in subclasses. The base implementation requires projectId and includes an early return check, but making it optional allows derived classes to override the method with different parameter requirements.
Applied to files:
apps/web/core/components/inbox/content/issue-root.tsx
📚 Learning: 2025-10-10T13:25:14.810Z
Learnt from: gakshita
Repo: makeplane/plane PR: 7949
File: apps/web/core/components/issues/issue-modal/form.tsx:183-189
Timestamp: 2025-10-10T13:25:14.810Z
Learning: In `apps/web/core/components/issues/issue-modal/form.tsx`, the form reset effect uses a `dataResetProperties` dependency array prop (default: []) to give parent components explicit control over when the form resets. Do not suggest adding the `data` prop itself to the dependency array, as this would cause unwanted resets on every render when the data object reference changes, disrupting user input. The current pattern is intentional and allows the parent to trigger resets only when specific conditions are met.
Applied to files:
apps/web/core/components/editor/rich-text/description-input/root.tsx
🧬 Code graph analysis (5)
apps/web/core/components/issues/issue-detail/main-content.tsx (1)
apps/space/core/store/publish/publish.store.ts (1)
workspaceSlug(93-95)
apps/web/core/components/inbox/content/issue-root.tsx (1)
apps/space/core/store/publish/publish.store.ts (1)
workspaceSlug(93-95)
apps/api/plane/app/views/intake/base.py (1)
apps/api/plane/bgtasks/issue_activities_task.py (1)
issue_activity(1500-1600)
apps/web/core/components/issues/peek-overview/issue-detail.tsx (1)
apps/space/core/store/publish/publish.store.ts (1)
workspaceSlug(93-95)
apps/api/plane/app/views/issue/base.py (2)
apps/api/plane/bgtasks/issue_activities_task.py (1)
issue_activity(1500-1600)apps/api/plane/bgtasks/webhook_task.py (1)
model_activity(460-502)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: Agent
- GitHub Check: CodeQL analysis (javascript-typescript)
- GitHub Check: Build and lint web apps
- GitHub Check: Analyze (javascript)
🔇 Additional comments (2)
packages/editor/src/core/types/editor.ts (1)
163-163: onChange signature extension looks correct and backward‑compatibleThe added optional
{ isMigrationUpdate }third parameter matches howuseEditorand the rich text flow now pass migration metadata, while keeping existing two‑argument call sites valid.packages/editor/src/core/hooks/use-editor.ts (1)
83-87: Correct wiring of transaction meta into onChangeUsing
transaction.getMeta("uniqueIdOnlyChange") === trueto deriveisMigrationUpdateand passing it through as the third argument toonChangecleanly exposes migration‑only updates to consumers without breaking existing signatures.If you introduce more places that read/write this meta key, consider centralizing the
"uniqueIdOnlyChange"literal as a shared constant, but the current implementation is fine as‑is.
| onSubmit={async (value, isMigrationUpdate) => { | ||
| if (!issue.id || !issue.project_id) return; | ||
| await issueOperations.update(workspaceSlug, issue.project_id, issue.id, { | ||
| description_html: value, | ||
| ...(isMigrationUpdate ? { no_activity: "true" } : {}), | ||
| }); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
rg -n "no_activity" -SRepository: makeplane/plane
Length of output: 456
🏁 Script executed:
#!/bin/bash
rg -n "skip_activity" -SRepository: makeplane/plane
Length of output: 488
🏁 Script executed:
#!/bin/bash
# Search for issue operations/update patterns to understand payload structure
rg -n "issueOperations\.update|description_html" -S -A 3 -B 1Repository: makeplane/plane
Length of output: 50372
🏁 Script executed:
#!/bin/bash
# Check the exact backend logic for skip_activity in issue updates
sed -n '610,670p' apps/api/plane/app/views/issue/base.pyRepository: makeplane/plane
Length of output: 2688
🏁 Script executed:
#!/bin/bash
# Check intake view as well
sed -n '320,430p' apps/api/plane/app/views/intake/base.pyRepository: makeplane/plane
Length of output: 4883
Field name mismatch blocks activity suppression; rename no_activity to skip_activity
The handler sends no_activity: "true" but the backend's partial_update method (issue/base.py:615, intake/base.py:325) pops and checks for skip_activity. Because the field name does not match, the backend defaults skip_activity to False, causing activity to be logged on every migration update instead of suppressing it.
Additionally, the field is sent as a string "true" rather than a boolean. The backend's logic if not skip_activity or not is_description_update: expects a boolean value.
Rename no_activity to skip_activity and send it as a boolean (true instead of "true"):
...(isMigrationUpdate ? { skip_activity: true } : {}),
🤖 Prompt for AI Agents
In apps/web/core/components/issues/issue-detail/main-content.tsx around lines
137 to 142, the update payload uses the wrong field name and type for
suppressing activity: it sends no_activity: "true" but the backend expects
skip_activity as a boolean. Change the conditional payload to use skip_activity:
true (boolean) instead of no_activity: "true" so the backend's partial_update
logic correctly detects and respects activity suppression.
| onSubmit={async (value, isMigrationUpdate) => { | ||
| if (!issue.id || !issue.project_id) return; | ||
| await issueOperations.update(workspaceSlug, issue.project_id, issue.id, { | ||
| description_html: value, | ||
| ...(isMigrationUpdate ? { no_activity: "true" } : {}), | ||
| }); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# Search for no_activity usage patterns
rg -n "no_activity" -S --type-add 'web:tsx,ts' -t webRepository: makeplane/plane
Length of output: 207
🏁 Script executed:
# Search for skip_activity or similar alternative patterns
rg -n "skip_activity|skipActivity" -S --type-add 'web:tsx,ts' -t webRepository: makeplane/plane
Length of output: 207
🏁 Script executed:
# Search for issueOperations.update calls to see how no_activity is used
rg -B 2 -A 2 "issueOperations\.update" --type-add 'web:tsx,ts' -t webRepository: makeplane/plane
Length of output: 207
🏁 Script executed:
# Check the issueOperations definition to understand the update signature
fd -e ts -e tsx | xargs grep -l "issueOperations\s*=" | head -5Repository: makeplane/plane
Length of output: 484
🏁 Script executed:
# Search for no_activity without type restrictions
rg "no_activity" -nRepository: makeplane/plane
Length of output: 456
🏁 Script executed:
# Search for skip_activity or similar patterns
rg "skip_activity|skipActivity" -nRepository: makeplane/plane
Length of output: 488
🏁 Script executed:
# Search for issueOperations.update calls
rg "issueOperations\.update" -B 2 -A 2 -nRepository: makeplane/plane
Length of output: 15603
🏁 Script executed:
# Inspect the target file
cat -n apps/web/core/components/issues/peek-overview/issue-detail.tsx | head -150Repository: makeplane/plane
Length of output: 6562
🏁 Script executed:
# Search for issueOperations.update implementation to see how payload is sent
rg -n "const.*issueOperations.*=" --type-add 'web:tsx,ts,js' -A 5 | head -50Repository: makeplane/plane
Length of output: 4914
🏁 Script executed:
# Look for the update method definition in issue operations
fd -e ts -e tsx | xargs grep -l "update.*workspaceSlug.*projectId" | grep -i operationRepository: makeplane/plane
Length of output: 137
🏁 Script executed:
# Check for any API middleware or transformation
rg -n "no_activity|skip_activity" apps/web --type-add 'web:tsx,ts,js' -B 3 -A 3Repository: makeplane/plane
Length of output: 2378
🏁 Script executed:
# Get the full issueOperations definition from peek-overview/root.tsx
cat -n apps/web/core/components/issues/peek-overview/root.tsx | sed -n '63,150p'Repository: makeplane/plane
Length of output: 3922
🏁 Script executed:
# Search for the update method definition in issueOperations
rg -n "update.*async.*workspaceSlug" apps/web/core/components/issues/peek-overview/root.tsx -A 10Repository: makeplane/plane
Length of output: 587
🏁 Script executed:
# Look for API service or client that processes the update payload
rg -n "class.*IssueService|export.*function.*update" --type-add 'web:tsx,ts,js' apps/web/services -A 3Repository: makeplane/plane
Length of output: 116
🏁 Script executed:
# Find where issues.updateIssue is defined
rg -n "updateIssue.*async" --type-add 'web:tsx,ts,js' -A 5 | head -80Repository: makeplane/plane
Length of output: 7001
🏁 Script executed:
# Search for issues store/hook definition
rg -n "useIssues|issues.*useMemo" apps/web/core/components/issues/peek-overview/root.tsx -B 5 -A 3Repository: makeplane/plane
Length of output: 1158
🏁 Script executed:
# Find the actual store implementation
fd -type f -name "*.ts" -o -name "*.tsx" | xargs rg -l "updateIssue" | grep -E "store|hook" | head -5Repository: makeplane/plane
Length of output: 472
🏁 Script executed:
# Get the full updateIssue implementation from issue.store.ts
cat -n apps/web/core/store/issue/issue-details/issue.store.ts | sed -n '175,220p'Repository: makeplane/plane
Length of output: 2275
🏁 Script executed:
# Search for projectIssues service to see the actual API call
rg -n "projectIssues\." apps/web/core/store/issue/issue-details/issue.store.ts -B 2 -A 2Repository: makeplane/plane
Length of output: 41
🏁 Script executed:
# Find where projectIssues is instantiated/imported
rg -n "projectIssues" apps/web/core/store/issue/issue-details/issue.store.ts | head -20Repository: makeplane/plane
Length of output: 268
🏁 Script executed:
# Find rootIssueStore definition
rg -n "class.*RootIssueStore|projectIssues.*=" apps/web/core/store/issue/issue-details/root.store.ts -A 3 | head -40Repository: makeplane/plane
Length of output: 41
🏁 Script executed:
# Search for projectIssues store file
fd -name "*project*issues*" -o -name "*root*store*" | grep -E "store|issue" | head -10Repository: makeplane/plane
Length of output: 289
🏁 Script executed:
# Find the actual API service that sends the payload
rg -n "class.*ProjectIssues|updateIssue.*async" apps/web/core/store -A 5 | grep -A 5 "updateIssue"Repository: makeplane/plane
Length of output: 2750
🏁 Script executed:
# Find BaseIssuesStore which likely has the actual updateIssue implementation
fd "base*issues*" -type fRepository: makeplane/plane
Length of output: 229
🏁 Script executed:
# Search for the store file that contains updateIssue with API call
rg "updateIssue.*service\.|issueService\.update" --type-add 'web:tsx,ts,js' -B 3 -A 8Repository: makeplane/plane
Length of output: 3137
🏁 Script executed:
# Look for where the data payload is actually sent (likely in a service file)
rg "PUT.*issue|issueService" apps/web/core/store -A 5 | head -60Repository: makeplane/plane
Length of output: 4408
🏁 Script executed:
# Find IssueService definition
fd "issue.*service" -type f | head -5Repository: makeplane/plane
Length of output: 229
🏁 Script executed:
# Search for IssueService class and updateIssue method
rg "class IssueService|updateIssue.*async" -A 10 | head -100Repository: makeplane/plane
Length of output: 9263
🏁 Script executed:
# Get IssueService.updateIssue method
cat apps/web/core/services/issue/issue.service.ts | grep -n "updateIssue" -A 15 | head -50Repository: makeplane/plane
Length of output: 1882
🏁 Script executed:
# Get the full IssueService file to find updateIssue method
wc -l apps/web/core/services/issue/issue.service.tsRepository: makeplane/plane
Length of output: 108
🏁 Script executed:
# Search more specifically for updateIssue pattern
rg "updateIssue.*\(" apps/web/core/services/issue/issue.service.ts -A 10Repository: makeplane/plane
Length of output: 1236
🏁 Script executed:
# Look at the full IssueService to see all methods
cat -n apps/web/core/services/issue/issue.service.ts | head -100Repository: makeplane/plane
Length of output: 3673
🏁 Script executed:
# Search for BaseIssuesStore which extends or contains projectIssues
rg "class.*BaseIssues|updateIssue.*=" apps/web/core/store/issue/helpers/base-issues.store.ts -A 8 | head -100Repository: makeplane/plane
Length of output: 390
🏁 Script executed:
# Search for updateIssue in BaseIssuesStore
rg "updateIssue.*=" apps/web/core/store/issue/helpers/base-issues.store.ts -A 20 | head -80Repository: makeplane/plane
Length of output: 41
🏁 Script executed:
# Also check the size and search for issueUpdate which might be the method name
wc -l apps/web/core/store/issue/helpers/base-issues.store.tsRepository: makeplane/plane
Length of output: 118
🏁 Script executed:
# Search for issueUpdate method
rg "issueUpdate\s*=" apps/web/core/store/issue/helpers/base-issues.store.ts -A 30 | head -100Repository: makeplane/plane
Length of output: 41
🏁 Script executed:
# Also search for PATCH or patchIssue calls
rg "patchIssue\|issueService\.patch" apps/web/core/store/issue/helpers/base-issues.store.ts -B 3 -A 8 | head -80Repository: makeplane/plane
Length of output: 41
🏁 Script executed:
# Find ProjectIssues store definition
fd "project.*issues.*store" -type fRepository: makeplane/plane
Length of output: 229
🏁 Script executed:
# Search for class ProjectIssues
rg "class ProjectIssues" apps/web/core/store -A 30Repository: makeplane/plane
Length of output: 4816
🏁 Script executed:
# Look at the root store to see how projectIssues is initialized
rg "projectIssues" apps/web/core/store/issue/root-issue-store.ts -B 2 -A 5 | head -50Repository: makeplane/plane
Length of output: 144
🏁 Script executed:
# Search BaseIssuesStore for all methods containing "update" or "issue"
rg "^\s*(updateIssue|issueUpdate)\s*=" apps/web/core/store/issue/helpers/base-issues.store.ts -A 25Repository: makeplane/plane
Length of output: 41
🏁 Script executed:
# More broad search - look for methods that call issueService
rg "this\.issueService\." apps/web/core/store/issue/helpers/base-issues.store.ts | head -20Repository: makeplane/plane
Length of output: 1054
Field name and type mismatch: frontend sends no_activity: "true" but backend expects skip_activity as boolean
The code sends no_activity: "true" (string) to the backend, but the API expects skip_activity (boolean). Backend code in apps/api/plane/app/views/issue/base.py:615 explicitly pops skip_activity from the request payload:
skip_activity = request.data.pop("skip_activity", False)The no_activity field will be silently ignored by the backend, and the migration flag won't suppress activity logging. Change the payload to:
...(isMigrationUpdate ? { skip_activity: true } : {})This affects three files: peek-overview/issue-detail.tsx, issue-detail/main-content.tsx, and inbox/content/issue-root.tsx.
🤖 Prompt for AI Agents
In apps/web/core/components/issues/peek-overview/issue-detail.tsx around lines
137-142 (and likewise update issue-detail/main-content.tsx and
inbox/content/issue-root.tsx), the payload uses no_activity: "true" (a string)
which the backend ignores; change the migration flag to send skip_activity: true
(a boolean) when isMigrationUpdate is true so the backend's
request.data.pop("skip_activity", False) receives the correct boolean field and
suppresses activity logging.
…tracking-description' of github.com:makeplane/plane into fix-activity-tracking-description
Description
This pull request introduces a mechanism to distinguish between regular and migration-only updates to issue descriptions, ensuring that activity logs are not generated for migration-only changes.
Type of Change
Screenshots and Media (if applicable)
Test Scenarios
References
Summary by CodeRabbit
New Features
Bug Fixes
✏️ Tip: You can customize this high-level summary in your review settings.