diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index ebe51d3..0000000 --- a/.editorconfig +++ /dev/null @@ -1,12 +0,0 @@ -# EditorConfig is awesome: https://EditorConfig.org - -# top-most EditorConfig file -root = true - -[*] -indent_style = space -indent_size = 2 -end_of_line = lf -charset = utf-8 -trim_trailing_whitespace = false -insert_final_newline = false \ No newline at end of file diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..6562bcb --- /dev/null +++ b/.prettierignore @@ -0,0 +1,6 @@ +# Package Managers +package-lock.json +pnpm-lock.yaml +yarn.lock +bun.lock +bun.lockb diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..fb40e07 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,18 @@ +{ + "useTabs": true, + "singleQuote": true, + "trailingComma": "none", + "printWidth": 100, + "plugins": [ + "prettier-plugin-svelte", + "prettier-plugin-tailwindcss" + ], + "overrides": [ + { + "files": "*.svelte", + "options": { + "parser": "svelte" + } + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..cf7e14f --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,13 @@ +{ + // "editor.formatOnSave": true, + // "editor.defaultFormatter": "biomejs.biome", + // "editor.codeActionsOnSave": { + // "source.fixAll.biome": "always" + // }, + // "[typescript]": { + // "editor.defaultFormatter": "biomejs.biome" + // }, + // "[svelte]": { + // "editor.defaultFormatter": "biomejs.biome" + // } +} \ No newline at end of file diff --git a/CONFIGURACAO_PUSH_NOTIFICATIONS.md b/CONFIGURACAO_PUSH_NOTIFICATIONS.md deleted file mode 100644 index 2f072f7..0000000 --- a/CONFIGURACAO_PUSH_NOTIFICATIONS.md +++ /dev/null @@ -1,117 +0,0 @@ -# 🔔 Configuração de Push Notifications - -## Passo 1: Configurar VAPID Keys - -### 1.1 Gerar VAPID Keys (se ainda não tiver) - -Execute no diretório do backend: -```bash -cd packages/backend -bunx web-push generate-vapid-keys -``` - -Isso gerará duas chaves: -- **Public Key**: Segura para expor no frontend -- **Private Key**: Deve ser mantida em segredo, apenas no backend - -### 1.2 Configurar no Convex (Backend) - -As variáveis de ambiente no Convex são configuradas via dashboard ou CLI: - -#### Opção A: Via Dashboard Convex -1. Acesse https://dashboard.convex.dev -2. Selecione seu projeto -3. Vá em **Settings** > **Environment Variables** -4. Adicione as seguintes variáveis: - -``` -VAPID_PUBLIC_KEY=BDerX0lK_hBCLpC7EbuxoJb2EJ7bcCLaHWxkNumVbvrx9w0MmJduHxJOP3WBwBP-SpQGcueMOyHCv7LFK3KnQks -VAPID_PRIVATE_KEY=KWkJLMxCuCPQQiRXIJEt06G4pTdW0FaUN_vMyY02sc4 -FRONTEND_URL=http://localhost:5173 -``` - -#### Opção B: Via CLI Convex -```bash -cd packages/backend -npx convex env set VAPID_PUBLIC_KEY "BDerX0lK_hBCLpC7EbuxoJb2EJ7bcCLaHWxkNumVbvrx9w0MmJduHxJOP3WBwBP-SpQGcueMOyHCv7LFK3KnQks" -npx convex env set VAPID_PRIVATE_KEY "KWkJLMxCuCPQQiRXIJEt06G4pTdW0FaUN_vMyY02sc4" -npx convex env set FRONTEND_URL "http://localhost:5173" -``` - -### 1.3 Configurar no Frontend - -Crie um arquivo `.env` no diretório `apps/web/` com: - -```env -VITE_VAPID_PUBLIC_KEY=BDerX0lK_hBCLpC7EbuxoJb2EJ7bcCLaHWxkNumVbvrx9w0MmJduHxJOP3WBwBP-SpQGcueMOyHCv7LFK3KnQks -``` - -**Importante**: Reinicie o servidor de desenvolvimento após criar/modificar o `.env`. - -## Passo 2: Configurar FRONTEND_URL - -A variável `FRONTEND_URL` é usada nos templates de email para gerar links de volta ao sistema. - -### Para Desenvolvimento: -``` -FRONTEND_URL=http://localhost:5173 -``` - -### Para Produção: -``` -FRONTEND_URL=https://seu-dominio.com -``` - -## Passo 3: Testar Push Notifications - -### 3.1 Registrar Subscription no Frontend - -O sistema automaticamente solicita permissão e registra a subscription quando: -1. O usuário faz login -2. Acessa o chat pela primeira vez -3. O Service Worker é instalado - -### 3.2 Verificar se está funcionando - -1. Abra o DevTools do navegador (F12) -2. Vá na aba **Application** > **Service Workers** -3. Verifique se o Service Worker está registrado -4. Vá em **Application** > **Notifications** -5. Verifique se a permissão está concedida - -### 3.3 Testar envio de push - -1. Abra o chat em duas abas/janelas diferentes -2. Faça login com usuários diferentes -3. Envie uma mensagem de um usuário para o outro -4. A mensagem deve aparecer como notificação push na outra aba - -## Troubleshooting - -### Push notifications não funcionam - -1. **Verificar VAPID keys**: Certifique-se de que as keys estão configuradas corretamente -2. **Verificar Service Worker**: O arquivo `sw.js` deve estar em `/static/sw.js` -3. **Verificar permissões**: O navegador deve ter permissão para notificações -4. **Verificar console**: Procure por erros no console do navegador e do Convex - -### Erro "VAPID keys não configuradas" - -- Verifique se as variáveis de ambiente estão configuradas no Convex -- Reinicie o servidor Convex após configurar as variáveis -- Verifique se os nomes das variáveis estão corretos (case-sensitive) - -### Service Worker não registra - -- Verifique se o arquivo `sw.js` existe em `apps/web/static/sw.js` -- Verifique se o servidor está servindo arquivos estáticos corretamente -- Limpe o cache do navegador e tente novamente - -## Segurança - -⚠️ **IMPORTANTE**: -- A **Private Key** nunca deve ser exposta no frontend -- Use variáveis de ambiente diferentes para desenvolvimento e produção -- Regenere as keys se suspeitar de comprometimento -- Mantenha as keys em segredo (não commite no Git) - diff --git a/GUIA_TESTE_PUSH_NOTIFICATIONS.md b/GUIA_TESTE_PUSH_NOTIFICATIONS.md deleted file mode 100644 index 1e31371..0000000 --- a/GUIA_TESTE_PUSH_NOTIFICATIONS.md +++ /dev/null @@ -1,214 +0,0 @@ -# 🧪 Guia de Teste - Push Notifications e Melhorias do Chat - -## Pré-requisitos - -1. ✅ Convex rodando (`cd packages/backend && bun run dev`) -2. ✅ Frontend rodando (`cd apps/web && bun run dev`) -3. ✅ Variáveis de ambiente configuradas (ver `configurar-variaveis-ambiente.md`) -4. ✅ Usuários criados no sistema - -## Teste 1: Configuração de Push Notifications - -### 1.1 Verificar Service Worker - -1. Abra o navegador em `http://localhost:5173` -2. Faça login no sistema -3. Abra DevTools (F12) -4. Vá em **Application** > **Service Workers** -5. ✅ Verifique se `sw.js` está registrado e ativo - -### 1.2 Solicitar Permissão de Notificações - -1. Abra o chat no sistema -2. O sistema deve solicitar permissão para notificações automaticamente -3. Clique em **Permitir** -4. ✅ Verifique em **Application** > **Notifications** que a permissão está concedida - -### 1.3 Verificar Subscription - -1. Abra o Console do DevTools -2. Execute: -```javascript -navigator.serviceWorker.ready.then(reg => { - reg.pushManager.getSubscription().then(sub => { - console.log('Subscription:', sub); - }); -}); -``` -3. ✅ Deve retornar um objeto Subscription com endpoint e keys - -## Teste 2: Envio e Recebimento de Push Notifications - -### 2.1 Teste Básico - -1. Abra o sistema em **duas abas diferentes** (ou dois navegadores) -2. Faça login com usuários diferentes em cada aba -3. Na aba 1, abra uma conversa com o usuário da aba 2 -4. Envie uma mensagem da aba 1 -5. ✅ A aba 2 deve receber uma notificação push (mesmo se estiver em background) - -### 2.2 Teste de Menção - -1. Na aba 1, envie uma mensagem mencionando o usuário da aba 2 (use @) -2. ✅ A aba 2 deve receber uma notificação push destacada - -### 2.3 Teste Offline - -1. Feche a aba 2 (ou coloque o navegador em modo offline) -2. Envie uma mensagem da aba 1 -3. ✅ O sistema deve enviar um email para o usuário da aba 2 (se estiver offline) - -## Teste 3: Edição de Mensagens - -### 3.1 Editar Mensagem Própria - -1. Envie uma mensagem no chat -2. Clique no ícone ✏️ ao lado da mensagem -3. Edite o conteúdo -4. Pressione **Ctrl+Enter** ou clique em **Salvar** -5. ✅ A mensagem deve ser atualizada com indicador "(editado)" - -### 3.2 Tentar Editar Mensagem de Outro Usuário - -1. Tente editar uma mensagem de outro usuário -2. ✅ Não deve aparecer o botão de editar (ou deve retornar erro) - -## Teste 4: Soft Delete de Mensagens - -### 4.1 Deletar Mensagem Própria - -1. Envie uma mensagem -2. Clique no ícone 🗑️ ao lado da mensagem -3. Confirme a exclusão -4. ✅ A mensagem deve ser marcada como "Mensagem deletada" - -### 4.2 Tentar Deletar Mensagem de Outro Usuário - -1. Tente deletar uma mensagem de outro usuário -2. ✅ Não deve aparecer o botão de deletar (ou deve retornar erro) - -## Teste 5: Respostas Encadeadas - -### 5.1 Responder Mensagem - -1. Clique no botão **↪️ Responder** em uma mensagem -2. ✅ Deve aparecer um preview da mensagem original no campo de input -3. Digite sua resposta e envie -4. ✅ A mensagem enviada deve mostrar o preview da mensagem original acima - -### 5.2 Visualizar Thread - -1. Envie várias respostas para diferentes mensagens -2. ✅ Cada resposta deve mostrar claramente qual mensagem está respondendo - -## Teste 6: Preview de Links - -### 6.1 Enviar Mensagem com URL - -1. Envie uma mensagem contendo uma URL (ex: `https://www.google.com`) -2. Aguarde alguns segundos -3. ✅ Deve aparecer um preview do link abaixo da mensagem com: - - Imagem (se disponível) - - Título - - Descrição - - Site/nome do domínio - -### 6.2 Testar Diferentes URLs - -Teste com diferentes tipos de URLs: -- ✅ Google: `https://www.google.com` -- ✅ YouTube: `https://www.youtube.com` -- ✅ Artigo de notícia -- ✅ Site sem Open Graph (deve funcionar mesmo assim) - -## Teste 7: Busca Full-Text - -### 7.1 Busca Básica - -1. Envie algumas mensagens com palavras específicas -2. Use a busca no chat (se implementada) ou a query de busca -3. ✅ Deve encontrar mensagens mesmo com acentos diferentes - -### 7.2 Busca com Filtros - -1. Busque mensagens por: - - ✅ Remetente específico - - ✅ Tipo (texto, arquivo, imagem) - - ✅ Período de data -2. ✅ Os filtros devem funcionar corretamente - -## Teste 8: Rate Limiting de Emails - -### 8.1 Enviar Múltiplos Emails - -1. Configure o sistema para enviar emails -2. Tente enviar mais de 10 emails em 1 minuto -3. ✅ Deve retornar erro de rate limit após o limite - -### 8.2 Verificar Delay Exponencial - -1. Aguarde o rate limit ser aplicado -2. Tente enviar novamente -3. ✅ Deve haver um delay antes de permitir novo envio - -## Checklist de Validação - -- [ ] Service Worker registrado e funcionando -- [ ] Permissão de notificações concedida -- [ ] Push notifications sendo recebidas -- [ ] Emails sendo enviados quando usuário offline -- [ ] Edição de mensagens funcionando -- [ ] Soft delete funcionando -- [ ] Respostas encadeadas funcionando -- [ ] Preview de links aparecendo -- [ ] Busca full-text funcionando -- [ ] Rate limiting de emails funcionando - -## Problemas Comuns e Soluções - -### Push notifications não funcionam - -**Problema**: Notificações não aparecem - -**Soluções**: -1. Verifique se as VAPID keys estão configuradas no Convex -2. Verifique se `VITE_VAPID_PUBLIC_KEY` está no `.env` do frontend -3. Reinicie o servidor Convex e frontend -4. Limpe o cache do navegador -5. Verifique o console para erros - -### Preview de links não aparece - -**Problema**: Links não geram preview - -**Soluções**: -1. Verifique se a URL é válida (começa com http:// ou https://) -2. Aguarde alguns segundos (processamento é assíncrono) -3. Verifique o console do Convex para erros na extração -4. Alguns sites bloqueiam scrapers - isso é normal - -### Edição não funciona - -**Problema**: Botão de editar não aparece ou não funciona - -**Soluções**: -1. Verifique se a mensagem é sua (só pode editar próprias mensagens) -2. Verifique se a mensagem não foi deletada -3. Verifique o console para erros -4. Certifique-se de que a mutation `editarMensagem` está funcionando - -## Relatório de Testes - -Após completar os testes, preencha: - -- **Data**: ___________ -- **Testador**: ___________ -- **Ambiente**: [ ] Desenvolvimento [ ] Produção -- **Navegador**: ___________ -- **Resultados**: ___________ - -**Observações**: -_______________________________________ -_______________________________________ -_______________________________________ - diff --git a/PASSO_A_PASSO_CONFIGURACAO.md b/PASSO_A_PASSO_CONFIGURACAO.md deleted file mode 100644 index 46a90ce..0000000 --- a/PASSO_A_PASSO_CONFIGURACAO.md +++ /dev/null @@ -1,163 +0,0 @@ -# 📋 Passo a Passo - Configuração Completa - -## ✅ Passo 1: Configurar VAPID Keys - -### 1.1 Configurar no Convex (Backend) - -**Opção A: Via Dashboard (Recomendado)** - -1. Acesse https://dashboard.convex.dev -2. Selecione seu projeto -3. Vá em **Settings** > **Environment Variables** -4. Adicione as seguintes variáveis: - -``` -VAPID_PUBLIC_KEY=BDerX0lK_hBCLpC7EbuxoJb2EJ7bcCLaHWxkNumVbvrx9w0MmJduHxJOP3WBwBP-SpQGcueMOyHCv7LFK3KnQks -VAPID_PRIVATE_KEY=KWkJLMxCuCPQQiRXIJEt06G4pTdW0FaUN_vMyY02sc4 -FRONTEND_URL=http://localhost:5173 -``` - -**Opção B: Via CLI** - -Execute do diretório raiz do projeto: - -```powershell -cd packages/backend -npx convex env set VAPID_PUBLIC_KEY "BDerX0lK_hBCLpC7EbuxoJb2EJ7bcCLaHWxkNumVbvrx9w0MmJduHxJOP3WBwBP-SpQGcueMOyHCv7LFK3KnQks" -npx convex env set VAPID_PRIVATE_KEY "KWkJLMxCuCPQQiRXIJEt06G4pTdW0FaUN_vMyY02sc4" -npx convex env set FRONTEND_URL "http://localhost:5173" -``` - -**Opção C: Usar Script Automático** - -Execute na raiz do projeto: - -```powershell -.\scripts\configurar-push-notifications.ps1 -``` - -### 1.2 Configurar no Frontend - -Crie o arquivo `apps/web/.env` com: - -```env -VITE_VAPID_PUBLIC_KEY=BDerX0lK_hBCLpC7EbuxoJb2EJ7bcCLaHWxkNumVbvrx9w0MmJduHxJOP3WBwBP-SpQGcueMOyHCv7LFK3KnQks -``` - -**Importante**: Reinicie o servidor frontend após criar/modificar o `.env` - -## ✅ Passo 2: Configurar FRONTEND_URL - -A variável `FRONTEND_URL` já foi configurada no Passo 1.1. Ela é usada nos templates de email para gerar links de volta ao sistema. - -**Para Desenvolvimento:** -``` -FRONTEND_URL=http://localhost:5173 -``` - -**Para Produção (quando fizer deploy):** -``` -FRONTEND_URL=https://seu-dominio.com -``` - -## ✅ Passo 3: Testar Funcionalidades - -### 3.1 Verificar Configuração Inicial - -1. **Inicie o Convex** (se não estiver rodando): - ```bash - cd packages/backend - bun run dev - ``` - -2. **Inicie o Frontend** (se não estiver rodando): - ```bash - cd apps/web - bun run dev - ``` - -3. **Verifique as variáveis de ambiente**: - - No Convex Dashboard: Settings > Environment Variables - - No Frontend: Verifique se `apps/web/.env` existe - -### 3.2 Testar Push Notifications - -1. Abra `http://localhost:5173` no navegador -2. Faça login no sistema -3. Abra DevTools (F12) > **Application** > **Service Workers** -4. ✅ Verifique se `sw.js` está registrado -5. ✅ Verifique se a permissão de notificações foi solicitada - -### 3.3 Testar Chat Completo - -Siga o guia completo em `GUIA_TESTE_PUSH_NOTIFICATIONS.md` para testar: -- ✅ Push notifications -- ✅ Edição de mensagens -- ✅ Soft delete -- ✅ Respostas encadeadas -- ✅ Preview de links -- ✅ Busca full-text - -## 🔍 Verificação Rápida - -Execute estes comandos para verificar: - -### Verificar Variáveis no Convex: -```bash -cd packages/backend -npx convex env list -``` - -Deve mostrar: -- `VAPID_PUBLIC_KEY` -- `VAPID_PRIVATE_KEY` -- `FRONTEND_URL` - -### Verificar Frontend: -```bash -cd apps/web -# Verifique se o arquivo .env existe -cat .env -``` - -## 🐛 Troubleshooting - -### Problema: Variáveis não aparecem no Convex - -**Solução**: -- Certifique-se de estar no projeto correto no dashboard -- Reinicie o servidor Convex após configurar -- Use `npx convex env list` para verificar - -### Problema: Frontend não encontra VAPID_PUBLIC_KEY - -**Solução**: -- Verifique se o arquivo `.env` está em `apps/web/.env` -- Verifique se a variável começa com `VITE_` -- Reinicie o servidor frontend -- Limpe o cache do navegador - -### Problema: Service Worker não registra - -**Solução**: -- Verifique se `apps/web/static/sw.js` existe -- Abra DevTools > Application > Service Workers -- Clique em "Unregister" e recarregue a página -- Verifique o console para erros - -## 📝 Checklist Final - -- [ ] VAPID keys configuradas no Convex -- [ ] FRONTEND_URL configurada no Convex -- [ ] VITE_VAPID_PUBLIC_KEY no `.env` do frontend -- [ ] Convex rodando -- [ ] Frontend rodando -- [ ] Service Worker registrado -- [ ] Permissão de notificações concedida -- [ ] Push notifications funcionando -- [ ] Todas as funcionalidades testadas - -## 🎉 Pronto! - -Após completar os 3 passos, o sistema estará totalmente configurado e pronto para uso! - diff --git a/RESUMO_CONFIGURACAO_COMPLETA.md b/RESUMO_CONFIGURACAO_COMPLETA.md deleted file mode 100644 index a7a83b9..0000000 --- a/RESUMO_CONFIGURACAO_COMPLETA.md +++ /dev/null @@ -1,68 +0,0 @@ -# ✅ Resumo da Configuração Completa - -## 📋 Passo 1: VAPID Keys - CONCLUÍDO - -### Keys Geradas: -- **Public Key**: `BDerX0lK_hBCLpC7EbuxoJb2EJ7bcCLaHWxkNumVbvrx9w0MmJduHxJOP3WBwBP-SpQGcueMOyHCv7LFK3KnQks` -- **Private Key**: `KWkJLMxCuCPQQiRXIJEt06G4pTdW0FaUN_vMyY02sc4` - -### Configuração Necessária: - -**1. No Convex (Backend):** -- Via Dashboard: Settings > Environment Variables -- Adicionar: `VAPID_PUBLIC_KEY`, `VAPID_PRIVATE_KEY`, `FRONTEND_URL` -- OU executar: `.\scripts\configurar-push-notifications.ps1` - -**2. No Frontend:** -- Criar arquivo `apps/web/.env` -- Adicionar: `VITE_VAPID_PUBLIC_KEY=BDerX0lK_hBCLpC7EbuxoJb2EJ7bcCLaHWxkNumVbvrx9w0MmJduHxJOP3WBwBP-SpQGcueMOyHCv7LFK3KnQks` - -## 📋 Passo 2: FRONTEND_URL - CONCLUÍDO - -- Valor padrão: `http://localhost:5173` -- Configurar no Convex junto com as VAPID keys -- Usado nos templates de email para links de retorno - -## 📋 Passo 3: Testes - PRONTO PARA EXECUTAR - -### Arquivos Criados: -- ✅ `PushNotificationManager.svelte` - Registra subscription automaticamente -- ✅ `GUIA_TESTE_PUSH_NOTIFICATIONS.md` - Guia completo de testes -- ✅ `PASSO_A_PASSO_CONFIGURACAO.md` - Instruções detalhadas -- ✅ `CONFIGURACAO_PUSH_NOTIFICATIONS.md` - Documentação técnica -- ✅ `scripts/configurar-push-notifications.ps1` - Script automático - -### Para Testar: - -1. **Configure as variáveis** (ver Passo 1) -2. **Reinicie os servidores** (Convex e Frontend) -3. **Faça login** no sistema -4. **Siga o guia**: `GUIA_TESTE_PUSH_NOTIFICATIONS.md` - -## 🎯 Checklist de Configuração - -- [ ] VAPID keys configuradas no Convex Dashboard -- [ ] FRONTEND_URL configurada no Convex -- [ ] Arquivo `apps/web/.env` criado com VITE_VAPID_PUBLIC_KEY -- [ ] Convex reiniciado após configurar variáveis -- [ ] Frontend reiniciado após criar .env -- [ ] Service Worker registrado (verificar DevTools) -- [ ] Permissão de notificações concedida -- [ ] Testes executados conforme guia - -## 📚 Documentação Disponível - -1. **CONFIGURACAO_PUSH_NOTIFICATIONS.md** - Configuração técnica detalhada -2. **PASSO_A_PASSO_CONFIGURACAO.md** - Instruções passo a passo -3. **GUIA_TESTE_PUSH_NOTIFICATIONS.md** - Guia completo de testes -4. **configurar-variaveis-ambiente.md** - Referência rápida - -## 🚀 Próximos Passos - -1. Execute o script de configuração OU configure manualmente -2. Reinicie os servidores -3. Teste todas as funcionalidades -4. Reporte qualquer problema encontrado - -**Tudo pronto para configuração e testes!** 🎉 - diff --git a/apps/web/eslint.config.js b/apps/web/eslint.config.js new file mode 100644 index 0000000..25fd275 --- /dev/null +++ b/apps/web/eslint.config.js @@ -0,0 +1,20 @@ +import { config as svelteConfigBase } from '@sgse-app/eslint-config/svelte'; +import svelteConfig from './svelte.config.js'; +import ts from 'typescript-eslint'; +import { defineConfig } from "eslint/config"; + +/** @type {import("eslint").Linter.Config} */ +export default defineConfig([ + ...svelteConfigBase, + { + files: ['**/*.svelte', '**/*.svelte.ts', '**/*.svelte.js'], + languageOptions: { + parserOptions: { + projectService: true, + extraFileExtensions: ['.svelte'], + parser: ts.parser, + svelteConfig + } + } + } +]) \ No newline at end of file diff --git a/apps/web/package.json b/apps/web/package.json index 7061285..61cc60c 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -12,6 +12,7 @@ "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch" }, "devDependencies": { + "@sgse-app/eslint-config": "*", "@sveltejs/adapter-auto": "^6.1.0", "@sveltejs/kit": "^2.31.1", "@sveltejs/vite-plugin-svelte": "^6.1.2", @@ -27,6 +28,8 @@ "vite": "^7.1.2" }, "dependencies": { + "eslint": "catalog:", + "@convex-dev/better-auth": "^0.9.7", "@dicebear/collection": "^9.2.4", "@dicebear/core": "^9.2.4", "@fullcalendar/core": "^6.1.19", @@ -35,13 +38,16 @@ "@fullcalendar/list": "^6.1.19", "@fullcalendar/multimonth": "^6.1.19", "@internationalized/date": "^3.10.0", + "@mmailaender/convex-better-auth-svelte": "^0.2.0", "@sgse-app/backend": "*", "@tanstack/svelte-form": "^1.19.2", "@types/papaparse": "^5.3.14", + "better-auth": "catalog:", "convex": "catalog:", "convex-svelte": "^0.0.11", "date-fns": "^4.1.0", "emoji-picker-element": "^1.27.0", + "is-network-error": "^1.3.0", "jspdf": "^3.0.3", "jspdf-autotable": "^5.0.2", "lucide-svelte": "^0.552.0", diff --git a/apps/web/src/app.d.ts b/apps/web/src/app.d.ts index da08e6d..6633a80 100644 --- a/apps/web/src/app.d.ts +++ b/apps/web/src/app.d.ts @@ -1,13 +1,9 @@ -// See https://svelte.dev/docs/kit/types#app.d.ts -// for information about these interfaces declare global { - namespace App { - // interface Error {} - // interface Locals {} - // interface PageData {} - // interface PageState {} - // interface Platform {} - } + namespace App { + interface Locals { + token: string | undefined; + } + } } export {}; diff --git a/apps/web/src/hooks.server.ts b/apps/web/src/hooks.server.ts index de58268..08c379c 100644 --- a/apps/web/src/hooks.server.ts +++ b/apps/web/src/hooks.server.ts @@ -1,9 +1,9 @@ import type { Handle } from "@sveltejs/kit"; - -// Middleware desabilitado - proteção de rotas feita no lado do cliente -// para compatibilidade com localStorage do authStore +import { createAuth } from "@sgse-app/backend/convex/auth"; +import { getToken } from "@mmailaender/convex-better-auth-svelte/sveltekit"; export const handle: Handle = async ({ event, resolve }) => { + event.locals.token = await getToken(createAuth, event.cookies); + return resolve(event); }; - diff --git a/apps/web/src/lib/auth.ts b/apps/web/src/lib/auth.ts index 6de9cf0..7881eb4 100644 --- a/apps/web/src/lib/auth.ts +++ b/apps/web/src/lib/auth.ts @@ -1,7 +1,13 @@ -import { createAuthClient } from "better-auth/client"; +/** + * Cliente Better Auth para frontend SvelteKit + * + * Configurado para trabalhar com Convex via plugin convexClient. + * Este cliente será usado para autenticação quando Better Auth estiver ativo. + */ + +import { createAuthClient } from "better-auth/svelte"; import { convexClient } from "@convex-dev/better-auth/client/plugins"; export const authClient = createAuthClient({ - baseURL: "http://localhost:5173", plugins: [convexClient()], }); diff --git a/apps/web/src/lib/components/ActionGuard.svelte b/apps/web/src/lib/components/ActionGuard.svelte index d88ca22..a616643 100644 --- a/apps/web/src/lib/components/ActionGuard.svelte +++ b/apps/web/src/lib/components/ActionGuard.svelte @@ -2,9 +2,8 @@ import { useQuery } from "convex-svelte"; import { api } from "@sgse-app/backend/convex/_generated/api"; import type { Id } from "@sgse-app/backend/convex/_generated/dataModel"; - import { authStore } from "$lib/stores/auth.svelte"; import { loginModalStore } from "$lib/stores/loginModal.svelte"; - import { AlertTriangle } from "lucide-svelte"; + import { TriangleAlert } from "lucide-svelte"; interface Props { recurso: string; @@ -17,18 +16,21 @@ let verificando = $state(true); let permitido = $state(false); + // Usuário atual + const currentUser = useQuery(api.auth.getCurrentUser, {}); + const permissaoQuery = $derived( - authStore.usuario + currentUser?.data ? useQuery(api.permissoesAcoes.verificarAcao, { - usuarioId: authStore.usuario._id as Id<"usuarios">, + usuarioId: currentUser.data._id as Id<"usuarios">, recurso, acao, }) - : null + : null, ); $effect(() => { - if (!authStore.autenticado) { + if (!currentUser?.data) { verificando = false; permitido = false; const currentPath = window.location.pathname; @@ -60,7 +62,7 @@
diff --git a/apps/web/src/lib/components/AprovarAusencias.svelte b/apps/web/src/lib/components/AprovarAusencias.svelte index 68f5b53..49b6072 100644 --- a/apps/web/src/lib/components/AprovarAusencias.svelte +++ b/apps/web/src/lib/components/AprovarAusencias.svelte @@ -35,7 +35,7 @@ } const totalDias = $derived( - calcularDias(solicitacao.dataInicio, solicitacao.dataFim) + calcularDias(solicitacao.dataInicio, solicitacao.dataFim), ); async function aprovar() { @@ -52,10 +52,15 @@ if (onSucesso) onSucesso(); } catch (e) { const mensagemErro = e instanceof Error ? e.message : String(e); - + // Verificar se é erro de permissão - if (mensagemErro.includes("permissão") || mensagemErro.includes("permission") || mensagemErro.includes("Você não tem permissão")) { - mensagemErroModal = "Você não tem permissão para aprovar esta solicitação de ausência. Apenas o gestor responsável pelo time do funcionário pode realizar esta ação."; + if ( + mensagemErro.includes("permissão") || + mensagemErro.includes("permission") || + mensagemErro.includes("Você não tem permissão") + ) { + mensagemErroModal = + "Você não tem permissão para aprovar esta solicitação de ausência. Apenas o gestor responsável pelo time do funcionário pode realizar esta ação."; mostrarModalErro = true; } else { erro = mensagemErro; @@ -85,10 +90,15 @@ if (onSucesso) onSucesso(); } catch (e) { const mensagemErro = e instanceof Error ? e.message : String(e); - + // Verificar se é erro de permissão - if (mensagemErro.includes("permissão") || mensagemErro.includes("permission") || mensagemErro.includes("Você não tem permissão")) { - mensagemErroModal = "Você não tem permissão para reprovar esta solicitação de ausência. Apenas o gestor responsável pelo time do funcionário pode realizar esta ação."; + if ( + mensagemErro.includes("permissão") || + mensagemErro.includes("permission") || + mensagemErro.includes("Você não tem permissão") + ) { + mensagemErroModal = + "Você não tem permissão para reprovar esta solicitação de ausência. Apenas o gestor responsável pelo time do funcionário pode realizar esta ação."; mostrarModalErro = true; } else { erro = mensagemErro; @@ -125,7 +135,9 @@
Analise a solicitação e tome uma decisão
Nome
-{solicitacao.funcionario?.nome || "N/A"}
++ {solicitacao.funcionario?.nome || "N/A"} +
Time