Skip to content

Conversation

@b-saikrishnakanth
Copy link
Collaborator

@b-saikrishnakanth b-saikrishnakanth commented Dec 30, 2025

Description

improvements in members page

Type of Change

  • Code refactoring

Screenshots and Media (if applicable)

Test Scenarios

References


Note

Refactors member and workspace stores, removes unused activity mutation hooks, and consolidates workspace store wiring.

  • Eliminates mutateProjectMembersActivity and mutateWorkspaceMembersActivity from project/workspace member flows (bulk add, role update, remove, invite, delete invitation)
  • Introduces BaseWorkspaceMemberStore in core with a CE WorkspaceMemberStore implementation; updates imports to use plane-web paths
  • Makes core WorkspaceRootStore concrete and updates CoreRootStore to use it; removes CE workspace/index.ts
  • Minor method refactors to async function syntax and internal cleanups in project/workspace member stores

Written by Cursor Bugbot for commit 1aac9ce. This will update automatically on new commits. Configure here.

Summary by CodeRabbit

  • Refactor
    • Improved member management store architecture by removing deprecated internal mutation methods.
    • Restructured member store implementations for better code organization and maintainability.
    • Updated method signatures across workspace and project member stores to follow standard patterns.
    • All member management functionality remains unchanged and fully compatible with existing workflows.

✏️ Tip: You can customize this high-level summary in your review settings.

@makeplane
Copy link

makeplane bot commented Dec 30, 2025

Linked to Plane Work Item(s)

This comment was auto-generated by Plane

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 30, 2025

📝 Walkthrough

Walkthrough

This PR refactors member stores by removing optimistic-activity mutation hooks (mutateProjectMembersActivity/mutateWorkspaceMembersActivity), converting several methods from arrow-function properties to standard async method signatures, and reorganizing store class hierarchies. Workspace member functionality is elevated to CE exports while the root workspace store is consolidated into a concrete implementation.

Changes

Cohort / File(s) Summary
Project Member Store Cleanup
apps/web/ce/store/member/project-member.store.ts, apps/web/core/store/member/project/base-project-member.store.ts
Removed mutateProjectMembersActivity method. Converted bulkAddMembersToProject, updateMemberRole, and removeMemberFromProject from arrow-function properties to standard async methods; removed all calls to mutateProjectMembersActivity and eliminated the interface member.
Workspace Member Store Restructuring
apps/web/core/store/member/workspace/workspace-member.store.ts, apps/web/ce/store/member/workspace-member.store.ts
Renamed IWorkspaceMemberStore to IBaseWorkspaceMemberStore and made WorkspaceMemberStore abstract as BaseWorkspaceMemberStore. Converted updateMember, removeMemberFromWorkspace, inviteMembersToWorkspace, and deleteMemberInvitation from arrow functions to standard async methods; removed all mutateWorkspaceMembersActivity calls. New CE store file created as a thin wrapper extending base class.
Root Store Updates
apps/web/core/store/workspace/index.ts, apps/web/core/store/root.store.ts, apps/web/ce/store/workspace/index.ts
Removed mutateWorkspaceMembersActivity from IWorkspaceRootStore interface. Consolidated BaseWorkspaceRootStore to concrete WorkspaceRootStore. Removed CE workspace root store file. Updated imports in root store.
Store Export Consolidation
apps/web/core/store/member/index.ts
Replaced local imports of workspace member store with absolute alias imports from CE store path.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • prateekshourya29

Poem

🐰 Hoppy refactoring, the mutations depart,
Async methods hop where arrows did start,
Workspace and project stores align,
No more activity mutations—so fine!
The CE bridge built, the hierarchy shine!

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Description check ❓ Inconclusive The description includes required sections (Description, Type of Change) but is incomplete; Test Scenarios and References sections are empty, and the actual description text is minimal. Add more detail to the Description section explaining the refactoring changes, and fill in Test Scenarios with validation steps (or explain why testing is not applicable for this refactor).
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: refactoring of the members page/store implementation with clear scope indicated by the ticket number.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings

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 and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a37e5e2 and 1aac9ce.

📒 Files selected for processing (8)
  • apps/web/ce/store/member/project-member.store.ts
  • apps/web/ce/store/member/workspace-member.store.ts
  • apps/web/ce/store/workspace/index.ts
  • apps/web/core/store/member/index.ts
  • apps/web/core/store/member/project/base-project-member.store.ts
  • apps/web/core/store/member/workspace/workspace-member.store.ts
  • apps/web/core/store/root.store.ts
  • apps/web/core/store/workspace/index.ts
💤 Files with no reviewable changes (2)
  • apps/web/ce/store/member/project-member.store.ts
  • apps/web/ce/store/workspace/index.ts
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx,mts,cts}

📄 CodeRabbit inference engine (.github/instructions/typescript.instructions.md)

**/*.{ts,tsx,mts,cts}: Use const type parameters for more precise literal inference in TypeScript 5.0+
Use the satisfies operator to validate types without widening them
Leverage inferred type predicates to reduce the need for explicit is return types in filter/check functions
Use NoInfer<T> utility to block inference for specific type arguments when they should be determined by other arguments
Utilize narrowing in switch(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 legacy experimentalDecorators
Use using declarations for explicit resource management with Disposable pattern instead of manual cleanup (TypeScript 5.2+)
Use with { type: "json" } for import attributes; avoid deprecated assert syntax (TypeScript 5.3/5.8+)
Use import type explicitly when importing types to ensure they are erased during compilation, respecting verbatimModuleSyntax flag
Use .ts, .mts, .cts extensions in import type statements (TypeScript 5.2+)
Use import 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 new Set methods like union, intersection, etc., when available (TypeScript 5.5+)
Use Object.groupBy / Map.groupBy standard methods for grouping instead of external libraries (TypeScript 5.4+)
Use Promise.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 via super in classes (TypeScript 5....

Files:

  • apps/web/ce/store/member/workspace-member.store.ts
  • apps/web/core/store/member/index.ts
  • apps/web/core/store/member/workspace/workspace-member.store.ts
  • apps/web/core/store/root.store.ts
  • apps/web/core/store/member/project/base-project-member.store.ts
  • apps/web/core/store/workspace/index.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Enable TypeScript strict mode and ensure all files are fully typed

Files:

  • apps/web/ce/store/member/workspace-member.store.ts
  • apps/web/core/store/member/index.ts
  • apps/web/core/store/member/workspace/workspace-member.store.ts
  • apps/web/core/store/root.store.ts
  • apps/web/core/store/member/project/base-project-member.store.ts
  • apps/web/core/store/workspace/index.ts
**/*.{js,jsx,ts,tsx,json,css}

📄 CodeRabbit inference engine (AGENTS.md)

Use Prettier with Tailwind plugin for code formatting, run pnpm fix:format

Files:

  • apps/web/ce/store/member/workspace-member.store.ts
  • apps/web/core/store/member/index.ts
  • apps/web/core/store/member/workspace/workspace-member.store.ts
  • apps/web/core/store/root.store.ts
  • apps/web/core/store/member/project/base-project-member.store.ts
  • apps/web/core/store/workspace/index.ts
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,jsx,ts,tsx}: Use ESLint with shared config across packages, adhering to max warnings limits per package
Use camelCase for variable and function names, PascalCase for components and types
Use try-catch with proper error types and log errors appropriately

Files:

  • apps/web/ce/store/member/workspace-member.store.ts
  • apps/web/core/store/member/index.ts
  • apps/web/core/store/member/workspace/workspace-member.store.ts
  • apps/web/core/store/root.store.ts
  • apps/web/core/store/member/project/base-project-member.store.ts
  • apps/web/core/store/workspace/index.ts
🧠 Learnings (5)
📓 Common learnings
Learnt from: CR
Repo: makeplane/plane PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-12T15:20:36.542Z
Learning: Applies to packages/shared-state/**/*.{ts,tsx} : Maintain MobX stores in `packages/shared-state` using reactive patterns
📚 Learning: 2025-12-12T15:20:36.542Z
Learnt from: CR
Repo: makeplane/plane PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-12T15:20:36.542Z
Learning: Applies to packages/shared-state/**/*.{ts,tsx} : Maintain MobX stores in `packages/shared-state` using reactive patterns

Applied to files:

  • apps/web/ce/store/member/workspace-member.store.ts
  • apps/web/core/store/member/index.ts
  • apps/web/core/store/member/workspace/workspace-member.store.ts
  • apps/web/core/store/root.store.ts
📚 Learning: 2025-12-12T15:20:36.542Z
Learnt from: CR
Repo: makeplane/plane PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-12T15:20:36.542Z
Learning: Applies to **/package.json : Use `workspace:*` for internal packages and `catalog:` for external dependencies in imports

Applied to files:

  • apps/web/core/store/root.store.ts
📚 Learning: 2025-10-06T01:44:38.472Z
Learnt from: lifeiscontent
Repo: makeplane/plane PR: 7888
File: packages/propel/src/collapsible/collapsible.stories.tsx:4-4
Timestamp: 2025-10-06T01:44:38.472Z
Learning: In Storybook v9, imports use bare paths instead of scoped packages. For example, `import { useArgs } from "storybook/preview-api"` is correct (not `storybook/preview-api`). This applies to other Storybook modules as well - the scoped storybook/* packages were consolidated into bare "storybook/*" imports.

Applied to files:

  • apps/web/core/store/root.store.ts
📚 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/store/member/project/base-project-member.store.ts
🧬 Code graph analysis (3)
apps/web/ce/store/member/workspace-member.store.ts (2)
apps/web/core/store/member/workspace/workspace-member.store.ts (1)
  • IBaseWorkspaceMemberStore (26-58)
apps/web/core/store/member/index.ts (1)
  • IMemberRootStore (12-21)
apps/web/core/store/member/workspace/workspace-member.store.ts (1)
packages/types/src/workspace.ts (1)
  • IWorkspaceBulkInviteFormData (56-58)
apps/web/core/store/member/project/base-project-member.store.ts (1)
packages/types/src/project/projects.ts (1)
  • IProjectBulkAddFormData (110-112)
⏰ 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). (3)
  • GitHub Check: Build packages
  • GitHub Check: Cursor Bugbot
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (11)
apps/web/core/store/root.store.ts (1)

64-64: LGTM: Import path updated for workspace store reorganization.

The import source change aligns with the broader refactoring to consolidate workspace store implementations.

apps/web/core/store/member/index.ts (1)

8-9: LGTM: Import paths updated to use absolute aliases.

The import source change from relative to absolute paths aligns with the architectural shift where workspace member store implementations are now sourced from the CE layer.

apps/web/ce/store/member/workspace-member.store.ts (1)

1-13: LGTM: Valid CE concrete implementation.

This follows the standard CE/EE pattern where the CE layer provides a concrete implementation of the abstract base store from core. The type alias maintains backward compatibility while the class extends the base with no additional CE-specific logic, which is expected for the baseline CE implementation.

apps/web/core/store/workspace/index.ts (1)

66-66: LGTM: Concrete workspace root store implementation.

The class is now a concrete implementation of IWorkspaceRootStore with all methods properly defined. MobX decorators are correctly applied and the implementation maintains proper reactive patterns.

apps/web/core/store/member/workspace/workspace-member.store.ts (4)

26-26: LGTM: Interface rename and abstract base class declaration.

The interface rename to IBaseWorkspaceMemberStore and class conversion to abstract BaseWorkspaceMemberStore correctly establish this as a base abstraction for CE/EE extension. This aligns with the architectural refactoring pattern.

Also applies to: 60-60


254-271: LGTM: Method conversion from arrow function to standard async method.

The updateMember method has been correctly converted from an arrow function property to a standard async method. The MobX action decorator is properly applied (line 87), and the optimistic update pattern with error rollback is maintained.


278-285: LGTM: Method conversion for removeMemberFromWorkspace.

The removeMemberFromWorkspace method has been correctly converted to a standard async method with the MobX action decorator properly applied (line 88).


345-352: LGTM: Method conversion for deleteMemberInvitation.

The deleteMemberInvitation method has been correctly converted to a standard async method with proper MobX action decorator (line 91) and state updates wrapped in runInAction.

apps/web/core/store/member/project/base-project-member.store.ts (3)

307-327: LGTM: Method conversion for bulkAddMembersToProject.

The bulkAddMembersToProject method has been correctly converted from an arrow function to a standard async method. The MobX action decorator is properly applied (line 119), state updates are wrapped in runInAction, and the method now returns the service response directly. The blank line 324 indicates where the mutation hook call was removed.


348-401: LGTM: Method conversion for updateMemberRole.

The updateMemberRole method has been correctly converted to a standard async method with proper MobX action decorator (line 120). The implementation maintains sophisticated optimistic updates with error rollback, correctly handling both regular member updates and current user permission synchronization.


431-438: LGTM: Method conversion for removeMemberFromProject.

The removeMemberFromProject method has been correctly converted to a standard async method with proper MobX action decorator (line 121). The implementation correctly delegates member cleanup to the abstract processMemberRemoval method and properly wraps state updates in runInAction.

Comment on lines +304 to +307
async inviteMembersToWorkspace(workspaceSlug: string, data: IWorkspaceBulkInviteFormData) {
await this.workspaceService.inviteWorkspace(workspaceSlug, data);
await this.fetchWorkspaceMemberInvitations(workspaceSlug);
void this.rootStore.workspaceRoot.mutateWorkspaceMembersActivity(workspaceSlug);
};
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Missing MobX action decorator for inviteMembersToWorkspace.

The inviteMembersToWorkspace method was converted from an arrow function to a standard async method, but it's not included in the makeObservable configuration (lines 77-92). Since this method triggers state changes by calling fetchWorkspaceMemberInvitations, it should be decorated with action.

🔎 Proposed fix

Add the action decorator in the makeObservable call:

 makeObservable(this, {
   // observables
   workspaceMemberMap: observable,
   workspaceMemberInvitations: observable,
   // computed
   workspaceMemberIds: computed,
   workspaceMemberInvitationIds: computed,
   memberMap: computed,
   // actions
   fetchWorkspaceMembers: action,
   updateMember: action,
   removeMemberFromWorkspace: action,
   fetchWorkspaceMemberInvitations: action,
+  inviteMembersToWorkspace: action,
   updateMemberInvitation: action,
   deleteMemberInvitation: action,
 });

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In apps/web/core/store/member/workspace/workspace-member.store.ts around lines
304-307, the async method inviteMembersToWorkspace was converted from an arrow
function but not added to the makeObservable configuration (lines 77-92), so it
lacks the MobX action decorator; update the makeObservable call to include
inviteMembersToWorkspace as an action (alongside the other action-decorated
methods) so state changes triggered by fetchWorkspaceMemberInvitations are
wrapped as a MobX action.

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

This PR is being reviewed by Cursor Bugbot

Details

Your team is on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle for each member of your team.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

throw error;
}
};
}
Copy link

Choose a reason for hiding this comment

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

Methods lose this binding after arrow-to-method conversion

Several methods (updateMember, removeMemberFromWorkspace, inviteMembersToWorkspace, deleteMemberInvitation, bulkAddMembersToProject, updateMemberRole, removeMemberFromProject) were converted from arrow functions to regular class methods. Throughout the codebase, these methods are destructured from stores and called as standalone functions (e.g., const { removeMemberFromProject } = useMember().project; await removeMemberFromProject(...)). Regular methods lose their this binding when destructured, causing this to be undefined at runtime. This will crash when users try to update roles, remove members, or invite members.

Additional Locations (2)

Fix in Cursor Fix in Web

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