Módulos
Friends
Sistema de amizades simétricas + bloqueios direcionais.
Visão geral
Sistema social com duas relações:
- Friendship — simétrica em significado, com fluxo pedido/aceite (modelado em uma única tabela com
requester_id/receiver_id) - Block — assimétrica e direcional (A bloqueia B é diferente de B bloqueia A; podem coexistir)
Bloquear um amigo derruba a amizade automaticamente, desconecta chat 1-1 entre os dois, e esconde conteúdo de ambos os lados.
Entidades principais
| Tabela | O que guarda |
|---|---|
friendships | Pedidos pending + amizades aceitas |
user_blocks | Bloqueios direcionais |
Endpoints
11 endpoints divididos em duas seções:
Pedidos / amigos (montado em /friends):
| Endpoint | Resumo |
|---|---|
POST /friends/requests | Enviar pedido |
GET /friends/requests/received | Pedidos pra mim |
GET /friends/requests/sent | Pedidos que enviei |
POST /friends/requests/:id/accept | Aceitar |
POST /friends/requests/:id/reject | Rejeitar |
DELETE /friends/requests/:id | Cancelar enviado |
GET /friends | Minha lista de amigos |
DELETE /friends/:friendId | Desfazer amizade |
Blocks (montado em /blocks):
| Endpoint | Resumo |
|---|---|
POST /blocks/:userId | Bloquear |
DELETE /blocks/:userId | Desbloquear |
GET /blocks | Lista de bloqueados |
Fluxos
Pedido + aceite
Bloquear (cascade)
Listar amigos (denormalização)
Eventos de socket
| Evento | Quando |
|---|---|
notification:new (friend_request) | Pedido recebido |
notification:new (friend_accepted) | Aceito |
conversation:refresh | Block/unblock — força frontend re-fetch da lista |
friend:link (interno chat) | linkFriendship após aceite — vincula sockets ao mesmo room DM |
friend:unlink (interno chat) | unlinkFriendship após remove ou block |
Edge cases e regras especiais
- Mutual interest: se A pede a B e já existe pending B→A, o backend aceita automaticamente (não cria duplicado)
- Block desfaz amizade silenciosamente — sem notificação ao bloqueado de que foi bloqueado
- Unblock NÃO restaura amizade — o user precisa refazer pedido. Block é "ruptura limpa".
- Tentar adicionar quem te bloqueou: backend retorna BLOCKED — frontend pode mostrar genérico "não foi possível enviar"
- Amizade não existe sem aceite —
friend_acceptedé o gatilho real (pendingé "interesse expresso") - Cancel ≠ Reject — cancel é o requester desfazendo, reject é o receiver recusando. Ambos viram DELETE; sem notificação em qualquer caso
- Privacy interage com amizade — perfil
friends_onlyrevela tudo só pra accepted friends
Dependências entre módulos
- Notifications — friend_request, friend_accepted
- Chat — linkFriendship/unlinkFriendship pra conectar/desconectar DM 1-1
- Users — privacy gating em getProfile depende de areFriends
- Posts/Feed —
friends_onlyposts só aparecem pra friends accepted - Collections / Items —
friends_onlycollections seguem mesma regra