Skip to main content

Project Members

This guide covers everything about managing project members, including adding members, assigning roles, removing members, and implementing effective access control within projects.

Project Member Overview

Project members are users who have access to a specific project within a workspace. Each member can have project-specific roles and permissions that determine what they can do with project resources.

Understanding Project Membership

Member Structure

Each project member has:

  • User Association: Link to user account
  • Project Association: Link to specific project
  • Role (Optional): Project-specific role
  • Join Date: When member was added
  • Unique Constraint: User can only be added once per project

Member Lifecycle

Add to Project → Active Member → Role Changes → Removal

Stages:

  1. Addition: User added to project (must be workspace member first)
  2. Active Member: User has project access
  3. Role Management: Roles updated as needed
  4. Removal: User removed from project
important

Prerequisite: Users must be workspace members before they can be added to projects within that workspace.

Viewing Project Members

Get All Project Members

query GetProjectMembers {
getProject(id: "project-uuid-here") {
projectMembers {
id
userID
projectID
role
createdAt
user {
id
firstName
lastName
email
}
}
}
}

Response Includes:

  • Complete member list
  • User details
  • Role assignments
  • Join dates

Filter by Role

# Client-side filtering (API returns all)
query GetProjectMembers {
getProject(id: "project-uuid") {
projectMembers {
id
userID
role
user {
firstName
lastName
}
}
}
}

# Filter for specific role:
const developers = members.filter(m => m.role === 'developer');
const admins = members.filter(m => m.role === 'admin');

View Specific Member

query GetSpecificMember {
getProject(id: "project-uuid-here") {
projectMembers(where: { userID: { equals: "user-uuid-here" } }) {
id
role
createdAt
user {
firstName
lastName
email
}
}
}
}

Adding Project Members

Add Single Member

Add a workspace member to your project:

mutation AddMember {
addProjectMember(
input: {
projectID: "project-uuid-here"
userID: "user-uuid-here"
role: "developer"
}
) {
id
userID
projectID
role
createdAt
}
}

Requirements:

  • User must be a workspace member
  • You need project.addMember permission
  • User not already a project member

Common Roles:

  • admin - Project administration
  • developer - Development access
  • viewer - Read-only access
  • tester - Testing access
  • team-lead - Team management
  • Custom roles based on your setup

What Happens:

  1. System validates user is workspace member
  2. Checks user not already project member
  3. Creates project member record
  4. Assigns specified role
  5. User gains immediate project access
  6. Activity logged

Add Multiple Members

Add several members to a project:

mutation AddMultipleMembers {
member1: addProjectMember(
input: {
projectID: "project-uuid"
userID: "user-1-uuid"
role: "developer"
}
) { id }

member2: addProjectMember(
input: {
projectID: "project-uuid"
userID: "user-2-uuid"
role: "developer"
}
) { id }

member3: addProjectMember(
input: {
projectID: "project-uuid"
userID: "user-3-uuid"
role: "viewer"
}
) { id }
}

Bulk Addition Script:

const teamMembers = [
{ userId: "user-1-uuid", role: "developer" },
{ userId: "user-2-uuid", role: "developer" },
{ userId: "user-3-uuid", role: "tester" }
];

for (const member of teamMembers) {
await addProjectMember({
projectID: projectId,
userID: member.userId,
role: member.role
});
}

Managing Member Roles

Update Member Role

info

Current Limitation: The updateProjectMemberRole mutation is currently commented out in the codebase. Role updates must be handled through the RBAC system directly or by removing and re-adding the member with a new role.

Workaround - Remove and Re-Add:

# 1. Remove member
mutation RemoveMember {
removeProjectMember(
input: {
projectID: "project-uuid"
userID: "user-uuid"
id: "project-member-uuid"
}
)
}

# 2. Re-add with new role
mutation ReAddWithNewRole {
addProjectMember(
input: {
projectID: "project-uuid"
userID: "user-uuid"
role: "admin" # New role
}
) {
id
role
}
}

Workaround - Via RBAC (Advanced):

mutation UpdateRoleViaRBAC {
assignRolesToActor(
input: {
actorId: "user-actor-uuid"
roleIds: ["new-project-role-uuid"]
resourceId: "project-uuid"
}
) {
success
}
}

Role Assignment Best Practices

Role Selection:

RolePermissionsUse For
AdminFull controlProject leads, managers
DeveloperCreate/edit resourcesDevelopers, engineers
TesterExecute, testQA engineers, testers
ViewerRead-onlyStakeholders, clients
Team LeadTeam managementTeam leads, coordinators

Promotion Path:

Viewer → Developer → Team Lead → Admin

Removing Project Members

Remove Single Member

Remove a user from the project:

mutation RemoveMember {
removeProjectMember(
input: {
projectID: "project-uuid-here"
userID: "user-uuid-here"
id: "project-member-uuid-here"
}
)
}

Returns: true if successful

Required Fields:

  • projectID: Project UUID
  • userID: User UUID
  • id: ProjectMember record UUID

Effects:

  1. Member record deleted from project
  2. User loses project access
  3. User maintains workspace access
  4. User notified via email/in-app
  5. Activity logged for audit
  6. RBAC permissions updated

Notification:

Title: "Removed From The Project"
Message: "You have been removed from [Project Name] Project."
Type: Info
Channels: Email + In-app

Remove Multiple Members

mutation RemoveMultipleMembers {
member1: removeProjectMember(
input: {
projectID: "project-uuid"
userID: "user-1-uuid"
id: "member-1-uuid"
}
)

member2: removeProjectMember(
input: {
projectID: "project-uuid"
userID: "user-2-uuid"
id: "member-2-uuid"
}
)
}

Common Member Management Scenarios

Scenario 1: New Feature Team

Setup: Assembling team for new feature

# 1. Add tech lead
mutation AddLead {
addProjectMember(
input: {
projectID: "feature-project-uuid"
userID: "lead-user-uuid"
role: "admin"
}
) { id }
}

# 2. Add developers
mutation AddDevelopers {
dev1: addProjectMember(
input: {
projectID: "feature-project-uuid"
userID: "dev1-uuid"
role: "developer"
}
) { id }

dev2: addProjectMember(
input: {
projectID: "feature-project-uuid"
userID: "dev2-uuid"
role: "developer"
}
) { id }
}

# 3. Add QA engineer
mutation AddQA {
addProjectMember(
input: {
projectID: "feature-project-uuid"
userID: "qa-user-uuid"
role: "tester"
}
) { id }
}

Scenario 2: Client Project Access

Setup: Give client read-only access

# Add client stakeholder with viewer role
mutation AddClientStakeholder {
addProjectMember(
input: {
projectID: "client-project-uuid"
userID: "client-user-uuid"
role: "viewer" # Read-only
}
) {
id
role
user {
firstName
lastName
email
}
}
}

Benefits:

  • Client can view progress
  • No edit capabilities
  • Transparent collaboration
  • Professional communication

Scenario 3: Contractor Onboarding/Offboarding

Onboarding:

mutation OnboardContractor {
addProjectMember(
input: {
projectID: "project-uuid"
userID: "contractor-uuid"
role: "developer"
}
) {
id
role
}
}

# Note: Set time-limited role via RBAC separately

Offboarding:

mutation OffboardContractor {
removeProjectMember(
input: {
projectID: "project-uuid"
userID: "contractor-uuid"
id: "project-member-uuid"
}
)
}

Scenario 4: Team Reorganization

Process:

1. Audit current project members
2. Identify members to remove (moved to other projects)
3. Identify new members to add
4. Remove departing members
5. Add new members with appropriate roles
6. Notify all affected users
7. Update project documentation

Implementation:

# Remove moved members
mutation RemoveMovedMembers {
removeProjectMember(
input: {
projectID: "project-uuid"
userID: "moved-user-uuid"
id: "member-uuid"
}
)
}

# Add new members
mutation AddNewMembers {
addProjectMember(
input: {
projectID: "project-uuid"
userID: "new-user-uuid"
role: "developer"
}
) { id }
}

Best Practices

Adding Members

Do:

  • Verify user is workspace member first
  • Assign appropriate role based on job function
  • Notify team when adding new members
  • Document why each member is added
  • Provide onboarding information to new members

Don't:

  • Add users who aren't workspace members
  • Grant excessive permissions unnecessarily
  • Add entire workspace to every project
  • Forget to communicate additions to team
  • Skip role assignment

Role Management

Principles:

  • Least Privilege: Start with minimal access
  • Role-Based: Use roles consistently
  • Documented: Keep notes on role assignments
  • Reviewed: Regular access reviews
  • Flexible: Adjust as responsibilities change

Role Documentation:

Project: Customer Portal Backend

Roles:
- Admin: Tech leads and project managers
- Developer: Backend engineers working on features
- Tester: QA engineers for testing
- Viewer: Stakeholders and product owners

Review: Monthly
Last Updated: 2024-01-15

Member Reviews

Schedule:

  • Monthly: Quick member list review
  • Quarterly: Full role audit
  • Annually: Comprehensive access review
  • Ad-hoc: When team structure changes

Review Checklist:

  • All members still need access?
  • Roles still appropriate?
  • Any departures not removed?
  • Any new team members to add?
  • Documentation up to date?

Offboarding

Checklist:

  • Remove from project
  • Verify removal notification sent
  • Check for resource ownership
  • Transfer ownership if needed
  • Update project documentation
  • Log offboarding completion

Troubleshooting

Issue: Can't Add Member to Project

Symptoms: Addition fails or returns error

Possible Causes:

  • User not a workspace member
  • User already a project member
  • Missing project.addMember permission
  • Invalid user ID or project ID

Solutions:

  1. Verify user is workspace member
  2. Check if user already in project
  3. Verify your permissions
  4. Validate UUIDs are correct
  5. Check project is not archived

Issue: Can't Remove Member

Symptoms: Removal mutation fails

Possible Causes:

  • Missing project.removeMember permission
  • Invalid project member ID
  • Member not in project
  • Database constraints

Solutions:

  1. Verify removal permissions
  2. Check project member ID is correct
  3. Confirm member is in project
  4. Verify you're not removing yourself if you're the only admin

Issue: Member Can't Access Project

Symptoms: Member added but can't see project

Possible Causes:

  • Permission sync delay
  • JWT token not refreshed
  • Browser cache issues
  • RBAC not updated
  • Project is archived

Solutions:

  1. Have member refresh browser
  2. Log out and log back in
  3. Wait 1-2 minutes for sync
  4. Verify project not archived
  5. Check RBAC permissions

Issue: Role Not Working as Expected

Symptoms: Member has role but wrong permissions

Possible Causes:

  • Role-permission mismatch
  • RBAC sync delay
  • Custom role misconfigured
  • Permission inheritance issues

Solutions:

  1. Verify role permissions in RBAC
  2. Check role definition
  3. Wait for permission sync
  4. Review RBAC hierarchy
  5. Contact administrator

Advanced Topics

Custom Roles

Create project-specific custom roles:

mutation CreateProjectRole {
createRole(
input: {
name: "Backend Developer"
description: "Backend development access"
resourceType: "project"
resourceId: "project-uuid"
permissions: [
"workflow.create",
"workflow.update",
"bot.read",
"knowledgebase.read"
]
}
) {
id
name
}
}

Temporary Access

Grant time-limited project access:

# 1. Add member normally
mutation AddMember {
addProjectMember(
input: {
projectID: "project-uuid"
userID: "temp-user-uuid"
role: "developer"
}
) { id }
}

# 2. Set expiration via RBAC
mutation SetExpiration {
assignRolesToActor(
input: {
actorId: "user-actor-uuid"
roleIds: ["developer-role-uuid"]
resourceId: "project-uuid"
expiresAt: "2024-06-30T23:59:59Z"
}
) { success }
}

Member Analytics

Metrics to Track:

  • Members per project
  • Average project team size
  • Role distribution
  • Addition/removal frequency
  • Member tenure
  • Cross-project membership

Automation Scripts

Auto-Add Team Members:

// Add entire team to new project
const teamMembers = await getTeamMembers(teamId);

for (const member of teamMembers) {
await addProjectMember({
projectID: newProjectId,
userID: member.userId,
role: member.defaultRole
});
console.log(`Added ${member.name} as ${member.defaultRole}`);
}

Sync with HR System:

// Sync project members with HR system
const hrTeamMembers = await fetchHRTeamMembers();
const projectMembers = await getProjectMembers(projectId);

// Add new members
for (const hrMember of hrTeamMembers) {
if (!projectMembers.find(pm => pm.email === hrMember.email)) {
await addProjectMember({
projectID: projectId,
userID: hrMember.workspaceUserId,
role: mapRoleFromHR(hrMember.jobTitle)
});
}
}

What's Next?


Need Help? Contact your project administrator for member management assistance or review the RBAC documentation for advanced permission configurations.