# 🤝 Sistema de Maktubia Friends e Transferências P2P

## 📋 **Visão Geral**

Sistema completo de amizades e transferências ponto-a-ponto (P2P) entre clientes, com validação obrigatória de amizade para transferências.

---

## 🎯 **Funcionalidades Principais**

### 1. **Sistema de Amizades (Maktubia Friends)**
- ✅ Cliente pode enviar pedido de amizade por `user_code`, `phone` ou `email`
- ✅ Receptor recebe notificação de pedido de amizade
- ✅ Receptor pode aceitar ou rejeitar pedido
- ✅ Ao aceitar, ambos ficam na lista de amigos
- ✅ Apenas amigos podem transferir pontos entre si

### 2. **Transferências P2P**
- ✅ Validação obrigatória: só amigos podem transferir pontos
- ✅ Receptor recebe notificação de pontos recebidos
- ✅ Registro completo no histórico de pontos
- ✅ Atualização automática de saldo em ambas carteiras

### 3. **Notificações**
- ✅ **Novo estabelecimento criado** → Todos os clientes recebem notificação
- ✅ **Nova compra realizada** → Gestores do estabelecimento recebem notificação (web)
- ✅ **Compra aprovada** → Cliente específico recebe notificação
- ✅ **Pedido de amizade** → Receptor recebe notificação
- ✅ **Transferência P2P** → Receptor recebe notificação

---

## 🗄️ **Estrutura do Banco de Dados**

### **Tabela: `users` (Atualizada)**
```sql
ALTER TABLE users 
ADD COLUMN user_code VARCHAR(20) UNIQUE;

-- Garantir phone único para busca de amigos
ALTER TABLE users 
ADD CONSTRAINT users_phone_unique UNIQUE (phone);
```

**Campos:**
- `user_code`: Código único para identificação (ex: MK000001)
- `phone`: Telefone único (usado para buscar amigos)

### **Tabela: `friend_requests` (Pedidos de Amizade)**
```sql
CREATE TABLE friend_requests (
    request_id SERIAL PRIMARY KEY,
    from_user_id INTEGER NOT NULL REFERENCES users(user_id) ON DELETE CASCADE,
    to_user_id INTEGER NOT NULL REFERENCES users(user_id) ON DELETE CASCADE,
    request_type VARCHAR(20) NOT NULL DEFAULT 'user_code',
    requested_identifier VARCHAR(100),
    status VARCHAR(20) NOT NULL DEFAULT 'pending' CHECK (status IN ('pending', 'accepted', 'rejected', 'cancelled')),
    message TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    responded_at TIMESTAMP
);

-- Índice único parcial: apenas um pedido pendente entre dois usuários
CREATE UNIQUE INDEX idx_friend_requests_unique_pending 
ON friend_requests(from_user_id, to_user_id) 
WHERE status = 'pending';
```

### **Tabela: `maktubia_friends` (Amizades Aceitas)**
```sql
CREATE TABLE maktubia_friends (
    friendship_id SERIAL PRIMARY KEY,
    user1_id INTEGER NOT NULL REFERENCES users(user_id) ON DELETE CASCADE,
    user2_id INTEGER NOT NULL REFERENCES users(user_id) ON DELETE CASCADE,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    last_interaction_at TIMESTAMP,
    
    UNIQUE(user1_id, user2_id),
    CHECK(user1_id < user2_id)  -- Evita duplicatas (sempre user1_id < user2_id)
);
```

---

## 📡 **Endpoints da API**

### **Amizades (`/api/friends`)**

#### 1. Enviar Pedido de Amizade
```http
POST /api/friends/request
Authorization: Bearer {token}

{
  "identifier": "MK000001",  // user_code, phone ou email
  "message": "Olá! Vamos ser amigos?"  // opcional
}
```

**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-01-15T10:30:00Z"
  },
  "message": "Pedido de amizade enviado com sucesso"
}
```

#### 2. Listar Pedidos Pendentes
```http
GET /api/friends/requests
Authorization: Bearer {token}
```

**Resposta:**
```json
{
  "success": true,
  "data": [
    {
      "request_id": 1,
      "from_user_id": 3,
      "from_user_name": "Maria Santos",
      "from_user_code": "MK000003",
      "message": "Olá! Vamos ser amigos?",
      "created_at": "2024-01-15T10:30:00Z"
    }
  ],
  "count": 1
}
```

#### 3. Aceitar Pedido de Amizade
```http
POST /api/friends/requests/:id/accept
Authorization: Bearer {token}
```

**Resposta:**
```json
{
  "success": true,
  "data": {
    "friendship_id": 1,
    "friend_id": 3,
    "friend_name": "Maria Santos",
    "friend_code": "MK000003"
  },
  "message": "Pedido de amizade aceito com sucesso!"
}
```

#### 4. Rejeitar Pedido de Amizade
```http
POST /api/friends/requests/:id/reject
Authorization: Bearer {token}
```

#### 5. Listar Amigos
```http
GET /api/friends
Authorization: Bearer {token}
```

**Resposta:**
```json
{
  "success": true,
  "data": [
    {
      "user_id": 3,
      "friend_id": 3,
      "name": "Maria Santos",
      "user_code": "MK000003",
      "phone": "+258841234567",
      "email": "maria@example.com",
      "friendship_date": "2024-01-15T10:35:00Z",
      "last_interaction_at": "2024-01-20T14:30:00Z"
    }
  ],
  "count": 1
}
```

#### 6. Buscar Usuário por Identificador
```http
GET /api/friends/search?identifier=MK000001
Authorization: Bearer {token}
```

**Resposta:**
```json
{
  "success": true,
  "data": {
    "user_id": 2,
    "name": "João Silva",
    "user_code": "MK000002",
    "phone": "+258842345678",
    "email": "joao@example.com",
    "is_friend": false,
    "can_add": true
  }
}
```

#### 7. Remover Amizade
```http
DELETE /api/friends/:friendId
Authorization: Bearer {token}
```

---

### **Transferências P2P (`/api/transfers`)**

#### 1. Transferir Pontos
```http
POST /api/transfers
Authorization: Bearer {token}

{
  "to_user_id": 3,
  "amount": 100,  // pontos
  "description": "Presente de aniversário"  // opcional
}
```

**Validações:**
- ✅ Usuários devem ser amigos
- ✅ Remetente deve ter saldo suficiente
- ✅ `amount` deve ser maior que zero

**Resposta (Sucesso):**
```json
{
  "success": true,
  "data": {
    "transfer_id": "TRF_1705327800000_abc123",
    "from_user_id": 1,
    "to_user_id": 3,
    "amount": 100,
    "description": "Presente de aniversário",
    "status": "completed",
    "new_balance": 400
  },
  "message": "Transferência de 100 pontos realizada com sucesso!"
}
```

**Resposta (Erro - Não são amigos):**
```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"
  }
}
```

#### 2. Listar Transferências
```http
GET /api/transfers?page=1&limit=20&type=all
Authorization: Bearer {token}
```

**Query Params:**
- `page`: Número da página (padrão: 1)
- `limit`: Itens por página (padrão: 20)
- `type`: `sent` | `received` | `all` (padrão: `all`)

**Resposta:**
```json
{
  "success": true,
  "data": [
    {
      "transfer_id": "TRF_1705327800000_abc123",
      "from_user_id": 1,
      "from_user_name": "João Silva",
      "from_user_code": "MK000001",
      "to_user_id": 3,
      "to_user_name": "Maria Santos",
      "to_user_code": "MK000003",
      "amount": 100,
      "description": "Presente de aniversário",
      "status": "completed",
      "created_at": "2024-01-15T10:30:00Z",
      "is_sent": true,
      "is_received": false
    }
  ],
  "pagination": {
    "total": 10,
    "page": 1,
    "limit": 20,
    "totalPages": 1,
    "hasNextPage": false,
    "hasPrevPage": false
  }
}
```

#### 3. Obter Transferência por ID
```http
GET /api/transfers/:id
Authorization: Bearer {token}
```

---

## 🔔 **Sistema de Notificações**

### **Tipos de Notificação**

#### 1. **Novo Estabelecimento (`new_establishment`)**
- **Quem recebe:** Todos os clientes (role = 'user')
- **Quando:** Ao criar novo estabelecimento
- **Mensagem:** `"{nome} foi adicionado! Confira as ofertas e ganhe pontos!"`

#### 2. **Nova Compra (`new_purchase`)**
- **Quem recebe:** Gestores do estabelecimento (criador + admins)
- **Quando:** Cliente escaneia QR code e cria compra
- **Mensagem:** `"Cliente fez uma compra de {valor} MZN. Pendente de aprovação."`

#### 3. **Compra Aprovada (`purchase_approved`)**
- **Quem recebe:** Cliente que fez a compra
- **Quando:** Gestor aprova compra
- **Mensagem:** `"Sua compra de {valor} MZN foi aprovada! Você ganhou {pontos} pontos!"`

#### 4. **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"`

#### 5. **Pedido Aceito (`friend_request_accepted`)**
- **Quem recebe:** Usuário que enviou o pedido
- **Quando:** Pedido de amizade é aceito
- **Mensagem:** `"{nome} aceitou seu pedido de amizade!"`

#### 6. **Pontos Recebidos (`points_transfer_received`)**
- **Quem recebe:** Cliente que recebe os pontos
- **Quando:** Amigo transfere pontos P2P
- **Mensagem:** `"Você recebeu {pontos} pontos de {nome}"`

---

## 🔒 **Regras de Negócio**

### **Amizades**
1. ✅ Cliente não pode adicionar a si mesmo
2. ✅ Não pode enviar mais de um pedido pendente para o mesmo usuário
3. ✅ Cliente não pode ser amigo de si mesmo
4. ✅ Ao aceitar pedido, ambos ficam na lista de amigos
5. ✅ Apenas amigos podem transferir pontos entre si

### **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 `points_history`
6. ✅ Saldo é atualizado em tempo real em ambas carteiras

---

## 🚀 **Como Usar**

### **1. Criar Estabelecimento**
```javascript
POST /api/establishments
// → Todos os clientes recebem notificação
```

### **2. Cliente Faz Compra**
```javascript
POST /api/purchases/scan
{
  "qrCode": "MAKTUBIA_SHOP_001",
  "purchaseAmount": 500
}
// → Gestores do estabelecimento recebem notificação
```

### **3. Gestor Aprova Compra**
```javascript
POST /api/purchases/:id/confirm
// → Cliente recebe notificação de compra aprovada
```

### **4. Enviar Pedido de Amizade**
```javascript
POST /api/friends/request
{
  "identifier": "MK000002",  // ou phone ou email
  "message": "Olá!"
}
// → Receptor recebe notificação
```

### **5. Aceitar Pedido**
```javascript
POST /api/friends/requests/:id/accept
// → Remetente recebe notificação de aceitação
```

### **6. Transferir Pontos**
```javascript
POST /api/transfers
{
  "to_user_id": 3,
  "amount": 100,
  "description": "Presente"
}
// → Receptor recebe notificação de pontos recebidos
```

---

## ✅ **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
- ✅ Notificações híbridas (Socket.io + FCM)

---

## 📝 **Arquivos Criados**

1. `create-maktubia-friends-system.js` - Script de criação das tabelas
2. `models/FriendsModel.js` - Modelo para gerenciar amizades
3. `controllers/friendsController.js` - Controller de amizades
4. `controllers/transferController.js` - Controller de transferências P2P
5. `routes/friendsRoutes.js` - Rotas de amizades
6. `routes/transferRoutes.js` - Rotas de transferências
7. `utils/notificationHelpers.js` - Helpers para notificações em massa

---

## 🎉 **Sistema Completo e Funcional!**

O sistema de Maktubia Friends e transferências P2P está completamente implementado e integrado com o sistema de notificações híbrido (Socket.io + FCM).




