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:
- Addition: User added to project (must be workspace member first)
- Active Member: User has project access
- Role Management: Roles updated as needed
- Removal: User removed from project
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.addMemberpermission - User not already a project member
Common Roles:
admin- Project administrationdeveloper- Development accessviewer- Read-only accesstester- Testing accessteam-lead- Team management- Custom roles based on your setup
What Happens:
- System validates user is workspace member
- Checks user not already project member
- Creates project member record
- Assigns specified role
- User gains immediate project access
- 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
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:
| Role | Permissions | Use For |
|---|---|---|
| Admin | Full control | Project leads, managers |
| Developer | Create/edit resources | Developers, engineers |
| Tester | Execute, test | QA engineers, testers |
| Viewer | Read-only | Stakeholders, clients |
| Team Lead | Team management | Team 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 UUIDuserID: User UUIDid: ProjectMember record UUID
Effects:
- Member record deleted from project
- User loses project access
- User maintains workspace access
- User notified via email/in-app
- Activity logged for audit
- 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.addMemberpermission - Invalid user ID or project ID
Solutions:
- Verify user is workspace member
- Check if user already in project
- Verify your permissions
- Validate UUIDs are correct
- Check project is not archived
Issue: Can't Remove Member
Symptoms: Removal mutation fails
Possible Causes:
- Missing
project.removeMemberpermission - Invalid project member ID
- Member not in project
- Database constraints
Solutions:
- Verify removal permissions
- Check project member ID is correct
- Confirm member is in project
- 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:
- Have member refresh browser
- Log out and log back in
- Wait 1-2 minutes for sync
- Verify project not archived
- 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:
- Verify role permissions in RBAC
- Check role definition
- Wait for permission sync
- Review RBAC hierarchy
- 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?
- Managing Projects: Project lifecycle operations
- Getting Started: Project creation basics
- Workspace Members: Workspace-level membership
- RBAC & Permissions: Deep dive into permissions
Need Help? Contact your project administrator for member management assistance or review the RBAC documentation for advanced permission configurations.