# 🔍 Sistema de Rastreabilidade Completa de Pontos

## 📋 Visão Geral

Sistema implementado para permitir rastreabilidade completa de pontos, sabendo exatamente de onde cada ponto veio e sua cadeia completa de transferências.

---

## 🎯 Funcionalidades

### 1. **Rastreamento de Origem**
- Cada ponto registrado no ledger com origem original (compra, campanha, bônus, etc.)
- Cadeia completa de transferências preservada
- Sistema FIFO (First In, First Out) para transferências

### 2. **Consultas de Rastreabilidade**
- Rastrear origem de qualquer montante de pontos
- Ver cadeia completa de um ponto específico
- Resumo de pontos agrupados por origem original
- Listar todas as entradas do ledger

---

## 🗄️ Estrutura do Banco de Dados

### **Tabela: `points_ledger`**

Ledger principal que armazena cada entrada de pontos com rastreabilidade completa.

```sql
CREATE TABLE points_ledger (
    ledger_id BIGSERIAL PRIMARY KEY,
    user_id VARCHAR(64) NOT NULL REFERENCES users_profile(user_id),
    points_amount BIGINT NOT NULL CHECK (points_amount > 0),
    
    -- Origem imediata
    origin_type VARCHAR(50) NOT NULL CHECK (origin_type IN ('purchase', 'transfer', 'reward', 'campaign', 'bonus', 'adjustment')),
    origin_id VARCHAR(64) NOT NULL,
    
    -- Origem original (primeira origem)
    original_origin_type VARCHAR(50) NOT NULL,
    original_origin_id VARCHAR(64) NOT NULL,
    
    -- Cadeia de transferências (JSON array)
    origin_chain JSONB DEFAULT '[]'::jsonb,
    
    -- Se veio de transferência
    transferred_from_user_id VARCHAR(64) REFERENCES users_profile(user_id),
    transferred_at TIMESTAMP,
    
    description TEXT,
    created_at TIMESTAMP DEFAULT NOW(),
    updated_at TIMESTAMP DEFAULT NOW()
);
```

**Campos principais:**
- `ledger_id`: ID único da entrada
- `user_id`: Dono atual dos pontos
- `points_amount`: Quantidade de pontos nesta entrada
- `origin_type` / `origin_id`: Origem imediata (pode ser transferência)
- `original_origin_type` / `original_origin_id`: Origem original (sempre preservada)
- `origin_chain`: Array JSON com todas as transferências
- `transferred_from_user_id`: Se veio de transferência, quem enviou

---

## 🔄 Como Funciona

### **1. Registro de Pontos (Compra Confirmada)**

Quando uma compra é confirmada, os pontos são registrados no ledger:

```javascript
// Em PurchasesModel.confirm()
await client.query(`
    INSERT INTO points_ledger (
        user_id, points_amount, origin_type, origin_id,
        original_origin_type, original_origin_id, origin_chain, description
    )
    VALUES ($1, $2, 'purchase', $3, 'purchase', $3, '[]'::jsonb, $4)
`, [userId, pointsEarned, purchaseId, description]);
```

**Exemplo:**
- Usuário A recebe 100 pontos de compra #123
- `origin_type`: `purchase`
- `origin_id`: `123`
- `original_origin_type`: `purchase`
- `original_origin_id`: `123`
- `origin_chain`: `[]`

### **2. Transferência de Pontos (FIFO)**

Quando pontos são transferidos, o sistema:
1. Busca os pontos mais antigos (FIFO)
2. Atualiza a cadeia de origem
3. Transfere mantendo a origem original

```javascript
// Em PointsLedgerService.transferPoints()
// 1. Buscar pontos FIFO
const sourcePoints = await client.query(`
    SELECT * FROM points_ledger
    WHERE user_id = $1
    ORDER BY created_at ASC
`, [fromUserId]);

// 2. Para cada ponto, atualizar cadeia
const newChainEntry = {
    transfer_id: transferId,
    from_user_id: fromUserId,
    to_user_id: toUserId,
    points_amount: transferAmount,
    at: new Date().toISOString()
};
const updatedChain = [...currentChain, newChainEntry];

// 3. Atualizar ou criar nova entrada
```

**Exemplo:**
- Usuário A transfere 50 pontos para Usuário B
- Sistema busca os 50 pontos mais antigos de A
- Atualiza `origin_chain` com a transferência
- Cria nova entrada para B mantendo `original_origin_type` e `original_origin_id`

**Resultado:**
- Usuário B tem pontos com:
  - `origin_type`: `transfer`
  - `origin_id`: `TRF_123`
  - `original_origin_type`: `purchase` (preservado!)
  - `original_origin_id`: `123` (preservado!)
  - `origin_chain`: `[{"transfer_id": "TRF_123", "from_user_id": "A", "to_user_id": "B", ...}]`

### **3. Cadeia Completa**

Se Usuário B transferir para Usuário C:
- `origin_chain` cresce: `[{...TRF_123...}, {...TRF_456...}]`
- `original_origin_type` e `original_origin_id` permanecem como `purchase:123`

---

## 📡 Endpoints da API

### **1. Rastrear Origem de Pontos**

```http
GET /api/points/trace?amount=100
Authorization: Bearer {token}
```

**Query Params:**
- `amount` (opcional): Quantidade específica de pontos para rastrear. Se omitido, retorna todos.

**Resposta:**
```json
{
  "success": true,
  "data": {
    "user_id": "123",
    "requested_amount": 100,
    "entries": [
      {
        "ledger_id": 1,
        "points_amount": 50,
        "current_origin": {
          "type": "transfer",
          "id": "TRF_456"
        },
        "original_origin": {
          "type": "purchase",
          "id": "123"
        },
        "transfer_chain": [
          {
            "transfer_id": "TRF_123",
            "from_user_id": "A",
            "to_user_id": "B",
            "points_amount": 50,
            "at": "2024-01-15T10:30:00Z"
          },
          {
            "transfer_id": "TRF_456",
            "from_user_id": "B",
            "to_user_id": "123",
            "points_amount": 50,
            "at": "2024-01-16T14:20:00Z"
          }
        ],
        "transferred_from": "B",
        "transferred_at": "2024-01-16T14:20:00Z",
        "created_at": "2024-01-15T10:00:00Z",
        "description": "Compra confirmada: COMPRA_123"
      }
    ],
    "total_traced": 100,
    "chain_summary": {
      "total_entries": 2,
      "origins": {
        "purchase:123": {
          "type": "purchase",
          "id": "123",
          "total_points": 100,
          "entries": 2
        }
      },
      "transfer_count": 2
    }
  }
}
```

---

### **2. Resumo por Origem**

```http
GET /api/points/summary-by-origin
Authorization: Bearer {token}
```

**Resposta:**
```json
{
  "success": true,
  "data": {
    "user_id": "123",
    "summary": [
      {
        "original_origin_type": "purchase",
        "original_origin_id": "123",
        "total_points": 150,
        "ledger_entries": 2,
        "first_received_at": "2024-01-15T10:00:00Z",
        "last_received_at": "2024-01-20T14:30:00Z"
      },
      {
        "original_origin_type": "campaign",
        "original_origin_id": "CAMP_001",
        "total_points": 50,
        "ledger_entries": 1,
        "first_received_at": "2024-01-18T09:00:00Z",
        "last_received_at": "2024-01-18T09:00:00Z"
      }
    ],
    "total_origins": 2,
    "total_points": 200
  }
}
```

---

### **3. Cadeia Completa de um Ponto**

```http
GET /api/points/chain/:ledger_id
Authorization: Bearer {token}
```

**Resposta:**
```json
{
  "success": true,
  "data": {
    "ledger_id": 1,
    "current_owner": "123",
    "points_amount": 50,
    "current_origin": {
      "type": "transfer",
      "id": "TRF_456"
    },
    "original_origin": {
      "type": "purchase",
      "id": "123"
    },
    "transfer_chain": [
      {
        "transfer_id": "TRF_123",
        "from_user_id": "A",
        "to_user_id": "B",
        "points_amount": 50,
        "at": "2024-01-15T10:30:00Z"
      },
      {
        "transfer_id": "TRF_456",
        "from_user_id": "B",
        "to_user_id": "123",
        "points_amount": 50,
        "at": "2024-01-16T14:20:00Z"
      }
    ],
    "description": "Compra confirmada: COMPRA_123",
    "created_at": "2024-01-15T10:00:00Z"
  }
}
```

---

### **4. Listar Ledger Completo**

```http
GET /api/points/ledger?page=1&limit=20
Authorization: Bearer {token}
```

**Query Params:**
- `page` (opcional): Número da página (padrão: 1)
- `limit` (opcional): Itens por página (padrão: 20)

**Resposta:**
```json
{
  "success": true,
  "data": [
    {
      "ledger_id": 1,
      "points_amount": 50,
      "current_origin": {
        "type": "transfer",
        "id": "TRF_456"
      },
      "original_origin": {
        "type": "purchase",
        "id": "123"
      },
      "transfer_chain": [...],
      "transferred_from": "B",
      "transferred_at": "2024-01-16T14:20:00Z",
      "description": "Compra confirmada: COMPRA_123",
      "created_at": "2024-01-15T10:00:00Z"
    }
  ],
  "pagination": {
    "total": 10,
    "page": 1,
    "limit": 20,
    "totalPages": 1,
    "hasNextPage": false,
    "hasPrevPage": false
  }
}
```

---

## 🚀 Como Usar

### **1. Inicializar Sistema**

Primeiro, execute o script para criar as tabelas e funções:

```bash
node create-points-ledger-system.js
```

### **2. Sistema Automático**

O sistema já está integrado:
- ✅ **Compras confirmadas**: Automaticamente registram no ledger
- ✅ **Transferências P2P**: Automaticamente usam FIFO e atualizam cadeia
- ✅ **Compatibilidade**: Mantém `points_history` para compatibilidade

### **3. Consultar Rastreabilidade**

```javascript
// Rastrear 100 pontos do usuário atual
GET /api/points/trace?amount=100

// Ver resumo por origem
GET /api/points/summary-by-origin

// Ver cadeia completa de um ponto específico
GET /api/points/chain/1

// Listar todo o ledger
GET /api/points/ledger?page=1&limit=20
```

---

## 🔒 Segurança

- ✅ Apenas usuários autenticados podem consultar seus próprios pontos
- ✅ Validação de propriedade em todas as consultas
- ✅ Transações atômicas para garantir integridade
- ✅ Sistema FIFO garante ordem correta de transferências

---

## 📊 Exemplo Completo

**Cenário:**
1. Usuário A faz compra de 100 MZN → recebe 20 pontos (compra #123)
2. Usuário A transfere 15 pontos para Usuário B
3. Usuário B transfere 10 pontos para Usuário C

**Resultado no Ledger:**

**Usuário A:**
- Ledger Entry 1: 5 pontos (restantes da compra #123)
- Ledger Entry 2: 15 pontos transferidos para B

**Usuário B:**
- Ledger Entry 3: 15 pontos recebidos de A
  - `original_origin`: `purchase:123`
  - `origin_chain`: `[{transfer_id: "TRF_001", from: "A", to: "B"}]`

**Usuário C:**
- Ledger Entry 4: 10 pontos recebidos de B
  - `original_origin`: `purchase:123` (preservado!)
  - `origin_chain`: `[{transfer_id: "TRF_001", from: "A", to: "B"}, {transfer_id: "TRF_002", from: "B", to: "C"}]`

**Consulta:**
```http
GET /api/points/chain/4
```

Retorna cadeia completa mostrando que os 10 pontos vieram originalmente da compra #123 do Usuário A!

---

## ✅ Status

- ✅ Tabela `points_ledger` criada
- ✅ Funções SQL auxiliares criadas
- ✅ Serviço `PointsLedgerService` implementado
- ✅ Integração com compras confirmadas
- ✅ Integração com transferências P2P (FIFO)
- ✅ Endpoints de consulta criados
- ✅ Documentação completa

**Sistema 100% funcional e pronto para uso!**

