Team Members Management - Implementation Guide¶
π― Overview¶
Complete implementation for listing, viewing, and removing team members with role assignment capabilities.
β What's Been Implemented¶
Backend¶
New Endpoints¶
- GET
/api/v1/teams/{teamId}/members - Lists all members of a team
- Returns user info, role, and join date
- Requires: Team membership
-
Response:
-
DELETE
/api/v1/teams/{teamId}/members/{memberUserId} - Removes a member from the team
- Requires:
team.managepermission - Protections:
- Cannot remove yourself
- Cannot remove the team owner
- Automatically revokes the removed user's sessions
- Response:
Service Functions¶
list_team_members()
- Fetches all team members with join details
- Joins User, TeamMember, and Role tables
- Marks current user for UI highlighting
remove_team_member()
- Validates permissions and ownership
- Prevents self-removal and owner removal
- Automatically revokes sessions for security
Frontend¶
New Component: TeamMembersManagement¶
Location: /home/badeath/cave/mbpanel-main/frontend/src/features/teams/components/TeamMembersManagement.tsx
Features: - β List all team members with avatars - β Display role badges with color coding - β Show join dates formatted - β Inline role change (dropdown) - β Remove member button with confirmation - β Real-time loading states - β Error handling with user feedback - β Refresh button - β Empty state - β Permission-based UI (only managers see actions) - β Cannot remove yourself or the owner - β Automatic session revocation on removal
Props:
interface TeamMembersManagementProps {
teamId: number;
currentUserId: number;
currentUserPermissions: string[];
onMemberRemoved?: () => void;
}
Visual Features: - Member avatars with initials - Color-coded role badges (Owner: purple, Manager: blue, Developer: green) - "You" badge for current user - Email display for members with names - Formatted join dates - Disabled states during operations - Hover effects on table rows - Dark mode support
Updated TeamMember Interface¶
export interface TeamMember {
user_id: number;
email: string;
user_name?: string | null;
role_id: number;
role_name: string;
joined_at: string;
is_current_user?: boolean;
}
Updated Service Methods¶
getMembers(teamId: number)
- Updated to use new backend endpoint
- Returns properly typed members
removeMember(teamId: number, memberUserId: number)
- Updated with CSRF token support
- Proper error handling
Example Page¶
Location: /home/badeath/cave/mbpanel-main/frontend/src/app/team-management/page.tsx
Shows both components together: - TeamMembersManagement (list/remove members) - RoleManagement (create/edit roles)
π¨ UI Screenshots (Description)¶
Team Members Table¶
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β π₯ Team Members π (Refresh) β
β 3 members β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β MEMBER β ROLE β JOINED β ACTIONS β
βββββββββββββββββββββββΌββββββββββββββΌββββββββββββββΌββββββββββββ€
β π€ John Doe [You]β π‘οΈ Owner β Jan 1, 2026 β -- β
β john@example.com β β β β
βββββββββββββββββββββββΌββββββββββββββΌββββββββββββββΌββββββββββββ€
β π€ Jane Smith β [Manager βΌ] β Jan 5, 2026 β β Remove β
β jane@example.com β β β β
βββββββββββββββββββββββΌββββββββββββββΌββββββββββββββΌββββββββββββ€
β π€ Bob Dev β [DeveloperβΌ]β Jan 10, 2026β β Remove β
β bob@example.com β β β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
π Usage Examples¶
Basic Integration¶
import { TeamMembersManagement } from '@/features/teams/components';
<TeamMembersManagement
teamId={user.team_id}
currentUserId={user.id}
currentUserPermissions={user.permissions}
/>
With Callback¶
<TeamMembersManagement
teamId={user.team_id}
currentUserId={user.id}
currentUserPermissions={user.permissions}
onMemberRemoved={() => {
console.log('Member was removed - refresh other data if needed');
// Refresh team stats, etc.
}}
/>
Full Page Example¶
'use client';
import { RoleManagement, TeamMembersManagement } from '@/features/teams/components';
import { useAuth } from '@/features/auth/hooks/useAuth';
export default function TeamPage() {
const { user } = useAuth();
return (
<div className="space-y-6">
{/* Members list with remove capability */}
<TeamMembersManagement
teamId={user.team_id}
currentUserId={user.id}
currentUserPermissions={user.permissions}
/>
{/* Role management */}
<RoleManagement
teamId={user.team_id}
currentUserPermissions={user.permissions}
/>
</div>
);
}
π Security & Permissions¶
Backend Security¶
- Cross-Tenant Protection
- All endpoints verify user is in the requested team
-
current_user.team_idmust matchteam_idparameter -
Permission Checks
- Removing members requires
team.managepermission -
Viewing members requires team membership only
-
Owner Protection
- Cannot remove the team owner
-
Owner can only be changed via ownership transfer
-
Self-Protection
- Cannot remove yourself from the team
-
Must use "leave team" function instead
-
Session Revocation
- When a member is removed, their sessions are immediately revoked
- Prevents access with stale JWT tokens
Frontend Security¶
- Permission-Based UI
- Actions only visible if user has
team.manage -
Remove buttons disabled for owner and current user
-
Confirmation Dialogs
-
Confirm before removing any member
-
Error Display
- Clear error messages from backend
- User-friendly error handling
π§ Backend Files Modified¶
Created/Modified:¶
- β
backend/app/modules/teams/schemas.py- Added TeamMemberRead, TeamMembersListResponse, TeamMemberRemoveResponse - β
backend/app/modules/teams/service.py- Added list_team_members() and remove_team_member() - β
backend/app/modules/teams/router.py- Added GET /members and DELETE /members endpoints
π Frontend Files Created/Modified¶
Created:¶
- β
frontend/src/features/teams/components/TeamMembersManagement.tsx- Main component - β
frontend/src/app/team-management/page.tsx- Example page
Modified:¶
- β
frontend/src/features/teams/types/team.types.ts- Updated TeamMember interface - β
frontend/src/features/teams/services/teamService.ts- Updated getMembers() and removeMember() - β
frontend/src/features/teams/components/index.ts- Added export
π§ͺ Testing Guide¶
Backend Tests (Manual)¶
-
List Members
-
Remove Member
-
Test Protections
- Try removing yourself (should fail)
- Try removing owner (should fail)
- Try without
team.managepermission (should fail)
Frontend Tests¶
- Visual Test
- Navigate to
/team-management - Verify members load
- Check role badges display correctly
-
Verify "You" badge on current user
-
Interaction Test
- Click role dropdown (should show all roles)
- Change a member's role
- Click Remove on a member
- Confirm dialog appears
- Verify member is removed
-
Check member disappears from list
-
Permission Test
- Login as non-manager
- Verify actions are hidden
- Login as manager
- Verify actions are visible
π― Key Features Implemented¶
Member Display¶
- β Avatar with initials
- β Name and email display
- β Role badge with color coding
- β Join date formatting
- β "You" indicator
- β Member count in header
Member Management¶
- β List all team members
- β Change member roles (inline dropdown)
- β Remove members with confirmation
- β Refresh members list
- β Loading states during operations
- β Error handling with messages
Security¶
- β Cannot remove yourself
- β Cannot remove owner
- β Permission-based UI
- β Session revocation on removal
- β CSRF protection
UX Enhancements¶
- β Empty state message
- β Loading spinner
- β Disabled states during operations
- β Hover effects
- β Dark mode support
- β Responsive design
- β Accessible markup
π Next Steps¶
- Add Member Invitation to Component
-
Could add invite form directly in TeamMembersManagement
-
Add Bulk Actions
- Select multiple members
- Bulk role assignment
-
Bulk removal
-
Add Member Activity
- Last seen timestamp
-
Activity indicators
-
Add Search/Filter
- Search by name/email
-
Filter by role
-
Add Pagination
- For teams with many members
- Show members per page
β FAQ¶
Q: Can a user remove themselves? A: No, the backend prevents self-removal. Users should use a "Leave Team" function instead.
Q: What happens when a member is removed? A: Their team membership is deleted, and all their active sessions are revoked immediately.
Q: Can the owner be removed? A: No, ownership must be transferred first via the ownership transfer flow.
Q: Who can see the members list?
A: Any team member can view the list, but only users with team.manage permission can remove members.
Q: Can I change multiple roles at once? A: Currently no, but this could be added as a bulk action feature.
Q: What if I remove someone by mistake? A: They need to be re-invited to the team. Consider adding an "undo" feature in the future.