---
sidebar_position: 10
title: "Coleta de Eventos (Analytics)"
---

# Coleta de Eventos com Plausible

Sistema de rastreamento de eventos educacionais através do Plausible Community Edition, permitindo análise de padrões de aprendizagem sem invasão de privacidade.

## Fluxo de coleta

```mermaid
graph TD
    A["Atividade de Programação<br/>(ex: PuzzleGame)"] -->|Usuário executa código| B["GameStateContext<br/>(finalizeWithSuccess/Failure)"]
    
    B -->|Dispara evento| C["trackEvent<br/>plausible.js"]
    
    C -->|Lê variáveis de ambiente| D{Qual ambiente?}
    
    D -->|Development| E["VITE_PLAUSIBLE_API<br/>http://localhost/api/event"]
    D -->|Production| F["VITE_PLAUSIBLE_API<br/>plausible.mtst.tec.br"]
    
    E --> G["Fetch com timeout 5s<br/>(AbortController)"]
    F --> G
    
    G -->|Success| H["Evento registrado<br/>no Plausible"]
    
    G -->|Timeout/Error| I["console.error<br/>App continua"]
    
    H --> J["Dashboard Plausible<br/>Análise de métricas"]
```

## Componentes principais

### 1. **GameStateContext** (`contexts/GameStateContext.jsx`)

Gerencia o ciclo de execução das atividades e dispara eventos:

```javascript
// Quando a atividade tem sucesso
const finalizeWithSuccess = () => {
  trackEvent('Activity Success', {
    activity: gameConfig.gameId,
    phase: currentPhase,
    blocks: currentBlockCount,
    attempts: attemptCount,      // Total de tentativas
    failures: failureCount,       // Total de falhas
    durationSeconds: Math.round((Date.now() - phaseStartTime) / 1000)
  });
};

// Quando a atividade falha
const finalizeWithFailure = () => {
  trackEvent('Activity Failure', {
    activity: gameConfig.gameId,
    phase: currentPhase,
    blocks: currentBlockCount,
    error: failureMessage
  });
};
```

Também rastreia:
- **Tentativas**: `attemptCount` incrementado a cada execução
- **Falhas**: `failureCount` incrementado a cada erro
- **Tempo**: `phaseStartTime` registrado ao mudar de fase

### 2. **Serviço Plausible** (`services/plausible.js`)

Abstração para envio de eventos com timeout e tratamento de erro:

```javascript
const sendEvent = (payload) => {
  const controller = new AbortController();
  const timeout = setTimeout(() => controller.abort(), 5000);

  fetch(PLAUSIBLE_API, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(payload),
    signal: controller.signal,
  })
    .catch((e) => console.error('Plausible error:', e))
    .finally(() => clearTimeout(timeout));
};
```

**Características**:
- ✅ Timeout de 5 segundos (não bloqueia a aplicação)
- ✅ Requisição não-bloqueante (não-await)
- ✅ Tratamento de erro silencioso (log no console, app continua)
- ✅ Configurável via variáveis de ambiente

### 3. **Rastreamento de Page View** (`App.jsx`)

Dispara `trackPageView` quando a rota muda:

```javascript
useEffect(() => {
  trackPageView(location.pathname);
}, [location.pathname]);
```

Registra visitas às páginas principais da plataforma.

## Estrutura de dados

### Payload enviado ao Plausible

```json
{
  "domain": "myapp-dev",              // ou https://decoda.mtst.tec.br (prod)
  "url": "http://localhost/#/atividades/programacao/puzzle",
  "referrer": "http://localhost/#/atividades",
  "screenWidth": 1920,
  "name": "Activity Success",
  "props": {
    "activity": "programacao/puzzle",
    "phase": "3",
    "blocks": "5",
    "attempts": "4",
    "failures": "2",
    "durationSeconds": "127"
  }
}
```

## Configuração por ambiente

| Variável | Development | Production |
|----------|-------------|-----------|
| `VITE_PLAUSIBLE_API` | `http://localhost/api/event` | Variável de ambiente (prod) |
| `VITE_PLAUSIBLE_DOMAIN` | `myapp-dev` | `decoda.mtst.tec.br` |
| **Arquivo** | `app/.env` | `app/.env.production` |

## Tratamento de falhas

Se o servidor de analytics não estiver disponível:

1. ✅ **Timeout (5s)**: Requisição é automaticamente cancelada
2. ✅ **Erro de conexão**: Capturado pelo `.catch()` e logado no console
3. ✅ **Sem impacto**: A aplicação continua funcionando normalmente
4. ✅ **Usuário não vê nada**: Erro não é exibido na UI

## Privacidade e LGPD

O Plausible CE foi escolhido porque:

- 🔒 **Sem cookies**: Não usa rastreamento persistente
- 🔒 **Sem IP**: Não armazena endereço IP completo
- 🔒 **Dados educacionais apenas**: Coleta apenas métricas de uso da aplicação
- 🔒 **Sem rastreamento cross-site**: Não segue usuários fora da aplicação
- 📜 **Conformidade LGPD**: Alinhado com legislação brasileira de proteção de dados
- 🔓 **Software livre**: Código aberto, auditável, hospedado localmente

## Fluxo de dados

```
Atividade → GameStateContext → trackEvent() → plausible.js →
  ↓
  Fetch com timeout
  ↓
  Plausible API ← erro/timeout → console.error (não bloqueia)
  ↓
  Dashboard Plausible → Análise pedagógica
```
