diff --git a/README.md b/README.md index a61f7ad..97321a6 100644 --- a/README.md +++ b/README.md @@ -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 ``` +#### 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 diff --git a/app/.dockerignore b/app/.dockerignore new file mode 100644 index 0000000..ee0d069 --- /dev/null +++ b/app/.dockerignore @@ -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 diff --git a/app/.env.example b/app/.env.example index ffcbe84..ec516c2 100644 --- a/app/.env.example +++ b/app/.env.example @@ -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_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 + +# 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 +# diff --git a/app/Dockerfile b/app/Dockerfile index 4d4a502..a19fdce 100644 --- a/app/Dockerfile +++ b/app/Dockerfile @@ -15,19 +15,16 @@ ENV VITE_ANALYTICS_PROVIDER=$VITE_ANALYTICS_PROVIDER ENV VITE_GA4_ID=$VITE_GA4_ID ENV VITE_GA4_DEBUG=$VITE_GA4_DEBUG -RUN npm install -g pnpm - COPY package.json pnpm-lock.yaml ./ -RUN pnpm install +RUN npm install -g pnpm && pnpm install --frozen-lockfile COPY . . -RUN echo "{\"version\": \"$APP_VERSION\", \"commit\": \"$GIT_COMMIT_HASH\", \"buildDate\": \"$(date)\"}" > public/version.json - -RUN pnpm run build +RUN echo "{\"version\": \"$APP_VERSION\", \"commit\": \"$GIT_COMMIT_HASH\", \"buildDate\": \"$(date)\"}" > public/version.json && \ + pnpm run build && \ + rm -rf node_modules .pnpm-store FROM nginx:alpine COPY --from=builder /app/dist /usr/share/nginx/html - COPY nginx-spa.conf /etc/nginx/conf.d/default.conf diff --git a/app/index.html b/app/index.html index 7869230..d3baf2e 100644 --- a/app/index.html +++ b/app/index.html @@ -6,6 +6,26 @@ Decoda +
diff --git a/app/src/App.jsx b/app/src/App.jsx index dfe40e5..9a0405a 100644 --- a/app/src/App.jsx +++ b/app/src/App.jsx @@ -12,13 +12,15 @@ import LabPython from "./pages/LabPython/LabPython"; import ScrollToTop from "./components/ScrollToTop"; import { getAnalytics, usePageTracking } from "./services/analytics"; import { initializeAnalytics, analyticsConfig } from "./services/analytics"; -import { ConsentManager } from "./services/consent"; // Inline CookieBanner para evitar bloqueio do Brave function CookieBanner() { const [visible, setVisible] = useState(false); + const enableBanner = import.meta.env.VITE_ENABLE_CONSENT_BANNER === 'true'; useEffect(() => { + if (!enableBanner) return; + try { const stored = localStorage.getItem('decoda_consent'); if (!stored) { @@ -27,7 +29,7 @@ function CookieBanner() { } catch (e) { console.error('Consent check failed:', e); } - }, []); + }, [enableBanner]); const handleAccept = () => { try { @@ -57,7 +59,7 @@ function CookieBanner() { } }; - if (!visible) return null; + if (!visible || !enableBanner) return null; return (
@@ -212,11 +214,10 @@ export default function App() { const [analyticsReady, setAnalyticsReady] = useState(false); useEffect(() => { - const hasConsent = ConsentManager.hasConsent(); initializeAnalytics({ providerType: analyticsConfig.providerType, measurementId: analyticsConfig.measurementId, - hasConsent, + hasConsent: true, debugMode: analyticsConfig.debugMode, }); diff --git a/docs/docs/plataforma/arquitetura/analytics.md b/docs/docs/plataforma/arquitetura/analytics.md new file mode 100644 index 0000000..539c304 --- /dev/null +++ b/docs/docs/plataforma/arquitetura/analytics.md @@ -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 ; +} +``` + +**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 ( + + ); +} +``` + +**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. diff --git a/docs/docs/plataforma/arquitetura/intro.md b/docs/docs/plataforma/arquitetura/intro.md index 0ecf29f..471d03e 100644 --- a/docs/docs/plataforma/arquitetura/intro.md +++ b/docs/docs/plataforma/arquitetura/intro.md @@ -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 letramento em `app/src/atividades/letramento`. - Componentes compartilhados em `app/src/components`. -- Estado compartilhado em `app/src/contexts`. \ No newline at end of file +- 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 \ No newline at end of file diff --git a/docs/docs/plataforma/arquitetura/versionamento-atualizacoes.md b/docs/docs/plataforma/arquitetura/versionamento-atualizacoes.md new file mode 100644 index 0000000..6ad6ab5 --- /dev/null +++ b/docs/docs/plataforma/arquitetura/versionamento-atualizacoes.md @@ -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 `` 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) diff --git a/docs/docs/releases/intro.md b/docs/docs/releases/intro.md index 189f664..00cf24f 100644 --- a/docs/docs/releases/intro.md +++ b/docs/docs/releases/intro.md @@ -58,5 +58,17 @@ gitGraph checkout develop commit id: "ordenação, offline, segurança" 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 | diff --git a/docs/docs/releases/v1.1.3.md b/docs/docs/releases/v1.1.3.md new file mode 100644 index 0000000..0a98b86 --- /dev/null +++ b/docs/docs/releases/v1.1.3.md @@ -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