# 🤝 Como Funciona o Maktubia Friends

## 📖 **Visão Geral**

O **Maktubia Friends** é um sistema de amizades integrado ao sistema de pontos que permite que usuários:
- ✅ Adicionem outros usuários como amigos
- ✅ Transfiram pontos entre amigos (P2P)
- ✅ Recebam notificações de interações

---

## 🔄 **Fluxo Completo do Sistema**

### **Passo 1: Buscar Usuário**

O usuário **A** quer adicionar o usuário **B** como amigo.

#### Opções de Busca:
1. **Por código de usuário** (`user_code`): `MK000001`
2. **Por telefone**: `+258841234567`
3. **Por email**: `usuario@example.com`

#### Requisição:
```http
GET /api/friends/search?identifier=MK000001
Authorization: Bearer {token_do_usuario_A}
```

#### Resposta:
```json
{
  "success": true,
  "data": {
    "user_id": 2,
    "name": "João Silva",
    "user_code": "MK000002",
    "phone": "+258842345678",
    "email": "joao@example.com",
    "is_friend": false,      // Ainda não são amigos
    "can_add": true          // Pode adicionar
  }
}
```

---

### **Passo 2: Enviar Pedido de Amizade**

O usuário **A** envia um pedido de amizade para o usuário **B**.

#### Requisição:
```http
POST /api/friends/request
Authorization: Bearer {token_do_usuario_A}
Content-Type: application/json

{
  "identifier": "MK000002",  // ou phone ou email
  "message": "Olá! Vamos ser amigos?"  // opcional
}
```

#### O que acontece:
1. ✅ Sistema valida se **B** existe
2. ✅ Sistema verifica se **A** não está tentando adicionar a si mesmo
3. ✅ Sistema verifica se **A** e **B** já são amigos
4. ✅ Sistema verifica se já existe pedido pendente
5. ✅ Sistema cria registro em `friend_requests` com status `pending`
6. ✅ Sistema envia **notificação** para o usuário **B**

#### Banco de Dados:
```sql
-- Tabela: friend_requests
INSERT INTO friend_requests (
  from_user_id: 1,      -- ID do usuário A
  to_user_id: 2,        -- ID do usuário B
  status: 'pending',
  message: 'Olá! Vamos ser amigos?',
  created_at: NOW()
);
```

#### Resposta:
```json
{
  "success": true,
  "data": {
    "request_id": 1,
    "to_user_id": 2,
    "to_user_name": "João Silva",
    "to_user_code": "MK000002",
    "status": "pending",
    "created_at": "2024-11-02T15:30:00Z"
  },
  "message": "Pedido de amizade enviado com sucesso"
}
```

#### Notificação para B:
```json
{
  "type": "friend_request",
  "title": "Novo Pedido de Amizade",
  "message": "Maria Santos quer ser seu Maktubia Friend",
  "data": {
    "request_id": 1,
    "from_user_id": 1,
    "from_user_name": "Maria Santos",
    "from_user_code": "MK000001"
  }
}
```

---

### **Passo 3: Listar Pedidos Pendentes**

O usuário **B** vê todos os pedidos de amizade recebidos.

#### Requisição:
```http
GET /api/friends/requests
Authorization: Bearer {token_do_usuario_B}
```

#### Resposta:
```json
{
  "success": true,
  "data": [
    {
      "request_id": 1,
      "from_user_id": 1,
      "from_user_name": "Maria Santos",
      "from_user_code": "MK000001",
      "message": "Olá! Vamos ser amigos?",
      "created_at": "2024-11-02T15:30:00Z"
    }
  ],
  "count": 1
}
```

---

### **Passo 4: Aceitar Pedido de Amizade**

O usuário **B** aceita o pedido do usuário **A**.

#### Requisição:
```http
POST /api/friends/requests/1/accept
Authorization: Bearer {token_do_usuario_B}
```

#### O que acontece:
1. ✅ Sistema valida que o pedido existe e é para o usuário **B**
2. ✅ Sistema atualiza status do pedido para `accepted`
3. ✅ Sistema cria registro em `maktubia_friends`
4. ✅ Sistema envia **notificação** para o usuário **A**

#### Banco de Dados:
```sql
-- 1. Atualizar pedido
UPDATE friend_requests 
SET status = 'accepted', responded_at = NOW()
WHERE request_id = 1;

-- 2. Criar amizade (sempre user1_id < user2_id)
INSERT INTO maktubia_friends (
  user1_id: 1,    -- Menor ID
  user2_id: 2,    -- Maior ID
  created_at: NOW()
);
```

#### Resposta:
```json
{
  "success": true,
  "data": {
    "friendship_id": 1,
    "friend_id": 1,
    "friend_name": "Maria Santos",
    "friend_code": "MK000001"
  },
  "message": "Pedido de amizade aceito com sucesso!"
}
```

#### Notificação para A:
```json
{
  "type": "friend_request_accepted",
  "title": "Pedido Aceito",
  "message": "João Silva aceitou seu pedido de amizade!",
  "data": {
    "friend_id": 2,
    "friend_name": "João Silva"
  }
}
```

---

### **Passo 5: Listar Amigos**

Agora ambos podem ver um ao outro na lista de amigos.

#### Requisição:
```http
GET /api/friends
Authorization: Bearer {token_do_usuario_A}
```

#### Resposta:
```json
{
  "success": true,
  "data": [
    {
      "user_id": 2,
      "friend_id": 2,
      "name": "João Silva",
      "user_code": "MK000002",
      "phone": "+258842345678",
      "email": "joao@example.com",
      "friendship_date": "2024-11-02T15:35:00Z",
      "last_interaction_at": null
    }
  ],
  "count": 1,
  "statistics": {
    "total_friends": 1,
    "pending_requests": 0,
    "transfers_with_friends": {
      "total": 0,
      "total_points": 0
    }
  }
}
```

---

### **Passo 6: Transferir Pontos (P2P)**

Agora que são amigos, o usuário **A** pode transferir pontos para o usuário **B**.

#### Requisição:
```http
POST /api/transfers
Authorization: Bearer {token_do_usuario_A}
Content-Type: application/json

{
  "to_user_id": 2,
  "amount": 100,  // pontos
  "description": "Presente de aniversário"  // opcional
}
```

#### Validações:
1. ✅ Verifica se **A** e **B** são amigos (OBRIGATÓRIO)
2. ✅ Verifica se **A** tem saldo suficiente
3. ✅ Verifica se `amount` > 0
4. ✅ Verifica se não está transferindo para si mesmo

#### O que acontece:
1. ✅ Sistema valida amizade entre **A** e **B**
2. ✅ Sistema verifica saldo do usuário **A**
3. ✅ Sistema debita pontos da carteira de **A**
4. ✅ Sistema credita pontos na carteira de **B**
5. ✅ Sistema registra transferência em `transfers`
6. ✅ Sistema registra histórico em `points_history`
7. ✅ Sistema atualiza `last_interaction_at` na amizade
8. ✅ Sistema envia **notificação** para o usuário **B**

#### Banco de Dados:
```sql
-- 1. Debitar de A
UPDATE wallets 
SET points = points - 100, balance = balance - 100
WHERE user_id = 1;

-- 2. Creditar em B
UPDATE wallets 
SET points = points + 100, balance = balance + 100
WHERE user_id = 2;

-- 3. Registrar transferência
INSERT INTO transfers (
  from_user_id: '1',
  to_user_id: '2',
  amount: 100,
  description: 'Presente de aniversário',
  status: 'completed',
  created_at: NOW()
);

-- 4. Registrar histórico de A (debitou)
INSERT INTO points_history (
  user_id: '1',
  delta: -100,
  reason: 'transfer_sent',
  related_id: 'TRF_123',
  created_at: NOW()
);

-- 5. Registrar histórico de B (recebeu)
INSERT INTO points_history (
  user_id: '2',
  delta: 100,
  reason: 'transfer_received',
  related_id: 'TRF_123',
  created_at: NOW()
);

-- 6. Atualizar última interação
UPDATE maktubia_friends 
SET last_interaction_at = NOW()
WHERE (user1_id = 1 AND user2_id = 2) 
   OR (user1_id = 2 AND user2_id = 1);
```

#### Resposta:
```json
{
  "success": true,
  "data": {
    "transfer_id": "TRF_1705327800000_abc123",
    "from_user_id": 1,
    "to_user_id": 2,
    "amount": 100,
    "description": "Presente de aniversário",
    "status": "completed",
    "new_balance": 400  // Novo saldo de A
  },
  "message": "Transferência de 100 pontos realizada com sucesso!"
}
```

#### Notificação para B:
```json
{
  "type": "points_transfer_received",
  "title": "Pontos Recebidos",
  "message": "Você recebeu 100 pontos de Maria Santos",
  "data": {
    "transfer_id": "TRF_1705327800000_abc123",
    "from_user_id": 1,
    "from_user_name": "Maria Santos",
    "amount": 100,
    "description": "Presente de aniversário"
  }
}
```

---

### **Passo 7: Tentativa de Transferência Sem Ser Amigo**

Se o usuário **A** tentar transferir pontos para o usuário **C** (que não é amigo):

#### Requisição:
```http
POST /api/transfers
Authorization: Bearer {token_do_usuario_A}
Content-Type: application/json

{
  "to_user_id": 3,
  "amount": 100
}
```

#### Resposta (Erro):
```json
{
  "success": false,
  "error": {
    "statusCode": 403,
    "message": "Você só pode transferir pontos para seus Maktubia Friends. Adicione este usuário como amigo primeiro.",
    "code": "FORBIDDEN"
  }
}
```

---

## 📊 **Estrutura do Banco de Dados**

### **Tabela: `friend_requests`**

Armazena pedidos de amizade pendentes.

| Campo | Tipo | Descrição |
|-------|------|-----------|
| `request_id` | SERIAL | ID único do pedido |
| `from_user_id` | INTEGER | ID do usuário que enviou |
| `to_user_id` | INTEGER | ID do usuário que recebeu |
| `status` | VARCHAR | `pending`, `accepted`, `rejected`, `cancelled` |
| `message` | TEXT | Mensagem opcional |
| `created_at` | TIMESTAMP | Data de criação |
| `responded_at` | TIMESTAMP | Data de resposta |

**Regra:** Apenas 1 pedido pendente por par de usuários (índice único parcial).

### **Tabela: `maktubia_friends`**

Armazena amizades aceitas.

| Campo | Tipo | Descrição |
|-------|------|-----------|
| `friendship_id` | SERIAL | ID único da amizade |
| `user1_id` | INTEGER | ID do usuário 1 (sempre menor) |
| `user2_id` | INTEGER | ID do usuário 2 (sempre maior) |
| `created_at` | TIMESTAMP | Data de criação |
| `last_interaction_at` | TIMESTAMP | Última interação (transferência) |

**Regra:** Sempre `user1_id < user2_id` para evitar duplicatas.

---

## 🔒 **Regras de Negócio**

### **Amizades:**
1. ✅ Um usuário não pode adicionar a si mesmo
2. ✅ Não pode haver mais de 1 pedido pendente entre dois usuários
3. ✅ Usuários não podem ser amigos de si mesmos
4. ✅ Ao aceitar pedido, ambos ficam na lista de amigos automaticamente
5. ✅ Ao rejeitar pedido, não cria amizade (mas pode tentar novamente depois)

### **Transferências P2P:**
1. ✅ **OBRIGATÓRIO:** Usuários devem ser amigos
2. ✅ Remetente deve ter saldo suficiente
3. ✅ Valor deve ser maior que zero
4. ✅ Não pode transferir para si mesmo
5. ✅ Transferências são registradas no histórico
6. ✅ Saldo é atualizado em tempo real
7. ✅ Última interação é atualizada automaticamente

---

## 🔔 **Sistema de Notificações**

### **Tipos de Notificação:**

#### 1. **Pedido de Amizade (`friend_request`)**
- **Quem recebe:** Usuário que recebe o pedido
- **Quando:** Alguém envia pedido de amizade
- **Mensagem:** `"{nome} quer ser seu Maktubia Friend"`

#### 2. **Pedido Aceito (`friend_request_accepted`)**
- **Quem recebe:** Usuário que enviou o pedido
- **Quando:** Pedido é aceito
- **Mensagem:** `"{nome} aceitou seu pedido de amizade!"`

#### 3. **Pontos Recebidos (`points_transfer_received`)**
- **Quem recebe:** Usuário que recebe os pontos
- **Quando:** Amigo transfere pontos
- **Mensagem:** `"Você recebeu {pontos} pontos de {nome}"`

---

## 🎯 **Endpoints Disponíveis**

### **Amizades:**
- `POST /api/friends/request` - Enviar pedido de amizade
- `GET /api/friends/requests` - Listar pedidos pendentes
- `POST /api/friends/requests/:id/accept` - Aceitar pedido
- `POST /api/friends/requests/:id/reject` - Rejeitar pedido
- `GET /api/friends` - Listar amigos
- `GET /api/friends/search` - Buscar usuário
- `DELETE /api/friends/:friendId` - Remover amizade

### **Transferências:**
- `POST /api/transfers` - Transferir pontos (requer amizade)
- `GET /api/transfers` - Listar transferências
- `GET /api/transfers/:id` - Obter transferência específica

---

## 📱 **Exemplo de Uso no App Mobile**

### **1. Tela: Buscar Amigo**
```
[Buscar por código, telefone ou email...]
┌─────────────────────────────────┐
│ 🔍 MK000002                      │
└─────────────────────────────────┘

Resultado:
┌─────────────────────────────────┐
│ 👤 João Silva                   │
│ 📱 +258842345678                │
│ ✉️ joao@example.com             │
│ 📝 MK000002                     │
│ [Adicionar como Amigo]          │
└─────────────────────────────────┘
```

### **2. Tela: Pedidos Pendentes**
```
┌─────────────────────────────────┐
│ 📩 Maria Santos                 │
│ "Olá! Vamos ser amigos?"        │
│ [Aceitar]  [Rejeitar]           │
└─────────────────────────────────┘
```

### **3. Tela: Lista de Amigos**
```
┌─────────────────────────────────┐
│ 👫 Meus Amigos (3)              │
│                                  │
│ 👤 João Silva                    │
│ 📱 +258842345678                │
│ [Transferir Pontos]             │
│                                  │
│ 👤 Maria Santos                 │
│ 📱 +258841234567                │
│ [Transferir Pontos]             │
└─────────────────────────────────┘
```

### **4. Tela: Transferir Pontos**
```
┌─────────────────────────────────┐
│ 💸 Transferir Pontos            │
│                                  │
│ Para: João Silva                │
│ Quantidade: [100] pontos        │
│ Descrição: [Presente]           │
│                                  │
│ Seu saldo: 500 pontos           │
│ Saldo após: 400 pontos          │
│                                  │
│ [Confirmar Transferência]        │
└─────────────────────────────────┘
```

---

## ✅ **Validações Implementadas**

- ✅ Validação de amizade obrigatória para transferências
- ✅ Validação de saldo suficiente
- ✅ Validação de identificador único (user_code, phone, email)
- ✅ Prevenção de duplicatas (pedidos, amizades)
- ✅ Prevenção de auto-adicionar como amigo
- ✅ Prevenção de auto-transferir pontos
- ✅ Notificações híbridas (Socket.io + FCM)

---

## 🎉 **Resumo**

O **Maktubia Friends** funciona como uma rede social de pontos:

1. **Usuários buscam outros usuários** por código, telefone ou email
2. **Enviam pedidos de amizade** com mensagem opcional
3. **Recebem notificações** quando alguém quer ser amigo
4. **Aceitam ou rejeitam** pedidos
5. **Listam seus amigos** com informações completas
6. **Transferem pontos** entre amigos (P2P)
7. **Recebem notificações** quando recebem pontos

**Regra principal:** Apenas amigos podem transferir pontos entre si, garantindo segurança e controle nas transferências P2P.

---

**Status:** ✅ Sistema 100% Funcional e Pronto para Uso!

