Team Management
The Team module (sdk.teams) provides comprehensive team management capabilities including team creation, member management, role assignments, and team querying within workspaces.
Creating Teams
Basic Team Creation
const team = await sdk.teams.createTeam('Development Team', 'workspace-123');
console.log(`Created team: ${team.name}`);
console.log(`Team ID: ${team.id}`);
console.log(`Workspace: ${team.workspaceID}`);
console.log(`Status: ${team.status}`);
Getting Teams
Get Single Team
const team = await sdk.teams.getTeam('team-123');
if (team) {
console.log(`Team: ${team.name}`);
console.log(`Members: ${team.users?.length || 0}`);
console.log(`Created: ${team.createdAt}`);
// List team members
team.users?.forEach(user => {
console.log(`- ${user.name} (${user.email})`);
});
}
Get Teams by Workspace
// Get all teams in a workspace
const teamsResponse = await sdk.teams.getTeamsByWorkspace('workspace-123');
console.log(`Found ${teamsResponse.count} teams`);
teamsResponse.teams.forEach(team => {
console.log(`${team.name} - ${team.status}`);
});
// Get teams with pagination and search
const paginatedTeams = await sdk.teams.getTeamsByWorkspace('workspace-123', {
itemsPerPage: 10,
page: 1,
search: 'dev', // Search for teams with 'dev' in the name
});
Updating Teams
const updatedTeam = await sdk.teams.updateTeam('team-123', {
name: 'Senior Development Team',
status: 'ACTIVE',
});
console.log(`Updated team: ${updatedTeam.name}`);
Team Lifecycle Management
Archive Team
const archivedTeam = await sdk.teams.archiveTeam('team-123');
console.log(`Team archived: ${archivedTeam.status}`); // 'ARCHIVED'
Reactivate Team
const reactivatedTeam = await sdk.teams.reactivateTeam('team-123');
console.log(`Team reactivated: ${reactivatedTeam.status}`); // 'ACTIVE'
Delete Team
const deletedTeam = await sdk.teams.deleteTeam('team-123');
console.log(`Team deleted: ${deletedTeam.status}`); // 'DELETED'
Member Management
Add Team Member
// Add member by email
const updatedTeam = await sdk.teams.addUserToTeam('team-123', '[email protected]');
console.log(`Added member to team: ${updatedTeam.name}`);
console.log(`Team now has ${updatedTeam.users?.length} members`);
Remove Team Member
const updatedTeam = await sdk.teams.removeUserFromTeam('team-123', 'user-456');
console.log(`Removed member from team: ${updatedTeam.name}`);
Get Team Members
// Get all team members
const members = await sdk.teams.getTeamMembers('team-123');
console.log(`Team has ${members.count} members:`);
members.users.forEach(user => {
console.log(`- ${user.name} (${user.email}) - ${user.status}`);
console.log(` Joined: ${user.createdAt}`);
});
// Get members with pagination and search
const paginatedMembers = await sdk.teams.getTeamMembers('team-123', {
itemsPerPage: 5,
page: 1,
search: 'john', // Search for members with 'john' in their name
});
Role Assignments
Assign Role to Team
const teamRoleAssignment = await sdk.teams.assignRoleToTeam({
teamId: 'team-123',
roleId: 'developer-role-id',
});
console.log(`Assigned role to team: ${teamRoleAssignment.id}`);
console.log(`Assignment date: ${teamRoleAssignment.assignedAt}`);
Remove Role from Team
const removed = await sdk.teams.removeRoleFromTeam('developer-role-id', 'team-123');
console.log(`Role removed from team: ${removed}`);
Get Team Roles
const teamRoles = await sdk.teams.getTeamRoles('team-123');
console.log(`Team has ${teamRoles.length} roles:`);
teamRoles.forEach(assignment => {
console.log(`- ${assignment.role?.name}: ${assignment.role?.description}`);
console.log(` Assigned: ${assignment.assignedAt}`);
});
Advanced Usage Patterns
Team Management Dashboard
class TeamManager {
constructor(private sdk: WorkspacesSDK) {}
async createProjectTeam(
workspaceId: string,
projectName: string,
memberEmails: string[]
) {
try {
// Create team
const team = await this.sdk.teams.createTeam(
`${projectName} Team`,
workspaceId
);
// Add members
for (const email of memberEmails) {
try {
await this.sdk.teams.addUserToTeam(team.id, email);
console.log(`Added ${email} to team`);
} catch (error) {
console.error(`Failed to add ${email}:`, error.message);
}
}
// Assign default role
const roles = await this.sdk.rbac.getRoles();
const memberRole = roles.find(role => role.name === 'Team Member');
if (memberRole) {
await this.sdk.teams.assignRoleToTeam({
teamId: team.id,
roleId: memberRole.id,
});
}
return team;
} catch (error) {
console.error('Failed to create project team:', error.message);
throw error;
}
}
async getTeamSummary(teamId: string) {
const [team, members, roles] = await Promise.all([
this.sdk.teams.getTeam(teamId),
this.sdk.teams.getTeamMembers(teamId),
this.sdk.teams.getTeamRoles(teamId),
]);
return {
team,
memberCount: members.count,
members: members.users,
roles: roles.map(r => r.role),
activeMembers: members.users.filter(u => u.status === 'ACTIVE'),
recentJoins: members.users.filter(u => {
const joinDate = new Date(u.createdAt);
const thirtyDaysAgo = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000);
return joinDate > thirtyDaysAgo;
}),
};
}
async auditTeamAccess(workspaceId: string) {
const teamsResponse = await this.sdk.teams.getTeamsByWorkspace(workspaceId);
const auditResults = [];
for (const team of teamsResponse.teams) {
const members = await this.sdk.teams.getTeamMembers(team.id);
const roles = await this.sdk.teams.getTeamRoles(team.id);
auditResults.push({
teamName: team.name,
memberCount: members.count,
roleCount: roles.length,
status: team.status,
lastUpdated: team.updatedAt,
hasInactiveMembers: members.users.some(u => u.status !== 'ACTIVE'),
isEmpty: members.count === 0,
});
}
return auditResults;
}
}
// Usage
const teamManager = new TeamManager(sdk);
// Create a new project team
const team = await teamManager.createProjectTeam(
'workspace-123',
'Mobile App',
['[email protected]', '[email protected]', '[email protected]']
);
// Get comprehensive team summary
const summary = await teamManager.getTeamSummary(team.id);
console.log('Team Summary:', summary);
// Audit all teams in workspace
const auditResults = await teamManager.auditTeamAccess('workspace-123');
console.log('Team Audit Results:', auditResults);
Team-Based Permission Management
const assignTeamPermissions = async (teamId: string, permissions: string[]) => {
// Get or create a custom role for this team
const roleName = `Team-${teamId}-Custom`;
let teamRole;
try {
// Try to find existing role
const roles = await sdk.rbac.getRoles();
teamRole = roles.find(role => role.name === roleName);
if (!teamRole) {
// Create new role for the team
teamRole = await sdk.rbac.createRole({
name: roleName,
description: `Custom role for team ${teamId}`,
});
}
} catch (error) {
console.error('Failed to get/create team role:', error);
return;
}
// Assign permissions to the role
for (const permissionName of permissions) {
try {
const allPermissions = await sdk.rbac.getPermissions();
const permission = allPermissions.find(p => p.name === permissionName);
if (permission) {
await sdk.rbac.assignPermissionToRole({
roleId: teamRole.id,
permissionId: permission.id,
resourceId: `team:${teamId}`,
});
console.log(`Assigned ${permissionName} to team role`);
}
} catch (error) {
console.error(`Failed to assign ${permissionName}:`, error);
}
}
// Assign the role to the team
await sdk.teams.assignRoleToTeam({
teamId,
roleId: teamRole.id,
});
console.log(`Team permissions configured for team ${teamId}`);
};
// Usage
await assignTeamPermissions('team-123', [
'read_team_data',
'edit_team_settings',
'manage_team_members',
]);
Team Synchronization
const syncTeamWithExternalSource = async (
teamId: string,
externalMembers: Array<{ email: string; role: string }>
) => {
// Get current team members
const currentMembers = await sdk.teams.getTeamMembers(teamId);
const currentEmails = new Set(currentMembers.users.map(u => u.email));
// Get target emails
const targetEmails = new Set(externalMembers.map(m => m.email));
// Find members to add and remove
const toAdd = externalMembers.filter(m => !currentEmails.has(m.email));
const toRemove = currentMembers.users.filter(u => !targetEmails.has(u.email));
console.log(`Sync plan: Add ${toAdd.length}, Remove ${toRemove.length}`);
// Add new members
for (const member of toAdd) {
try {
await sdk.teams.addUserToTeam(teamId, member.email);
console.log(`Added ${member.email} to team`);
} catch (error) {
console.error(`Failed to add ${member.email}:`, error.message);
}
}
// Remove old members
for (const member of toRemove) {
try {
await sdk.teams.removeUserFromTeam(teamId, member.id);
console.log(`Removed ${member.email} from team`);
} catch (error) {
console.error(`Failed to remove ${member.email}:`, error.message);
}
}
return {
added: toAdd.length,
removed: toRemove.length,
total: targetEmails.size,
};
};
// Usage
const externalMembers = [
{ email: '[email protected]', role: 'developer' },
{ email: '[email protected]', role: 'developer' },
{ email: '[email protected]', role: 'lead' },
];
const syncResult = await syncTeamWithExternalSource('team-123', externalMembers);
console.log('Sync completed:', syncResult);
Error Handling
try {
const team = await sdk.teams.createTeam('Duplicate Team Name', 'workspace-123');
} catch (error) {
if (error.message.includes('already exists')) {
console.error('Team name already exists in this workspace');
} else if (error.message.includes('permission')) {
console.error('Insufficient permissions to create team');
} else if (error.message.includes('workspace not found')) {
console.error('Workspace does not exist');
} else {
console.error('Failed to create team:', error.message);
}
}
Best Practices
1. Team Naming Conventions
// Good naming patterns
const teams = [
'Frontend Development Team',
'Backend API Team',
'Design & UX Team',
'QA & Testing Team',
'Project Alpha - Core Team',
'Project Beta - Integration Team',
];
// Avoid generic names
const avoid = [
'Team 1',
'My Team',
'Development',
'Group A',
];
2. Regular Team Cleanup
const cleanupInactiveTeams = async (workspaceId: string, daysInactive = 90) => {
const teamsResponse = await sdk.teams.getTeamsByWorkspace(workspaceId);
const cutoffDate = new Date(Date.now() - daysInactive * 24 * 60 * 60 * 1000);
for (const team of teamsResponse.teams) {
const lastUpdated = new Date(team.updatedAt || team.createdAt);
if (lastUpdated < cutoffDate && team.status === 'ACTIVE') {
const members = await sdk.teams.getTeamMembers(team.id);
if (members.count === 0) {
console.log(`Archiving inactive empty team: ${team.name}`);
await sdk.teams.archiveTeam(team.id);
} else {
console.log(`Team ${team.name} is inactive but has ${members.count} members`);
}
}
}
};
3. Team Size Management
const monitorTeamSizes = async (workspaceId: string) => {
const teamsResponse = await sdk.teams.getTeamsByWorkspace(workspaceId);
const recommendations = [];
for (const team of teamsResponse.teams) {
const members = await sdk.teams.getTeamMembers(team.id);
if (members.count === 0) {
recommendations.push({
team: team.name,
issue: 'empty',
suggestion: 'Consider archiving or adding members',
});
} else if (members.count > 20) {
recommendations.push({
team: team.name,
issue: 'too_large',
suggestion: 'Consider splitting into smaller teams',
memberCount: members.count,
});
} else if (members.count === 1) {
recommendations.push({
team: team.name,
issue: 'single_member',
suggestion: 'Consider adding more members or merging with another team',
});
}
}
return recommendations;
};
4. Permission-Based Team Access
const getAccessibleTeams = async (workspaceId: string) => {
const teamsResponse = await sdk.teams.getTeamsByWorkspace(workspaceId);
const accessibleTeams = [];
for (const team of teamsResponse.teams) {
const canView = await sdk.rbac.checkPermission('view_team', `team:${team.id}`);
if (canView) {
const canManage = await sdk.rbac.checkPermission('manage_team', `team:${team.id}`);
accessibleTeams.push({
...team,
permissions: {
canView: true,
canManage,
},
});
}
}
return accessibleTeams;
};