QrRapido/Docs/QR-Analytics-Feature.md

346 lines
8.2 KiB
Markdown

# 📊 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