Módulo: Miembros
Scope
| Tipo de organización | Acceso |
|---|---|
| Empresa | ✅ |
| Agencia | ✅ |
| Reclutador independiente | ❌ |
Permisos por rol
| Acción | Disponible | Permiso |
|---|---|---|
| Ver lista de miembros | ✅ | memberships:read |
| Invitar miembro | ✅ | memberships:invite |
| Asignar rol | ✅ | memberships:update-role |
| Actualizar estado | ✅ | memberships:update-status |
¿Qué es?
Gestión de los miembros (usuarios) de la organización. Permite ver quién pertenece al equipo, su rol y estado, invitar nuevos miembros, y administrar accesos.
¿Qué puede hacer el usuario?
- Ver lista paginada de miembros con scroll infinito
- Buscar miembros por nombre, email o rol
- Filtrar por estado (Todos, Activo, Invitado, Suspendido, Retirado)
- Invitar nuevos miembros por email con rol seleccionado
- Asignar rol a un miembro (próximamente)
- Actualizar estado de un miembro (próximamente)
Flujo del usuario
Listar miembros
1. Abre "Equipo" → tab "Usuarios"
2. Ve lista con nombre, email, rol y estado
3. Busca por nombre/email/rol
4. Filtra por status con dropdown
5. Scroll infinito para cargar más
Invitar miembro
1. Presiona "Invitar" en el header
2. Se abre modal bottom sheet
3. Ingresa email del invitado
4. Selecciona rol de la lista de roles asignables
5. Confirma → se envía email de invitación
6. Navega automáticamente al tab "Invitaciones"
Reglas de negocio
- Un usuario solo puede pertenecer a un tenant
- Admins no pueden suspender/retirar su propia membresía
- La invitación requiere email válido + rol seleccionado
- Los roles asignables vienen del endpoint
/roles/assignable - El filtro de búsqueda es client-side sobre datos ya cargados
- El filtro de status es client-side (no se envía como query param)
Arquitectura
lib/features/team/
├── application/
│ ├── members_cubit.dart # loadMembers, loadMore, updateStatus, assignRole, loadAssignableRoles
│ └── members_state.dart # MembersStatus enum, members list, assignableRoles
├── data/
│ ├── datasources/
│ │ └── team_remote_datasource.dart # listMembers, updateMemberStatus, assignMemberRole
│ ├── models/
│ │ └── membership_model.dart # MembershipModel, MembershipsResponseModel
│ └── repositories/
│ └── team_repository_impl.dart
├── domain/
│ ├── entities/
│ │ └── membership.dart # Membership, MemberUser, MemberAvatar, MemberRole (Equatable)
│ └── repositories/
│ └── team_repository.dart
└── presentation/
└── tabs/
└── members_tab.dart # BlocProvider + BlocBuilder, invite modal
Endpoints API
| Método | Endpoint | Permiso | Descripción |
|---|---|---|---|
| GET | /memberships | memberships:read | Lista miembros (paginado, search, sort, status) |
| PATCH | /memberships/:id/status | memberships:update-status | Actualizar estado (ACTIVE, SUSPENDED, REMOVED) |
| PATCH | /memberships/:id/role | memberships:update-role | Asignar rol a miembro |
| GET | /roles/assignable | roles:read | Roles asignables para invitaciones |
| POST | /memberships/invitations | memberships:invite | Crear invitación |
Registro DI
- Cubit:
Factory(nueva instancia por pantalla)
getIt<MembersCubit>()
Localización
✅ Completa — claves con prefijo members en ambos ARB:
- Filtros:
membersFilterAll,membersFilterActive,membersFilterInvited, etc. - UI:
membersSubtitle,membersCount,membersSearchHint,membersInviteButton - Roles:
membersRoleAdmin,membersRoleHr,membersRoleViewer,membersRoleAgencyAdmin,membersRoleRecruiter - Status:
membersStatusActive,membersStatusInactive,membersStatusSuspended - Invite form:
membersInviteTitle,membersInviteDescription,membersEmailLabel, etc.