- Removido README.md padrão do Laravel (backend) - Removidos scripts de deploy (não mais necessários) - Atualizado copilot-instructions.md para novo fluxo - Adicionada documentação de auditoria do servidor - Sincronizado código de produção com repositório Novo workflow: - Trabalhamos diretamente em /root/webmoney (symlink para /var/www/webmoney) - Mudanças PHP são instantâneas - Mudanças React requerem 'npm run build' - Commit após validação funcional
7.6 KiB
Executable File
APRENDIZADOS TÉCNICOS - WEBMONEY
Este documento registra problemas encontrados e suas soluções para referência futura.
📋 Índice
1. Bootstrap 5 + React: Componentes JS não funcionam
Data: 8 de Dezembro de 2025
Versões afetadas: v1.3.8 - v1.3.11
Componentes afetados: Dropdown, Modal
❌ Problema
Componentes do Bootstrap 5 que dependem de JavaScript (Dropdown, Modal, Tooltip, Popover, etc.) não funcionam corretamente em aplicações React, mesmo importando o Bootstrap JS.
Sintomas:
- Dropdown não abre ao clicar
- Modal não aparece
data-bs-toggle="dropdown"não faz nadawindow.bootstrap.Modalnão inicializa corretamente
🔍 Causa Raiz
O Bootstrap 5 JavaScript foi projetado para manipular o DOM diretamente, o que conflita com o Virtual DOM do React:
- Ciclo de vida: Bootstrap inicializa componentes no
DOMContentLoaded, mas React renderiza depois - Re-renders: Quando React re-renderiza, os listeners do Bootstrap são perdidos
- Referências:
new bootstrap.Modal(element)pode referenciar elementos que React já substituiu
✅ Solução
Implementar os componentes usando 100% React puro, sem depender da API JavaScript do Bootstrap.
Dropdown Controlado (React)
// ❌ ERRADO - Não funciona
<div className="dropdown">
<button data-bs-toggle="dropdown">Menu</button>
<ul className="dropdown-menu">...</ul>
</div>
// ✅ CORRETO - React controlado
const [isOpen, setIsOpen] = useState(false);
const dropdownRef = useRef(null);
// Fechar ao clicar fora
useEffect(() => {
const handleClickOutside = (e) => {
if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
setIsOpen(false);
}
};
document.addEventListener('mousedown', handleClickOutside);
return () => document.removeEventListener('mousedown', handleClickOutside);
}, []);
<div className="dropdown" ref={dropdownRef} style={{ position: 'relative' }}>
<button onClick={() => setIsOpen(!isOpen)}>Menu</button>
<ul
className={`dropdown-menu ${isOpen ? 'show' : ''}`}
style={{
position: 'absolute',
right: 0,
top: '100%',
zIndex: 1000
}}
>
...
</ul>
</div>
Modal Controlado (React)
// ❌ ERRADO - Depende de window.bootstrap
useEffect(() => {
if (window.bootstrap) {
const modal = new window.bootstrap.Modal(modalRef.current);
// Não funciona consistentemente
}
}, []);
// ✅ CORRETO - React puro
const Modal = ({ show, onHide, title, children, footer }) => {
// Fechar com ESC
useEffect(() => {
const handleKeyDown = (e) => {
if (e.key === 'Escape' && show) onHide();
};
if (show) {
document.addEventListener('keydown', handleKeyDown);
document.body.style.overflow = 'hidden'; // Bloqueia scroll
}
return () => {
document.removeEventListener('keydown', handleKeyDown);
document.body.style.overflow = '';
};
}, [show, onHide]);
if (!show) return null;
return (
<>
<div className="modal-backdrop show" style={{ backgroundColor: 'rgba(0,0,0,0.7)' }} />
<div className="modal show d-block" onClick={(e) => e.target === e.currentTarget && onHide()}>
<div className="modal-dialog modal-dialog-centered">
<div className="modal-content">
<div className="modal-header">
<h5>{title}</h5>
<button className="btn-close" onClick={onHide} />
</div>
<div className="modal-body">{children}</div>
{footer && <div className="modal-footer">{footer}</div>}
</div>
</div>
</div>
</>
);
};
📝 Regra para o Futuro
NUNCA usar
data-bs-toggle,data-bs-dismissouwindow.bootstrapem React.Sempre implementar componentes interativos com
useState,useRefeuseEffect.
🔗 Alternativas
Se precisar de muitos componentes Bootstrap interativos, considere usar:
- React-Bootstrap (https://react-bootstrap.github.io/)
- Reactstrap (https://reactstrap.github.io/)
Estas bibliotecas reimplementam os componentes Bootstrap em React puro.
2. Deploy: Arquivos no diretório errado
Data: 8 de Dezembro de 2025
Versão afetada: v1.3.10
❌ Problema
Após fazer deploy do frontend, o site retornava 404 ou 403 Forbidden.
Sintomas:
curl https://webmoney.cnxifly.com/retorna 404/403- Arquivos existem no servidor mas não são servidos
- JS/CSS não carregam
🔍 Causa Raiz
Os arquivos foram copiados para o diretório errado:
# Onde os arquivos foram copiados:
/var/www/webmoney/frontend/assets/
# Onde o Nginx esperava encontrar:
/var/www/webmoney/frontend/dist/assets/
O Nginx estava configurado com:
root /var/www/webmoney/frontend/dist;
✅ Solução
- Verificar configuração do Nginx:
cat /etc/nginx/sites-available/webmoney-subdomain
# Procurar por: root /var/www/webmoney/frontend/dist;
- Deploy para o caminho correto:
# Build do frontend
cd frontend && npm run build
# Deploy para o caminho CORRETO (inclui /dist/)
scp -r dist/* root@213.165.93.60:/var/www/webmoney/frontend/dist/
- Ajustar permissões:
chown -R www-data:www-data /var/www/webmoney/frontend/dist
📝 Regra para o Futuro
Sempre verificar o
rootdo Nginx antes de fazer deploy.O caminho de deploy deve corresponder EXATAMENTE ao configurado no Nginx.
✅ Comando de Deploy Correto
# Frontend - Build e Deploy
cd /workspaces/webmoney/frontend
npm run build
sshpass -p 'Master9354' scp -r dist/* root@213.165.93.60:/var/www/webmoney/frontend/dist/
# Backend - Deploy
sshpass -p 'Master9354' rsync -avz --exclude 'vendor' --exclude '.git' \
/workspaces/webmoney/backend/ root@213.165.93.60:/var/www/webmoney/backend/
# Pós-deploy no servidor
ssh root@213.165.93.60 "
cd /var/www/webmoney/backend
COMPOSER_ALLOW_SUPERUSER=1 composer install --no-dev --optimize-autoloader
cp .env.production .env
php artisan config:cache
php artisan route:cache
chown -R www-data:www-data /var/www/webmoney
systemctl restart php8.4-fpm
"
📊 Resumo de Problemas Frequentes
| Problema | Sintoma | Solução Rápida |
|---|---|---|
| Dropdown não abre | Clique não faz nada | Usar useState + onClick |
| Modal não aparece | window.bootstrap undefined |
Implementar modal React puro |
| 404 no frontend | Site não carrega | Verificar root do Nginx |
| 403 Forbidden | Permissão negada | chown -R www-data:www-data |
| API retorna 404 | Endpoint não encontrado | Verificar se routes/api.php foi copiado |
| Cache desatualizado | Mudanças não aparecem | php artisan config:clear + hard refresh |
🔧 Checklist de Debug
Quando algo não funciona:
-
Frontend não carrega:
- Verificar se
npm run buildfoi executado - Verificar se arquivos estão em
/frontend/dist/ - Verificar
rootdo Nginx - Fazer hard refresh (Ctrl+Shift+R)
- Verificar se
-
Componente React não funciona:
- Verificar se não está usando
data-bs-* - Verificar console do browser para erros
- Implementar com
useState/useEffect
- Verificar se não está usando
-
API retorna erro:
- Verificar se
routes/api.phpexiste no servidor - Verificar se
.envestá configurado - Executar
php artisan config:cache - Verificar logs:
tail -f /var/log/nginx/webmoney_*.log
- Verificar se
Documento atualizado em: 8 de Dezembro de 2025 - v1.3.11