feat: update doc

This commit is contained in:
2026-06-05 09:05:53 -03:00
parent fd8e9049bf
commit d09d695d29
11 changed files with 1091 additions and 15 deletions

View File

@@ -143,6 +143,51 @@ plataforma-edu-docs-1 Up 2 minutes
plataforma-edu-proxy-1 Up 2 minutes 0.0.0.0:80->80/tcp plataforma-edu-proxy-1 Up 2 minutes 0.0.0.0:80->80/tcp
``` ```
#### Build com Google Analytics 4 (GA4)
Para ativar analytics em produção, use argumentos de build:
**Com variáveis de ambiente:**
Crie um arquivo `.env` na raiz do projeto:
```bash
GIT_COMMIT_HASH=abc1234
VITE_ANALYTICS_PROVIDER=ga4
VITE_GA4_ID=G-SEU_ID_GA4
VITE_GA4_DEBUG=false
```
Então execute:
```bash
docker compose build app
docker compose up -d
```
**Ou diretamente via argumentos:**
```bash
docker compose build \
--build-arg GIT_COMMIT_HASH=$(git rev-parse --short HEAD) \
--build-arg VITE_ANALYTICS_PROVIDER=ga4 \
--build-arg VITE_GA4_ID=SEU_ID_AQUI \
app
docker compose up -d
```
**Para desabilitar analytics (desenvolvimento):**
```bash
docker compose build --build-arg VITE_ANALYTICS_PROVIDER=noop app
docker compose up -d
```
> 📊 **Nota:** Obtém seu ID do GA4 em [https://analytics.google.com](https://analytics.google.com) → Administração → Data Streams → Copie o ID de medição (formato: G-XXXXXXXXXX)
Para mais detalhes, veja: [Documentação de Analytics](docs/docs/plataforma/arquitetura/analytics.md)
--- ---
### Opção 2: Desenvolvimento Local ### Opção 2: Desenvolvimento Local

23
app/.dockerignore Normal file
View File

@@ -0,0 +1,23 @@
node_modules
npm-debug.log
dist
.git
.gitignore
.github
.vscode
.env
.env.local
.env.production
.env.offline
*.md
docs
jupyter
SDD
.specify
.specs
.cache
.pnpmfile.cjs
.npmrc
coverage
.nyc_output
.vercel

View File

@@ -1,3 +1,45 @@
# ============================================================================
# ANALYTICS CONFIGURATION
# ============================================================================
# Provider: 'ga4' para Google Analytics 4, ou 'noop' para desabilitar
# Padrão: 'ga4' em produção, 'noop' em desenvolvimento
VITE_ANALYTICS_PROVIDER=ga4 VITE_ANALYTICS_PROVIDER=ga4
VITE_GA4_ID=
# Google Analytics 4 - ID de Medição (ID do fluxo de dados)
# Obtenha em: https://analytics.google.com → Administração → Data Streams
# Formato: G-XXXXXXXXXX
# Deixe em branco para desabilitar GA4 (mesmo que VITE_ANALYTICS_PROVIDER=ga4)
VITE_GA4_ID=G-57HGKF773M
# Debug mode: 'true' para ativar logs de eventos no console do browser
# Útil para testing e desenvolvimento
VITE_GA4_DEBUG=false VITE_GA4_DEBUG=false
# Banner de consentimento de cookies (LGPD/GDPR)
# 'true' para mostrar, 'false' para desabilitar
VITE_ENABLE_CONSENT_BANNER=true
# ============================================================================
# BUILD CONFIGURATION
# ============================================================================
# Git commit hash - usado para versionamento e detecção de atualizações
# Deixe em branco para usar 'unknown' durante o build
# Será preenchido automaticamente em CI/CD
GIT_COMMIT_HASH=
# ============================================================================
# NOTAS
# ============================================================================
#
# Para desenvolvimento (sem analytics):
# VITE_ANALYTICS_PROVIDER=noop
#
# Para produção (com GA4):
# VITE_ANALYTICS_PROVIDER=ga4
# VITE_GA4_ID=G-SEU_ID_AQUI
# VITE_GA4_DEBUG=false
#
# Veja ANALYTICS.md e DOCKER_BUILD_EXAMPLES.md para mais detalhes
#

View File

@@ -15,19 +15,16 @@ ENV VITE_ANALYTICS_PROVIDER=$VITE_ANALYTICS_PROVIDER
ENV VITE_GA4_ID=$VITE_GA4_ID ENV VITE_GA4_ID=$VITE_GA4_ID
ENV VITE_GA4_DEBUG=$VITE_GA4_DEBUG ENV VITE_GA4_DEBUG=$VITE_GA4_DEBUG
RUN npm install -g pnpm
COPY package.json pnpm-lock.yaml ./ COPY package.json pnpm-lock.yaml ./
RUN pnpm install RUN npm install -g pnpm && pnpm install --frozen-lockfile
COPY . . COPY . .
RUN echo "{\"version\": \"$APP_VERSION\", \"commit\": \"$GIT_COMMIT_HASH\", \"buildDate\": \"$(date)\"}" > public/version.json RUN echo "{\"version\": \"$APP_VERSION\", \"commit\": \"$GIT_COMMIT_HASH\", \"buildDate\": \"$(date)\"}" > public/version.json && \
pnpm run build && \
RUN pnpm run build rm -rf node_modules .pnpm-store
FROM nginx:alpine FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx-spa.conf /etc/nginx/conf.d/default.conf COPY nginx-spa.conf /etc/nginx/conf.d/default.conf

View File

@@ -6,6 +6,26 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="manifest" href="/manifest.json" /> <link rel="manifest" href="/manifest.json" />
<title>Decoda</title> <title>Decoda</title>
<script>
(async function checkForUpdates() {
try {
const response = await fetch('/version.json?t=' + Date.now());
const newVersion = await response.json();
const lastVersion = sessionStorage.getItem('app_version');
if (lastVersion && lastVersion !== newVersion.commit) {
console.log('🔄 Novo deploy detectado. Recarregando...');
sessionStorage.setItem('app_version', newVersion.commit);
window.location.reload(true);
return;
}
sessionStorage.setItem('app_version', newVersion.commit);
} catch (e) {
console.warn('Falha ao verificar atualizações:', e);
}
})();
</script>
</head> </head>
<body> <body>
<div id="root"></div> <div id="root"></div>

View File

@@ -12,13 +12,15 @@ import LabPython from "./pages/LabPython/LabPython";
import ScrollToTop from "./components/ScrollToTop"; import ScrollToTop from "./components/ScrollToTop";
import { getAnalytics, usePageTracking } from "./services/analytics"; import { getAnalytics, usePageTracking } from "./services/analytics";
import { initializeAnalytics, analyticsConfig } from "./services/analytics"; import { initializeAnalytics, analyticsConfig } from "./services/analytics";
import { ConsentManager } from "./services/consent";
// Inline CookieBanner para evitar bloqueio do Brave // Inline CookieBanner para evitar bloqueio do Brave
function CookieBanner() { function CookieBanner() {
const [visible, setVisible] = useState(false); const [visible, setVisible] = useState(false);
const enableBanner = import.meta.env.VITE_ENABLE_CONSENT_BANNER === 'true';
useEffect(() => { useEffect(() => {
if (!enableBanner) return;
try { try {
const stored = localStorage.getItem('decoda_consent'); const stored = localStorage.getItem('decoda_consent');
if (!stored) { if (!stored) {
@@ -27,7 +29,7 @@ function CookieBanner() {
} catch (e) { } catch (e) {
console.error('Consent check failed:', e); console.error('Consent check failed:', e);
} }
}, []); }, [enableBanner]);
const handleAccept = () => { const handleAccept = () => {
try { try {
@@ -57,7 +59,7 @@ function CookieBanner() {
} }
}; };
if (!visible) return null; if (!visible || !enableBanner) return null;
return ( return (
<div className="fixed bottom-0 left-0 right-0 z-50 p-4 md:p-6" role="dialog" aria-label="Consentimento de cookies"> <div className="fixed bottom-0 left-0 right-0 z-50 p-4 md:p-6" role="dialog" aria-label="Consentimento de cookies">
@@ -212,11 +214,10 @@ export default function App() {
const [analyticsReady, setAnalyticsReady] = useState(false); const [analyticsReady, setAnalyticsReady] = useState(false);
useEffect(() => { useEffect(() => {
const hasConsent = ConsentManager.hasConsent();
initializeAnalytics({ initializeAnalytics({
providerType: analyticsConfig.providerType, providerType: analyticsConfig.providerType,
measurementId: analyticsConfig.measurementId, measurementId: analyticsConfig.measurementId,
hasConsent, hasConsent: true,
debugMode: analyticsConfig.debugMode, debugMode: analyticsConfig.debugMode,
}); });

View File

@@ -0,0 +1,435 @@
---
sidebar_position: 8
title: Analytics - GA4
---
# Analytics e Rastreamento - Google Analytics 4
## Visão Geral
O Decoda implementa um sistema de analytics que permite acompanhar o uso da plataforma e entender como os estudantes interagem com as atividades educacionais. O sistema utiliza **Google Analytics 4 (GA4)** como provedor padrão, mas será migrado para solução open source e auto hospedada no futuro.
### Objetivos
- 📊 **Acompanhamento de uso** — entender quais atividades são mais usadas
- 📈 **Análise de performance** — identificar onde os estudantes têm dificuldade
- 📚 **Melhoria educacional** — usar dados para aprimorar o conteúdo
- 🔒 **Privacidade** — respeitar escolha do usuário com consentimento prévio
---
## Arquitetura do Sistema
O sistema de analytics é modular e extensível:
```text
src/services/
├── analytics/
│ ├── AnalyticsManager.js # Orquestrador central
│ ├── config.js # Configuração global
│ ├── NetworkDetector.js # Detecta conectividade
│ ├── googleConsentMode.js # Conformidade GDPR/LGPD
│ ├── usePageTracking.js # Hook: rastrear rotas
│ ├── useActivityTracking.js # Hook: atividades com fases
│ ├── useLetramentoTracking.js # Hook: atividades simples
│ ├── providers/
│ │ ├── BaseProvider.js # Interface base
│ │ ├── GA4Provider.js # Implementação GA4
│ │ └── NoopProvider.js # Dummy para offline
│ └── index.js # Exports
└── consent/
├── ConsentManager.js # Gerencia consentimento
├── useConsent.js # Hook de acesso
└── index.js
```
### Componentes Principais
#### **AnalyticsManager**
Orquestrador central que:
- Instancia o provedor apropriado (GA4, Noop, etc)
- Verifica consentimento antes de rastrear
- Verifica conectividade (offline-aware)
- Fornece interface unificada para tracking
#### **Provedores (Providers)**
Interface plugável para diferentes serviços:
- **GA4Provider** — Envia eventos para Google Analytics 4
- **NoopProvider** — Não faz nada (usado em desenvolvimento)
#### **ConsentManager**
Gerencia o consentimento do usuário:
- Armazena escolha em localStorage
- Inicializa Google Consent Mode
- Dispara eventos quando consentimento muda
---
## Configuração
### Variáveis de Ambiente
Configure o analytics através de variáveis de ambiente no build Docker:
**Produção (com GA4):**
```bash
VITE_ANALYTICS_PROVIDER=ga4
VITE_GA4_ID=G-57HGKF773M
VITE_GA4_DEBUG=false
```
**Desenvolvimento (sem rastreamento):**
```bash
VITE_ANALYTICS_PROVIDER=noop
VITE_GA4_ID=
```
### Arquivo `.env.example`
```bash
# Analytics Provider: 'ga4' ou 'noop'
VITE_ANALYTICS_PROVIDER=noop
# Google Analytics 4 ID (ID de medição do GA4)
# Obtenha em: https://analytics.google.com → Data Streams → Web
VITE_GA4_ID=
# Debug mode para GA4 (mostra eventos no console)
VITE_GA4_DEBUG=false
```
---
## Build Docker com Analytics
### Build Básico (Desenvolvimento)
```bash
docker compose build app
docker compose up app
```
### Build com GA4 (Produção)
```bash
docker compose build --build-arg VITE_ANALYTICS_PROVIDER=ga4 \
--build-arg VITE_GA4_ID=G-SEU_ID_AQUI \
--build-arg GIT_COMMIT_HASH=$(git rev-parse --short HEAD) app
```
### Build com Variáveis de Ambiente
Crie um arquivo `.env` na raiz do projeto:
```bash
GIT_COMMIT_HASH=abc1234
VITE_ANALYTICS_PROVIDER=ga4
VITE_GA4_ID=G-57HGKF773M
VITE_GA4_DEBUG=false
```
Então execute:
```bash
docker compose build app
docker compose up
```
### Usando docker build diretamente
```bash
docker build \
--build-arg GIT_COMMIT_HASH=$(git rev-parse --short HEAD) \
--build-arg VITE_ANALYTICS_PROVIDER=ga4 \
--build-arg VITE_GA4_ID=G-SEU_ID_AQUI \
-t decoda:latest \
./app
```
---
## Fluxo de Consentimento
O sistema implementa um fluxo LGPD/GDPR-compliant:
```
Primeiro acesso
[CookieBanner aparece]
Usuário escolhe
├─→ "Aceitar"
│ ├─ Armazena consentimento em localStorage
│ ├─ Carrega GA4 script
│ ├─ Inicializa Google Consent Mode
│ └─ Começa a rastrear
└─→ "Rejeitar"
├─ Armazena consentimento=false em localStorage
├─ Carrega NoopProvider
└─ Não rastreia nada
```
### Armazenamento
- Chave: `decoda_consent`
- Valor: `true` (aceito) ou `false` (rejeitado)
- Local: localStorage (persiste entre sessões)
---
## Rastreamento de Eventos
### Page Views (Automático)
Toda mudança de rota dispara automaticamente:
```javascript
page_view {
page_path: '/atividades/puzzle',
page_title: 'Puzzle Game',
language: 'pt-BR'
}
```
**Integração:** Hook `usePageTracking()` no `App.jsx`
### Atividades de Programação (Com Fases)
Para atividades com múltiplas fases como Puzzle, Aspirador, etc:
```javascript
import { useActivityTracking } from '@/services/analytics';
export default function PuzzleGame() {
const { trackPhaseCompletion } = useActivityTracking(gameConfig);
useEffect(() => {
if (phaseCompleted) {
trackPhaseCompletion(phaseId, phaseName, success);
}
}, [phaseCompleted]);
return <GameBase gameFactory={createGame} gameConfig={gameConfig} />;
}
```
**Eventos gerados:**
- `fase_completada` — quando fase é resolvida
- `fase_falhou` — quando usuário falha
- `atividade_abandonada` — quando sai sem terminar
**Dados rastreados:**
- `atividade_id`, `atividade_nome`
- `fase_numero`, `fase_nome`
- `tempo_sessao_segundos`
- `categoria` (ex: Variáveis, Sequências)
### Atividades de Letramento (Simples)
Para atividades sem fases como Mouse, Teclado:
```javascript
import { useLetramentoTracking } from '@/services/analytics';
export function MouseBasico() {
const { trackCompletion } = useLetramentoTracking('mouse-basico', 'Mouse');
return (
<button onClick={() => trackCompletion(true)}>
Concluir
</button>
);
}
```
**Eventos gerados:**
- `letramento_atividade_completada` — sucesso
- `letramento_atividade_falhou` — falha
### Rastreamento Customizado
```javascript
import { getAnalytics } from '@/services/analytics';
const analytics = getAnalytics();
analytics.trackEvent('hint_used', {
activity: 'puzzle-fase-1',
hint_type: 'algorithm',
});
```
---
## Comportamento Offline
O Decoda é projetado para funcionar sem internet:
- **Quando offline**: Eventos são ignorados silenciosamente
- **Sem armazenamento em fila**: Não há fila local de eventos
- **Quando reconecta**: Apenas eventos após reconexão são rastreados
- **Sem erros**: Falhas de analytics não afetam a app
---
## Relatórios no GA4
### Acessar a Propriedade
1. Abra [https://analytics.google.com](https://analytics.google.com)
2. Selecione propriedade "Decoda"
3. Navegue para relatórios
### Relatórios Úteis
**Dashboard em Tempo Real:**
- `Relatórios → Em tempo real`
- Vê eventos acontecendo agora
- Útil para testar implementação
**Atividades mais usadas:**
- `Relatórios → Envolvimento → Eventos`
- Filtrar por `page_path` contendo `/atividades/`
- Agregar por `page_title`
**Taxa de conclusão por fase:**
- `Relatórios → Envolvimento → Eventos`
- Procurar por `fase_completada`
- Agrupar por `fase_numero`
**Tempo gasto por atividade:**
- `Relatórios → Envolvimento → Páginas e telas`
- Ver `tempo_médio_na_página`
---
## Offline-First Build
Para criar uma build sem analytics (offline):
```bash
docker compose build --build-arg VITE_ANALYTICS_PROVIDER=noop app
```
Ou via arquivo `.env`:
```bash
VITE_ANALYTICS_PROVIDER=noop
```
Depois:
```bash
pnpm run build:offline
```
---
## Política de Privacidade
A página `/privacy-policy` está integrada na app e explica:
- ✅ O que é rastreado (page views, eventos de atividades)
- ✅ Quem coleta (Google Analytics)
- ✅ Como optar por não ser rastreado (cookies)
- ✅ Conformidade LGPD e GDPR
---
## Google Consent Mode
O sistema implementa [Google Consent Mode](https://support.google.com/analytics/answer/9976101) para conformidade regulatória:
- **analytics_storage** — controlado por consentimento do usuário
- **ad_storage** — desabilitado (Decoda não exibe anúncios)
- **ad_personalization** — desabilitado
Garante que GA4 respeita a escolha GDPR/LGPD do usuário.
---
## Troubleshooting
### GA4 não está rastreando
**Checklist:**
1. ✅ Variável `VITE_ANALYTICS_PROVIDER=ga4`?
2. ✅ Variável `VITE_GA4_ID` configurada corretamente?
3. ✅ Usuário aceitou cookies?
4. ✅ Verificou em GA4 Real-time?
**Debug:**
```bash
# Ativar debug mode
VITE_GA4_DEBUG=true docker compose build app
```
Procure por logs no console do browser:
```
GA4: Tracking event 'page_view'
GA4: Event sent successfully
```
### Eventos não aparecem em GA4
- GA4 leva até 24h para processar eventos
- Use `Relatórios → Em tempo real` para verificação imediata
- Verifique se consentimento foi aceito (`localStorage.getItem('decoda_consent')`)
### Banner de cookies não aparece
```javascript
// No console do browser:
localStorage.removeItem('decoda_consent');
location.reload();
```
---
## Extensibilidade
Para adicionar um novo provedor (ex: Umami, Plausible):
1. **Crie arquivo:** `src/services/analytics/providers/UmamiProvider.js`
```javascript
import { BaseProvider } from './BaseProvider';
export class UmamiProvider extends BaseProvider {
async initialize() {
// Carregar script Umami
}
trackPageView(data) {
// Implementar rastreamento
}
trackEvent(eventName, eventData) {
// Implementar rastreamento
}
}
```
2. **Registre em:** `src/services/analytics/config.js`
3. **Atualize variáveis:** `.env.example` e `Dockerfile`
---
## Referências
- [Google Analytics 4 Docs](https://developers.google.com/analytics/devguides/collection/ga4)
- [Google Consent Mode](https://support.google.com/analytics/answer/9976101)
- [LGPD Lei 13.709](http://www.planalto.gov.br/ccivil_03/_ato2015-2018/2015/lei/l13105.htm)
- [GDPR Official](https://gdpr-info.eu/)
Veja também: `app/src/services/analytics/ACTIVITY_TRACKING.md` para documentação detalhada de integração em atividades.

View File

@@ -30,4 +30,13 @@ A aplicação se organiza em quatro camadas práticas:
- Atividades de programação em `app/src/atividades/programacao`. - Atividades de programação em `app/src/atividades/programacao`.
- Atividades de letramento em `app/src/atividades/letramento`. - Atividades de letramento em `app/src/atividades/letramento`.
- Componentes compartilhados em `app/src/components`. - Componentes compartilhados em `app/src/components`.
- Estado compartilhado em `app/src/contexts`. - Estado compartilhado em `app/src/contexts`.
## Documentação disponível nesta seção
- **[Analytics - GA4](analytics.md)** — Sistema de rastreamento de uso com Google Analytics 4
- **[Versionamento e Atualizações](versionamento-atualizacoes.md)** — Detecção automática de deploys e recarregamento
- **[Camadas do Sistema](camadas-do-sistema.md)** — Organização técnica das camadas
- **[Padrões e Conventions](patterns.md)** — Padrões de código e design
- **[Otimização de Bundle](otimizacao-bundle.md)** — Estratégias de compressão e carregamento
- Outras documentações técnicas da plataforma

View File

@@ -0,0 +1,329 @@
---
sidebar_position: 9
title: Versionamento e Detecção de Atualizações
---
# Versionamento e Detecção Automática de Atualizações
## Visão Geral
A plataforma Decoda implementa um sistema automático de detecção de atualizações que recarrega a aplicação quando um novo deploy é detectado. Isso garante que os usuários sempre utilizem a versão mais recente sem necessidade de ação manual.
---
## Como Funciona
### Arquivo `version.json`
Durante o build Docker, o Dockerfile gera um arquivo `version.json` contendo metadados de versão:
```json
{
"version": "1.1.3",
"commit": "abc1234def5678",
"buildDate": "2026-06-05T10:30:45Z"
}
```
Este arquivo é:
- ✅ Gerado a cada build
- ✅ Servido pelo Nginx junto com os arquivos estáticos
- ✅ Sempre atualizado (sem cache)
- ✅ Acessível em `/version.json`
**Geração no Dockerfile:**
```dockerfile
RUN echo "{\"version\": \"$APP_VERSION\", \"commit\": \"$GIT_COMMIT_HASH\", \"buildDate\": \"$(date)\"}" > public/version.json
```
### Script de Detecção em `index.html`
No `<head>` da página, um script verifica atualizações:
```javascript
(async function checkForUpdates() {
try {
// Busca a versão atual do servidor
const response = await fetch('/version.json?t=' + Date.now());
const newVersion = await response.json();
const lastVersion = sessionStorage.getItem('app_version');
// Se houver versão anterior e for diferente da atual
if (lastVersion && lastVersion !== newVersion.commit) {
console.log('🔄 Novo deploy detectado. Recarregando...');
sessionStorage.setItem('app_version', newVersion.commit);
window.location.reload(true);
return;
}
// Armazena versão atual para próxima verificação
sessionStorage.setItem('app_version', newVersion.commit);
} catch (e) {
console.warn('Falha ao verificar atualizações:', e);
}
})();
```
### Fluxo de Detecção
```
1. Usuário acessa a página (GET /)
2. Script em index.html executa
├─ Faz fetch de /version.json (sem cache: ?t=Date.now())
├─ Compara commit com sessionStorage
├─ Se não há versão anterior:
│ └─ Armazena e continua
└─ Se versão mudou:
├─ Armazena nova versão
├─ Log: "🔄 Novo deploy detectado"
└─ window.location.reload(true) → força reload do cache
```
### Parâmetro `?t=Date.now()`
O parâmetro `?t=` garante que o navegador **não use o cache** de `/version.json`:
- **Sem o parâmetro:** Browser pode servir versão antiga do cache
- **Com o parâmetro:** Browser sempre faz nova requisição
- **Resultado:** Atualizações são detectadas na primeira página acessada
### `window.location.reload(true)`
O parâmetro `true` força reload ignorando cache:
```javascript
window.location.reload(true); // ✅ Ignora cache, carrega do servidor
window.location.reload(); // ❌ Pode usar cache
```
---
## Armazenamento em sessionStorage
O commit hash é armazenado em `sessionStorage` (não `localStorage`):
- **sessionStorage** — Limpo ao fechar a aba/navegador
- **localStorage** — Persiste entre sessões
Usar `sessionStorage` garante que:
- Verificação acontece em cada nova aba/janela
- Histórico de versões não acumula
- Usuário tem sempre a última versão do servidor
---
## Metadados Disponíveis
O arquivo `/version.json` contém:
| Campo | Exemplo | Descrição |
|---|---|---|
| `version` | `1.1.3` | Versão semântica da app |
| `commit` | `abc1234def5678` | Hash curto do commit Git |
| `buildDate` | `2026-06-05T10:30:45Z` | Data/hora do build |
Exemplo de acesso programático:
```javascript
// Obter informações de versão no console
fetch('/version.json')
.then(r => r.json())
.then(v => console.log(v));
// Output:
// { version: "1.1.3", commit: "abc1234", buildDate: "..." }
```
---
## Variáveis de Build
O Dockerfile recebe argumentos para gerar a versão:
```dockerfile
ARG GIT_COMMIT_HASH=unknown
ARG APP_VERSION=1.1.3
RUN echo "{\"version\": \"$APP_VERSION\", \"commit\": \"$GIT_COMMIT_HASH\", ...}" > public/version.json
```
### Passar argumentos
**Via Docker Compose:**
```bash
docker compose build --build-arg GIT_COMMIT_HASH=$(git rev-parse --short HEAD) app
```
**Via arquivo `.env`:**
```bash
GIT_COMMIT_HASH=abc1234
```
**Via docker build direto:**
```bash
docker build --build-arg GIT_COMMIT_HASH=abc1234 -t decoda:latest ./app
```
---
## Casos de Uso
### Usuário deixa a página aberta
```
14:00 — Usuário acessa /atividades
Script detecta versão "abc1234"
14:15 — Deploy realizado com commit "def5678"
14:20 — Usuário navega para /atividades/puzzle
Script detecta versão mudou
→ Recarrega página com novo código
```
### Novo deploy, usuário abre nova aba
```
14:00 — Deploy realizado com versão "def5678"
14:05 — Usuário abre nova aba (GET /)
Script detecta versão "def5678"
→ Versão nova é carregada na aba
```
### Offline, usuário reconecta
```
14:00 — Usuário offline, página em cache
Script falha ao fetch /version.json
→ Log: "Falha ao verificar atualizações"
→ Usuário continua com versão anterior
14:15 — Usuário reconecta e navega
14:20 — Script detecta nova versão
→ Recarrega com versão atualizada
```
---
## Tratamento de Erros
O script trata erros graciosamente:
```javascript
catch (e) {
console.warn('Falha ao verificar atualizações:', e);
}
```
**Cenários:**
-**Offline** — Erro de network, silencioso, continua rodando
-**JSON inválido** — Parse error, log, continua rodando
-**Timeout** — Requisição fica pendurada, timeout natural
-**Nginx indisponível** — Erro 500/502, log, continua rodando
**Resultado:** Sempre funciona, nunca quebra a página
---
## Debugging
### Ver versão atual no console
```javascript
sessionStorage.getItem('app_version')
// Output: "abc1234def5678"
```
### Forçar reload de versão
```javascript
sessionStorage.removeItem('app_version');
location.reload();
// Próximo acesso detectará e armazenará nova versão
```
### Inspecionar /version.json
```bash
# Terminal
curl http://localhost/version.json
# Browser DevTools
fetch('/version.json').then(r => r.json()).then(console.log)
```
---
## Integração com Analytics
O commit hash também é enviado para Google Analytics:
```javascript
// Em usePageTracking.js
analytics.trackPageView({
page_path: location.pathname,
page_title: document.title,
git_commit: window.APP_VERSION?.commit, // Hash do deploy
});
```
Permite rastrear qual versão o usuário estava utilizando quando completou uma atividade.
---
## Boas Práticas
1. **Sempre passar `GIT_COMMIT_HASH`** — Facilita debugging
```bash
docker compose build --build-arg GIT_COMMIT_HASH=$(git rev-parse --short HEAD) app
```
2. **Usar arquivo `.env`** — Mais limpo e repetível
```bash
GIT_COMMIT_HASH=$(git rev-parse --short HEAD) docker compose up --build
```
3. **Monitorar logs** — Verifique `console.log('🔄 Novo deploy detectado')`
```bash
# Browser DevTools → Console
```
4. **Testar localmente** — Modifique `version.json` e navegue para testar
---
## Limitações e Considerações
| Aspecto | Descrição |
|---|---|
| **Timing** | Detecta somente quando usuário acessa página, não em tempo real |
| **sessionStorage** | Limpo ao fechar aba, não persiste entre navegadores |
| **SPA** | Apenas recarrega ao navegar, não há polling contínuo |
| **Sem notificação** | Recarrega silenciosamente, sem avisar usuário |
### Se precisar de comportamento diferente
- **Polling contínuo** — Usar `setInterval()` em vez de só no load
- **Notificação ao usuário** — Mostrar modal antes de reload
- **localStorage** — Persistir versão entre abas/sessões
- **Update prompts** — Permitir usuário decidir quando recarregar
Veja [service-workers.md](sistema-tours.md) para implementações mais avançadas com PWA.
---
## Referências
- [sessionStorage MDN](https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage)
- [HTTP Cache Control](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control)
- [Service Workers para atualizações](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API)

View File

@@ -58,5 +58,17 @@ gitGraph
checkout develop checkout develop
commit id: "ordenação, offline, segurança" commit id: "ordenação, offline, segurança"
checkout main checkout main
merge develop id: "1.1.0 — Em desenvolvimento" tag: "v1.1.0" merge develop id: "1.1.0 — Release" tag: "v1.1.0"
checkout develop
commit id: "analytics, detecção de atualizações"
checkout main
merge develop id: "1.1.3 — Analytics e atualização" tag: "v1.1.3"
``` ```
## Histórico de Versões
| Versão | Data | Destaque Principal |
|---|---|---|
| [**v1.1.3**](v1.1.3.md) | 05/06/2026 | Analytics com Google Analytics 4 e detecção de atualizações automáticas |
| [**v1.1.0**](v1.1.0.md) | 14/07/2026 | Atividade de Ordenação, suporte offline (PWA) e segurança XSS |
| **v1.0.0** | — | Lançamento inicial da plataforma |

View File

@@ -0,0 +1,163 @@
---
sidebar_position: 1
title: "1.1.3"
---
# 1.1.3
**Data de lançamento:** 05/06/2026
---
## Adicionado
### Analytics - Google Analytics 4 (GA4)
Integração completa de analytics para rastreamento de uso e experiência dos estudantes:
- **Rastreamento de páginas** — acompanha quais seções da plataforma são mais visitadas
- **Rastreamento de atividades** — identifica quais atividades educacionais são completadas, falhadas ou abandonadas
- **Rastreamento de fases** — permite entender em qual fase os estudantes têm dificuldade
- **Offline-aware** — não tenta enviar dados quando o estudante está sem conexão
- **Configurável** — pode ser habilitado ou desabilitado via variáveis de ambiente
#### Como usar
**Development (sem analytics):**
```bash
docker compose build --build-arg VITE_ANALYTICS_PROVIDER=noop app
```
**Production (com GA4):**
```bash
docker compose build \
--build-arg VITE_ANALYTICS_PROVIDER=ga4 \
--build-arg VITE_GA4_ID=G-SEU_ID_AQUI \
--build-arg GIT_COMMIT_HASH=$(git rev-parse --short HEAD) app
```
Veja a [documentação completa de Analytics](../plataforma/arquitetura/analytics.md) para detalhes de integração e relatórios.
### Detecção Automática de Atualizações
Script no `index.html` que detecta novos deploys e recarrega automaticamente:
```javascript
(async function checkForUpdates() {
const response = await fetch('/version.json');
const newVersion = await response.json();
const lastVersion = sessionStorage.getItem('app_version');
if (lastVersion && lastVersion !== newVersion.commit) {
console.log('🔄 Novo deploy detectado. Recarregando...');
window.location.reload(true);
}
sessionStorage.setItem('app_version', newVersion.commit);
})();
```
**Benefícios:**
- Usuários recebem novas versões automaticamente
- Sem necessidade de limpar cache ou recarregar manual
- Transparente — nenhuma intervenção do usuário necessária
- Apenas recarrega se houver mudança de versão
---
## Melhorias
### Build Docker Aprimorado
O `Dockerfile` agora suporta argumentos de build para configurar analytics e versionamento:
```dockerfile
ARG GIT_COMMIT_HASH=unknown
ARG APP_VERSION=1.1.3
ARG VITE_ANALYTICS_PROVIDER=ga4
ARG VITE_GA4_ID=SEU_ID_AQUI
ARG VITE_GA4_DEBUG=false
```
Permite builds reproduzíveis e controlados por ambiente.
---
## Segurança
### Conformidade LGPD/GDPR
- Banner de consentimento antes de qualquer rastreamento
- Implementação de Google Consent Mode
- Opção clara de rejeitar analytics
- Dados anonimizados (anonymize_ip: true)
- Política de Privacidade atualizada em `/privacy-policy`
---
## Documentação
Documentação técnica completa adicionada:
- **[Analytics - GA4](../plataforma/arquitetura/analytics.md)** — Visão geral, arquitetura, build e relatórios
- **[Versionamento e Atualizações](../plataforma/arquitetura/versionamento-atualizacoes.md)** — Detecção automática de deploys
---
## Notas de Deploy
### Primeiro Deploy com Analytics
Ao fazer deploy em produção com GA4:
1. Configure as variáveis de ambiente:
```bash
VITE_ANALYTICS_PROVIDER=ga4
VITE_GA4_ID=G-SEU_ID_AQUI
```
2. Obtenha o ID do GA4:
- Acesse [https://analytics.google.com](https://analytics.google.com)
- Vá para `Administração → Data Streams`
- Copie o ID de medição (formato: G-XXXXXXXXXX)
3. Compile com:
```bash
docker compose build --build-arg VITE_GA4_ID=G-SEU_ID app
```
4. Teste em produção:
- Abra a app no browser
- Aceite cookies quando o banner aparecer
- Abra DevTools → Network
- Procure por requisições para `googletagmanager.com`
- Verifique `Relatórios → Em tempo real` no GA4
### Se optar por não usar Analytics
Para desabilitar analytics em qualquer ambiente:
```bash
docker compose build --build-arg VITE_ANALYTICS_PROVIDER=noop app
```
---
## Changelog Completo
**Adicionado:**
- ✨ Analytics com Google Analytics 4 (mas preparado para uso de outras ferramentas no futuro como Umami)
- ✨ Detecção automática de atualizações no `index.html`
- ✨ Documentação de Analytics e build Docker
- ✨ Hooks de rastreamento: `usePageTracking`, `useActivityTracking`, `useLetramentoTracking`
**Melhorado:**
- 🔧 Build Docker com suporte a argumentos de GA4
- 🔧 Versionamento integrado (`version.json`)
- 📚 Documentação técnica expandida
**Segurança:**
- 🔒 Implementação de Google Consent Mode
- 🔒 Anonimização de IPs em GA4