diff --git a/GEMINI.md b/GEMINI.md index 5a9e4d3..44940b4 100644 --- a/GEMINI.md +++ b/GEMINI.md @@ -26,3 +26,4 @@ 4. **Upload de Arquivos:** Proibido o uso de Base64 para envio de novos arquivos ao servidor. Use obrigatoriamente `FormData` e envie o objeto `File/Blob` para as rotas de API que integram com o MinIO. 5. **Build & Deploy Stability:** O pipeline de deploy deve obrigatoriamente utilizar `runs-on: self-hosted` e compilar apenas a plataforma `linux/arm64` (sem emulação QEMU). A atualização da stack em produção deve ser automatizada via container transiente do Watchtower. 6. **Express Compatibility**: Avoid using raw `/*` wildcards in Express 5 routes; use Regex paths (`/^\/route\/(.+)$/`) for compatibility with `path-to-regexp` v8. +7. **Frontend Independence**: NEVER import files from `services/` or `server.js` directly into React components to prevent Node.js/SDK leakage (causes White Screen). Use `helpers.ts` for UI logic. diff --git a/MEMORY.md b/MEMORY.md index 529c381..6fb05bf 100644 --- a/MEMORY.md +++ b/MEMORY.md @@ -11,6 +11,7 @@ - [x] Correção do Crash 404 no Portal: Injeção da pasta `src/services` no container de produção para permitir o import do `storage.js`. - [x] Correção das Imagens de Prova: Normalização das URLs nas questões de avaliações (Portal e Manager). - [x] Estabilização de CI/CD: Transição para `runs-on: self-hosted` (ARM64 nativo) eliminando lentidão e crashes do QEMU. +- [x] Fix Tela Branca (Portal): Refatoração de `normalizePhotoUrl` para `helpers.ts` isolado, evitando vazamento de SDK de Backend no Navegador. - [ ] Próximo Passo: Verificar se o Watchtower sincronizou as imagens corretamente na produção. ### 💳 Módulo Financeiro (Portal do Aluno) diff --git a/portal/src/components/Header.tsx b/portal/src/components/Header.tsx index c9f64a6..1d94d0a 100644 --- a/portal/src/components/Header.tsx +++ b/portal/src/components/Header.tsx @@ -3,7 +3,7 @@ import { useTheme } from '../context/ThemeContext'; import { Moon, Sun } from 'lucide-react'; import { useLocation } from 'react-router-dom'; import Notifications from './Notifications'; -import { normalizePhotoUrl } from '../services/storage'; +import { normalizePhotoUrl } from '../helpers'; const pageTitles: Record = { '/': 'Dashboard', diff --git a/portal/src/components/Sidebar.tsx b/portal/src/components/Sidebar.tsx index 17d39db..0162ee6 100644 --- a/portal/src/components/Sidebar.tsx +++ b/portal/src/components/Sidebar.tsx @@ -5,7 +5,7 @@ import { FileText, Award, User, LogOut, GraduationCap, X, Menu, ClipboardList } from 'lucide-react'; import { useState, useEffect } from 'react'; -import { normalizePhotoUrl } from '../services/storage'; +import { normalizePhotoUrl } from '../helpers'; const navItems = [ { path: '/', label: 'Dashboard', icon: LayoutDashboard }, diff --git a/portal/src/helpers.ts b/portal/src/helpers.ts new file mode 100644 index 0000000..0e68fa3 --- /dev/null +++ b/portal/src/helpers.ts @@ -0,0 +1,15 @@ +/** + * Helpers compartihados de UI + */ +export function normalizePhotoUrl(url) { + if (!url || typeof url !== 'string') return ''; + if (url.startsWith('data:image')) return url; + if (url.startsWith('/storage/')) return url; + + try { + const match = url.match(/^https?:\/\/[^\/]+\/(.+)$/); + if (match) return `/storage/${match[1]}`; + } catch(e) {} + + return url; +} diff --git a/portal/src/pages/Avaliacoes.tsx b/portal/src/pages/Avaliacoes.tsx index cfb9209..dd407c6 100644 --- a/portal/src/pages/Avaliacoes.tsx +++ b/portal/src/pages/Avaliacoes.tsx @@ -5,7 +5,7 @@ import { ClipboardList, Clock, ChevronLeft, ChevronRight, Send, CheckCircle2, XCircle, Award, AlertTriangle, Timer, ArrowLeft } from 'lucide-react'; -import { normalizePhotoUrl } from '../services/storage'; +import { normalizePhotoUrl } from '../helpers'; // ========================================== // Exam Environment — Portal do Aluno