# 📊 Métricas Dinâmicas Baseadas em Filtros

## 📋 Resumo

Implementado sistema de métricas dinâmicas que se adaptam aos filtros aplicados. Se há filtros, as métricas são calculadas apenas sobre os dados filtrados. Se não há filtros, as métricas mostram todos os dados.

---

## 🎯 Comportamento das Métricas

### **Sem Filtros Aplicados**
- ✅ Mostra **TODAS** as compras do usuário
- ✅ Calcula métricas sobre **TODAS** as compras
- ✅ Inclui todos os dados históricos

### **Com Filtros Aplicados**
- ✅ Mostra apenas compras que atendem aos filtros
- ✅ Calcula métricas **APENAS** sobre os dados filtrados
- ✅ Métricas são precisas para o conjunto filtrado

---

## 🔍 Filtros Suportados

### **GET /api/purchases/my-purchases**

**Parâmetros de Filtro:**
- `establishment_id` - Filtrar por estabelecimento
- `status` - Filtrar por status (pending, confirmed, rejected, cancelled)
- `start_date` - Data inicial (YYYY-MM-DD)
- `end_date` - Data final (YYYY-MM-DD)
- `min_amount` - Valor mínimo da compra
- `max_amount` - Valor máximo da compra

**Exemplos:**

1. **Sem filtros - Todas as compras:**
```bash
GET /api/purchases/my-purchases?page=1&limit=20
```
- Retorna todas as compras do usuário
- Métricas calculadas sobre todas as compras

2. **Com filtro de status:**
```bash
GET /api/purchases/my-purchases?status=confirmed&page=1&limit=20
```
- Retorna apenas compras confirmadas
- Métricas calculadas apenas sobre compras confirmadas

3. **Com filtro de estabelecimento:**
```bash
GET /api/purchases/my-purchases?establishment_id=5&page=1&limit=20
```
- Retorna apenas compras do estabelecimento 5
- Métricas calculadas apenas sobre compras deste estabelecimento

4. **Com filtro de data:**
```bash
GET /api/purchases/my-purchases?start_date=2024-01-01&end_date=2024-01-31&page=1&limit=20
```
- Retorna apenas compras de janeiro/2024
- Métricas calculadas apenas sobre compras deste período

5. **Múltiplos filtros:**
```bash
GET /api/purchases/my-purchases?status=confirmed&establishment_id=5&start_date=2024-01-01&min_amount=100&page=1&limit=20
```
- Retorna compras confirmadas do estabelecimento 5, em janeiro, acima de 100 MZN
- Métricas calculadas apenas sobre estas compras específicas

---

## 📊 Exemplo de Resposta

### **Sem Filtros**
```json
{
  "success": true,
  "data": [ ... todas as compras ... ],
  "pagination": { ... },
  "filters": {
    "applied": false,
    "establishment_id": null,
    "status": null,
    "start_date": null,
    "end_date": null,
    "min_amount": null,
    "max_amount": null
  },
  "metrics": {
    "purchases": {
      "total": 25,        // Todas as compras
      "confirmed": 20,     // Todas as confirmadas
      "pending": 3,
      "rejected": 2
    },
    "spending": {
      "totalSpent": 2500.50,  // Total de todas as compras
      "totalSpentConfirmed": 2000.50
    },
    "points": {
      "totalEarned": 400,  // Todos os pontos ganhos
      "totalSpent": 150,
      "netPoints": 250
    }
  }
}
```

### **Com Filtros (status=confirmed)**
```json
{
  "success": true,
  "data": [ ... apenas compras confirmadas ... ],
  "pagination": {
    "total": 20,  // Total de compras confirmadas
    "page": 1,
    "limit": 20
  },
  "filters": {
    "applied": true,
    "establishment_id": null,
    "status": "confirmed",
    "start_date": null,
    "end_date": null,
    "min_amount": null,
    "max_amount": null
  },
  "metrics": {
    "purchases": {
      "total": 20,        // Apenas confirmadas (filtradas)
      "confirmed": 20,    // Mesmo valor (já filtrado)
      "pending": 0,       // Zero porque filtrado
      "rejected": 0       // Zero porque filtrado
    },
    "spending": {
      "totalSpent": 2000.50,  // Apenas de compras confirmadas
      "totalSpentConfirmed": 2000.50
    },
    "points": {
      "totalEarned": 400,  // Apenas pontos de compras confirmadas
      "totalSpent": 100,   // Pontos gastos relacionados a estas compras
      "netPoints": 300
    }
  }
}
```

---

## 🔄 Fluxo de Filtragem

```
1. Cliente aplica filtros (status, data, estabelecimento, valor)
   ↓
2. Sistema busca compras com filtros aplicados na query SQL
   ↓
3. Sistema calcula métricas com MESMOS filtros aplicados
   ↓
4. Métricas refletem APENAS os dados filtrados
   ↓
5. Resposta inclui:
   - Dados filtrados
   - Métricas dos dados filtrados
   - Informação sobre filtros aplicados
```

---

## ⚙️ Implementação Técnica

### **Arquivos Modificados:**

1. **`models/PurchasesModel.js`**
   - ✅ `findByUserId` - Agora aceita todos os filtros (status, data, valor)
   - ✅ `getUserPurchaseMetrics` - Aceita filtros e aplica nas métricas

2. **`controllers/purchaseController.js`**
   - ✅ `getMyPurchases` - Aceita todos os filtros via query params
   - ✅ Aplica mesmos filtros nos dados e nas métricas

### **Filtros Aplicados:**

```javascript
const filters = {
    establishment_id: establishment_id ? parseInt(establishment_id) : null,
    status: status || null,
    start_date: start_date || null,
    end_date: end_date || null,
    min_amount: min_amount ? parseFloat(min_amount) : null,
    max_amount: max_amount ? parseFloat(max_amount) : null
};

// Aplicar nos dados
const result = await Purchase.findByUserId(userId, filters);

// Aplicar nas métricas
const metrics = await Purchase.getUserPurchaseMetrics(userId, filters);
```

---

## 📈 Exemplos Práticos

### **Cenário 1: Ver todas as compras**
```
GET /api/purchases/my-purchases
```
**Métricas:** Todas as compras do usuário

### **Cenário 2: Ver apenas compras confirmadas**
```
GET /api/purchases/my-purchases?status=confirmed
```
**Métricas:** Apenas compras confirmadas

### **Cenário 3: Ver compras de um período específico**
```
GET /api/purchases/my-purchases?start_date=2024-01-01&end_date=2024-01-31
```
**Métricas:** Apenas compras de janeiro/2024

### **Cenário 4: Ver compras de um estabelecimento específico**
```
GET /api/purchases/my-purchases?establishment_id=5
```
**Métricas:** Apenas compras do estabelecimento 5

### **Cenário 5: Ver compras acima de um valor**
```
GET /api/purchases/my-purchases?min_amount=100
```
**Métricas:** Apenas compras acima de 100 MZN

---

## ✅ Benefícios

1. ✅ **Precisão**: Métricas sempre refletem os dados exibidos
2. ✅ **Flexibilidade**: Cliente pode analisar qualquer subconjunto de dados
3. ✅ **Consistência**: Dados e métricas sempre alinhados
4. ✅ **Transparência**: Resposta indica quais filtros foram aplicados
5. ✅ **Performance**: Filtros aplicados no banco (eficiente)

---

## 🔍 Informação de Filtros na Resposta

A resposta sempre inclui um objeto `filters` que mostra:
- `applied` - Se há filtros aplicados (true/false)
- Valores de cada filtro (null se não aplicado)

```json
"filters": {
  "applied": true,
  "establishment_id": 5,
  "status": "confirmed",
  "start_date": "2024-01-01",
  "end_date": "2024-01-31",
  "min_amount": 100,
  "max_amount": null
}
```

---

## 🎯 Regra de Ouro

> **"As métricas sempre refletem os dados filtrados. Se não há filtros, métricas são sobre todos os dados. Se há filtros, métricas são apenas sobre os dados filtrados."**

---

## 📊 Métricas Afetadas por Filtros

### **Métricas de Compras:**
- Total, confirmadas, pendentes, rejeitadas, canceladas

### **Métricas de Gastos:**
- Total gasto, média, máximo, mínimo

### **Métricas de Pontos:**
- Total ganhos, total gastos, pontos líquidos
- Pontos gastos relacionados às compras filtradas

### **Métricas de Estabelecimentos:**
- Estabelecimentos únicos visitados (no conjunto filtrado)

### **Métricas de Datas:**
- Primeira/última compra (no conjunto filtrado)

### **Não Afetadas (sempre do usuário completo):**
- Pontos atuais na carteira
- Transferências totais
- Recompensas totais resgatadas

---

## ⚠️ Importante

- ✅ Filtros são aplicados **no banco de dados** (eficiente)
- ✅ Métricas são calculadas sobre **os mesmos filtros**
- ✅ Se não há filtros, mostra **todos os dados e todas as métricas**
- ✅ Paginação funciona corretamente com filtros
- ✅ Total na paginação reflete os filtros aplicados




