> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zappway.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# API de membresías

> Referencia interna para la API de Membresías: CRUD de miembros, administración de invitaciones, cambios de rol/grupo y aplicación del control de acceso.

> **Documentación interna para desarrolladores.** Esta página cubre la API de Membresías: administración de miembros del equipo, asignación de grupos de acceso y ciclo de vida de las invitaciones. No está destinado a usuarios finales.

***

## Mapa de ruta

| Método   | Punto final             | Archivo de controlador      | Descripción                        |
| -------- | ----------------------- | --------------------------- | ---------------------------------- |
| `GET`    | `/api/memberships`      | `memberships/route.ts`      | Listar miembros de la organización |
| `POST`   | `/api/memberships`      | `memberships/route.ts`      | Invitar a un nuevo miembro         |
| `GET`    | `/api/memberships/[id]` | `memberships/[id]/route.ts` | Obtener miembro por ID             |
| `PATCH`  | `/api/memberships/[id]` | `memberships/[id]/route.ts` | Actualizar rol/grupo               |
| `DELETE` | `/api/memberships/[id]` | `memberships/[id]/route.ts` | Eliminar miembro                   |

***

## Patrón de autenticación

```ts theme={null}
withPermissionRoute(req, {
  permission: 'team.read',    // reads
  permission: 'team.invite',  // invitations
  permission: 'team.manage',  // updates, removals
}, handler)
```

***

## Esquema de objetos de membresía

```ts theme={null}
interface Membership {
  id: string;
  organizationId: string;
  userId: string;
  user: { id: string; name: string; email: string; };
  role: 'admin' | 'member';
  status: 'active' | 'invited' | 'suspended';
  accessGroupIds: string[];
  invitedAt: string | null;
  joinedAt: string | null;
  createdAt: string;
}
```

***

## Ciclo de vida de la invitación

```
1. Admin: POST /api/memberships { email, accessGroupId }
   → status: 'invited', invitedAt = now()
   → Email sent with invite link

2. Invitee clicks link → GET /api/auth/invite?token=...
   → status: 'active', joinedAt = now()
   → User created (if first login)

3. Admin: DELETE /api/memberships/[id]
   → Removes membership (cascade: removes from access groups)
   → User loses org access immediately
```

***

## Asignación de grupo de acceso

Al actualizar un miembro (`PATCH /api/memberships/[id]`):

```ts theme={null}
// Body: { accessGroupIds: string[] }
// This REPLACES the member's group assignments entirely
// Validates all group IDs belong to the same organization
// Records change in permission audit log
```

***

## Prevención de autoeliminación

Los miembros no pueden eliminarse a sí mismos. El servidor comprueba:
***CÓDIGO\_BLOQUE\_4***

***

## Problemas conocidos / Problemas

* **Última protección del administrador:** Las organizaciones siempre deben tener al menos un administrador. Al intentar eliminar al último administrador se devuelve `403`.
* **Estado suspendido:** No implementado completamente en todos los flujos; tratado como `active` en algunas rutas de código heredadas. Verifique antes de usar el estado `suspended` en nuevas funciones.
* **Caché de permisos:** Los permisos se almacenan en caché en la sesión. Después de cambiar el grupo de acceso de un miembro, este debe cerrar sesión y volver a iniciarla para que los cambios surtan efecto en las sesiones existentes.
