> ## 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 assinaturas

> Referência interna para a API Memberships — CRUD de membros, gerenciamento de convites, alterações de funções/grupos e aplicação de controle de acesso.

> **Documentação interna para desenvolvedores.** Esta página aborda a API Memberships: gerenciamento de membros da equipe, atribuição de grupos de acesso e ciclo de vida de convites. Não se destina a usuários finais.

***

## Mapa de rotas

| Método   | Ponto final             | Arquivo manipulador         | Descrição                     |
| -------- | ----------------------- | --------------------------- | ----------------------------- |
| `GET`    | `/api/memberships`      | `memberships/route.ts`      | Listar membros da organização |
| `POST`   | `/api/memberships`      | `memberships/route.ts`      | Convide um novo membro        |
| `GET`    | `/api/memberships/[id]` | `memberships/[id]/route.ts` | Obter membro por ID           |
| `PATCH`  | `/api/memberships/[id]` | `memberships/[id]/route.ts` | Atualizar função/grupo        |
| `DELETE` | `/api/memberships/[id]` | `memberships/[id]/route.ts` | Remover membro                |

***

## Padrão de autenticação

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

***

## Esquema de objeto de associação

```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 do convite

```
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
```

***

## Acessar atribuição de grupo

Ao atualizar um membro (`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
```

***

## Prevenção de auto-remoção

Os membros não podem se remover. O servidor verifica:

```ts theme={null}
if (membershipToDelete.userId === req.session.user.id) {
  return NextResponse.json({ error: 'Cannot remove yourself' }, { status: 403 });
}
```

***

## Problemas conhecidos/pegadinhas

* **Proteção do último administrador:** As organizações devem sempre ter pelo menos um administrador. A tentativa de remover o último administrador retorna `403`.
* **Status suspenso:** Não totalmente implementado em todos os fluxos — tratado como `active` em alguns caminhos de código legado. Verifique antes de usar o status `suspended` em novos recursos.
* **Cache de permissões:** As permissões são armazenadas em cache na sessão. Depois de alterar o grupo de acesso de um membro, ele deverá efetuar logout e login novamente para que as alterações entrem em vigor nas sessões existentes.
