# Changelog

## [1.3.0] - 2026-05-21

### PWA
- `manifest.json` criado em `public/` com nome, ícones (44px, 150px, 500px), display standalone e cores do tema Bootstrap dark
- `sw.js` criado: cache-first para assets estáticos (CSS, JS, fontes, imagens, CDN Bootstrap), network-first para navegação HTML, nunca intercepta chamadas de API
- Registro do Service Worker nos dois layouts (`app.php` e `auth.php`) via `navigator.serviceWorker.register('/sw.js')`
- `<link rel="manifest">` e `<meta name="theme-color">` adicionados em ambos os layouts
- `.htaccess` atualizado: `manifest.json` excluído da regra de bloqueio de `.json`; `sw.js` servido com `Cache-Control: no-store`

### Dashboard admin
- Cards KPI no painel inicial do admin: Operadores, Setores, Canais e Palavras-chave
- Busca paralela via `Promise.all` em `/operadores`, `/setores`, `/canais` e `/palavras-chave`
- Atualização automática a cada 60 segundos via `setInterval`

### Chat — envio de arquivos
- Botão "Anexar" (ícone paperclip) no rodapé do chat do operador
- Seletor de arquivo oculto com `accept` configurado para imagens, áudio, vídeo, PDF e documentos Office
- Preview do arquivo selecionado com nome, tamanho (MB), ícone por tipo e botão "×" para remover
- Codificação `FileReader.readAsDataURL` → base64, enviado no campo `arquivo_url`
- Tipo da mensagem detectado pelo MIME: `IMAGEM` / `AUDIO` / `VIDEO` / `DOCUMENTO`
- Arquivo e preview limpos automaticamente após envio bem-sucedido ou quando o atendimento é fechado

## [1.2.0] - 2026-05-21

### UX — Fase 4 (continuação)
- **Notificações nativas do browser** para operadores: solicita permissão ao entrar no painel, notifica quando novo atendimento chega na fila e quando nova mensagem inbound é recebida (apenas quando o tab está em segundo plano)
- **Tempo relativo** em todos os timestamps do painel operador: "há 5 min", "há 2h", "ontem" (tooltip mostra a data completa original); suporta formato brasileiro DD/MM/AAAA HH:MM:SS e ISO 8601
- `App.requestNotificationPermission()`, `App.notify()` e `App.timeAgo()` adicionados ao namespace global `App`

## [1.1.0] - 2026-05-21

### Segurança
- JWT movido de `localStorage` para cookie `httpOnly; Secure; SameSite=Strict` — token não acessível ao JavaScript
- `session_regenerate_id(true)` após login para prevenir session fixation
- Rate limiting no endpoint `/auth`: 10 tentativas / 5 minutos por IP
- Headers HTTP de segurança: `X-Content-Type-Options`, `X-Frame-Options`, `X-XSS-Protection`, `Referrer-Policy`, `Permissions-Policy`
- Hardening de sessão PHP: `httponly`, `secure`, `samesite=Strict`, `use_strict_mode`
- Cookie `auth_token` removido corretamente no logout
- `ApiClient::proxyWithBearer()` usa `$_SESSION['auth_token']` como fonte primária do token
- `.env` de produção criado com `APP_DEBUG=false`, `APP_ENV=production`
- `.htaccess` protege arquivos sensíveis (`.env`, `.log`, `.lock`, `.md`, `.sh`, `.sql`, `.bak`)
- Listagem de diretórios desabilitada (`Options -Indexes`)

### Performance
- Versionamento automático de assets JS/CSS via `filemtime()` — cache bust sem deploy manual
- GZIP habilitado para HTML, CSS, JS, JSON, SVG e fontes
- Cache de browser configurado por tipo de arquivo (imagens 30 dias, fontes 1 ano, JS/CSS 7 dias)
- Redirecionamento HTTP → HTTPS via `.htaccess`

### Qualidade de código
- `RateLimiter.php` criado em `app/Support/`
- `Logger.php` criado em `app/Support/` — log rotativo diário em `storage/logs/`
- Erros de API 5xx e falhas cURL logados automaticamente
- Handler global de exceções com log em `index.php`
- `extractOperadorId()` centralizado no `AtendimentoController` — duplicação removida
- `curl_close()` depreciado (PHP 8.0+) removido do `ApiClient`
- `App.currentUser()` lê dados do usuário via `AppConfig.currentUser` (injetado pelo PHP)

### UX
- Detecção de estado offline com banner vermelho automático — verde ao reconectar
- `App.confirm()` — modal de confirmação Bootstrap reutilizável para ações destrutivas
- `App.initTableSearch()` — campo de busca com filtro em tempo real em todas as tabelas do painel

## [1.0.0] - 2026-04-30
- Estrutura inicial criada.
