# 📊 QR Code Analytics - Premium Feature

Sistema de rastreamento de leituras de QR codes para usuários premium.

## 🎯 Visão Geral

Permite que usuários premium acompanhem quantas vezes seus QR codes foram escaneados, com timestamps e histórico completo.

### Como Funciona

1. **Usuário premium** gera QR code com analytics habilitado
2. QR code aponta para URL de redirect: `https://qrrapido.site/t/{trackingId}`
3. Ao escanear, o sistema:
   - Incrementa contador de leituras (`scanCount`)
   - Atualiza timestamp da última leitura (`lastAccessedAt`)
   - Redireciona para URL original (HTTP 302)

---

## 🔧 Implementação Técnica

### Novos Componentes

#### 1. **TrackingController** (`Controllers/TrackingController.cs`)

Endpoints:
- `GET /t/{trackingId}` - Redireciona e contabiliza leitura
- `GET /t/analytics/{trackingId}` - Retorna analytics (requer autenticação)

#### 2. **Campos no MongoDB**

**QRCodeHistory** (campos já existentes, agora em uso):
```csharp
public int ScanCount { get; set; } = 0;           // Contador de leituras
public DateTime LastAccessedAt { get; set; }       // Última leitura
public bool IsDynamic { get; set; } = false;      // Se é trackable
public string? TrackingId { get; set; }           // ID público (novo)
```

#### 3. **QRGenerationRequest** (novo campo)
```csharp
public bool EnableTracking { get; set; } = false; // Premium feature
```

#### 4. **UserService** (novos métodos)
```csharp
Task<QRCodeHistory?> GetQRByTrackingIdAsync(string trackingId);
Task IncrementQRScanCountAsync(string trackingId);
```

---

## 🚀 Como Usar

### Backend (já implementado)

#### Gerar QR com Analytics

```csharp
var request = new QRGenerationRequest
{
    Type = "url",
    Content = "https://google.com",
    IsPremium = true,
    EnableTracking = true  // ✅ Habilita analytics
};

var result = await _qrService.GenerateRapidAsync(request);

// result.TrackingId conterá o ID para analytics
// QR code aponta para: https://qrrapido.site/t/{trackingId}
```

#### Consultar Analytics

```csharp
// Via UserService
var qr = await _userService.GetQRByTrackingIdAsync("abc123def456");
Console.WriteLine($"Leituras: {qr.ScanCount}");
Console.WriteLine($"Última leitura: {qr.LastAccessedAt}");

// Via API (requer autenticação)
GET /t/analytics/abc123def456
```

**Response:**
```json
{
  "trackingId": "abc123def456",
  "scanCount": 42,
  "createdAt": "2025-10-19T10:00:00Z",
  "lastAccessedAt": "2025-10-20T15:30:00Z",
  "content": "https://google.com",
  "type": "url"
}
```

---

### Frontend (ainda não implementado)

#### Opção 1: Checkbox no Gerador

```html
<!-- Em Views/Home/Index.cshtml -->
<div class="form-check premium-feature">
  <input type="checkbox" id="enableTracking" class="form-check-input">
  <label for="enableTracking">
    <i class="fas fa-chart-line"></i> Habilitar Analytics
    <span class="badge bg-warning">Premium</span>
  </label>
</div>
```

```javascript
// Em wwwroot/js/qr-speed-generator.js
const enableTracking = document.getElementById('enableTracking');

formData.append('EnableTracking', enableTracking?.checked && this.isPremium);
```

#### Opção 2: Dashboard de Analytics

```html
<!-- Nova view: Views/Premium/Analytics.cshtml -->
<div class="analytics-dashboard">
  <h2>Meus QR Codes com Analytics</h2>

  <div class="qr-list">
    @foreach (var qr in Model.TrackableQRs)
    {
      <div class="qr-card">
        <h3>@qr.Content</h3>
        <p><strong>Leituras:</strong> @qr.ScanCount</p>
        <p><strong>Última leitura:</strong> @qr.LastAccessedAt.ToString("dd/MM/yyyy HH:mm")</p>
        <a href="/t/analytics/@qr.TrackingId">Ver detalhes</a>
      </div>
    }
  </div>
</div>
```

---

## 📝 Limitações Conhecidas

### 1. **Apenas QR codes de URL**
- Tracking funciona apenas para `Type = "url"`
- WiFi, vCard, SMS, etc. **não suportam** redirect

**Razão**: Esses tipos não aceitam URLs customizadas

**Solução futura**: Implementar pixel de tracking invisível ou API de scan manual

### 2. **Redirect adiciona ~50-200ms**
- Usuário experimenta pequeno delay ao escanear
- Impacto: Mínimo para maioria dos casos

**Otimização**: Redirect é assíncrono, contador atualiza em background

### 3. **Bloqueadores de ads podem afetar**
- Alguns bloqueadores podem marcar `/t/` como tracking
- Probabilidade: Baixa (não usa cookies ou JS)

---

## 🔐 Segurança

### Proteções Implementadas

1. **Tracking ID não-sequencial**: GUID truncado (12 chars)
2. **Validação de ownership**: Endpoint `/t/analytics/` verifica se QR pertence ao usuário
3. **Fire-and-forget counting**: Não bloqueia redirect se MongoDB estiver lento
4. **Logging completo**: Todas as leituras são logadas

### Considerações de Privacidade

- **Não coleta**: IP, device, localização (por enquanto)
- **Apenas conta**: Quantidade de leituras + timestamp
- **LGPD compliant**: Usuário premium pode deletar histórico a qualquer momento

---

## 📊 Exemplos de Uso

### Caso 1: Rastreamento de Campanha

```csharp
// Gerar QR para campanha de marketing
var campaign = new QRGenerationRequest
{
    Type = "url",
    Content = "https://minhaloja.com/promo-verao",
    IsPremium = true,
    EnableTracking = true
};

var qr = await _qrService.GenerateRapidAsync(campaign);

// Distribuir QR em materiais impressos
// Depois consultar: await _userService.GetQRByTrackingIdAsync(qr.TrackingId);
```

### Caso 2: Validação de Engajamento

```csharp
// Verificar se QR code em outdoor teve leituras
var qr = await _userService.GetQRByTrackingIdAsync("abc123def456");

if (qr.ScanCount > 100)
{
    Console.WriteLine("Outdoor teve boa visibilidade!");
}
else if (qr.ScanCount == 0)
{
    Console.WriteLine("QR pode estar ilegível ou mal posicionado");
}
```

---

## 🛠️ Configuração

### appsettings.json

```json
{
  "App": {
    "BaseUrl": "https://qrrapido.site"  // ✅ Usado para gerar URLs de tracking
  }
}
```

### appsettings.Development.json

```json
{
  "App": {
    "BaseUrl": "https://localhost:52428"  // ✅ Para testes locais
  }
}
```

---

## 🧪 Testando Localmente

### 1. Gerar QR com Tracking

```bash
# POST /api/QR/GenerateRapid
curl -X POST https://localhost:52428/api/QR/GenerateRapid \
  -H "Content-Type: application/json" \
  -d '{
    "type": "url",
    "content": "https://google.com",
    "isPremium": true,
    "enableTracking": true
  }'
```

**Response:**
```json
{
  "qrCodeBase64": "iVBORw0KG...",
  "trackingId": "a1b2c3d4e5f6",
  "success": true
}
```

### 2. Simular Leitura do QR

```bash
# Abrir no navegador (ou curl)
curl -L https://localhost:52428/t/a1b2c3d4e5f6
# Deve redirecionar para https://google.com
```

### 3. Verificar Contador

```bash
# Acessar MongoDB ou via API
curl https://localhost:52428/t/analytics/a1b2c3d4e5f6 \
  -H "Authorization: Bearer {token}"
```

**Response:**
```json
{
  "trackingId": "a1b2c3d4e5f6",
  "scanCount": 1,
  "lastAccessedAt": "2025-10-20T10:00:00Z"
}
```

---

## 📈 Próximos Passos (Features Futuras)

### Analytics Avançado
- [ ] Gráfico de leituras por dia/semana/mês
- [ ] Geo-localização (IP → País/Cidade)
- [ ] Tipo de device (mobile/desktop)
- [ ] Browser/OS usado para escanear

### UI/UX
- [ ] Dashboard de analytics no painel premium
- [ ] Exportar dados para CSV/Excel
- [ ] Notificações quando QR atingir X leituras

### Performance
- [ ] Cache Redis para evitar queries MongoDB em cada scan
- [ ] Batch updates (atualizar contador a cada N leituras)

---

## 📚 Referências

- **Tracking URLs**: Mesma estratégia usada por bit.ly, tinyurl, etc.
- **HTTP 302 Redirect**: Padrão para preservar SEO e funcionalidade
- **Fire-and-forget**: Pattern do ASP.NET Core para operações assíncronas não-bloqueantes

---

## 🐛 Troubleshooting

### Problema: "QR code not found"
- Verificar se `trackingId` existe no MongoDB
- Verificar se QR foi salvo com `IsDynamic = true`

### Problema: Contador não incrementa
- Verificar logs do `TrackingController`
- Verificar conectividade MongoDB
- Verificar se `IncrementQRScanCountAsync` está sendo chamado

### Problema: Redirect não funciona
- Verificar se URL original está salva em `Content`
- Verificar se `BaseUrl` está configurado corretamente
- Verificar logs de erro no controller

---

**Implementado em**: 2025-10-20
**Versão**: 1.0.0
**Status**: ✅ Backend completo, Frontend pendente
