From 9f324289800846a666f37b52a49d2a6a1a732173 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?PontualTech=20/=20Karl=C3=A3o?= Date: Wed, 29 Apr 2026 08:01:30 -0300 Subject: [PATCH] feat(ble): envia diag log direto pro servidor (evita crash WebView) v1.10.9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Karlão reportou que app reinicia ao tentar copiar log (crash em v1.10.8 também — modal grande + textarea com Unicode pode crashar WebView Android skinned). Solução: novo endpoint POST /api/bms/diag-log que aceita texto do log + auth user, salva em /data/diag-logs/{userId}-{ts}.txt no servidor. Frontend tem botão '📤 Enviar pro servidor' (verde) que faz fetch POST. Resposta confirma recebimento. Eu (Claude) leio o arquivo direto do servidor — sem dependência de clipboard, share, modal HTML, ou copy manual. Co-Authored-By: Claude Opus 4.7 (1M context) --- app/diario-bordo.html | 24 +++++++++++++++++++----- mobile/android/app/build.gradle | 4 ++-- mobile/package.json | 2 +- server/public/index.html | 24 +++++++++++++++++++----- server/src/index.js | 19 ++++++++++++++++++- 5 files changed, 59 insertions(+), 14 deletions(-) diff --git a/app/diario-bordo.html b/app/diario-bordo.html index 5833c85..6c75450 100644 --- a/app/diario-bordo.html +++ b/app/diario-bordo.html @@ -1979,9 +1979,9 @@ Marque zonas de proibição (alarme alto) ou atenção (aviso suave). Detecção
📋 Diagnóstico (logs do pareamento) -
- - +
+ +
@@ -5794,8 +5794,22 @@ async function ensureBleNativeReady(){ _bleNativeInitialized=true; } +// Envia log diagnóstico direto pro servidor (evita crash de clipboard/share em WebView) +async function sendDiagLogToServer(){ + const el=document.getElementById('bt-diag'); + if(!el){toast('Log vazio');return} + const txt=`Shivao v${APP_VERSION} · log diagnóstico\n\n`+(el.innerText||el.textContent||'').trim(); + if(!cloudConfigured()){toast('Faça login primeiro pra enviar log');return} + toast('📤 Enviando log pro servidor...'); + try{ + const r=await cloudFetch('/api/bms/diag-log',{method:'POST',body:JSON.stringify({log:txt})}); + const j=await r.json(); + if(j.ok)toast('✓ Log enviado · '+(j.file||'OK')); + else throw new Error(j.error||'falhou'); + }catch(e){toast('Erro: '+e.message)} +} + // Mostra log num modal pro usuário copiar/compartilhar manualmente -// (navigator.clipboard crasha em alguns WebViews Capacitor / Samsung One UI) function copyDiagLog(){ const el=document.getElementById('bt-diag'); if(!el){toast('Log vazio');return} @@ -6329,7 +6343,7 @@ async function removeBluetoothDevice(id){ renderBluetoothCard(); } -const APP_VERSION='1.10.8'; +const APP_VERSION='1.10.9'; function renderBluetoothCard(){ const el=document.getElementById('bt-list'); const supportEl=document.getElementById('bt-support'); diff --git a/mobile/android/app/build.gradle b/mobile/android/app/build.gradle index 9c56606..369f379 100644 --- a/mobile/android/app/build.gradle +++ b/mobile/android/app/build.gradle @@ -7,8 +7,8 @@ android { applicationId "br.com.pontualtech.shivao" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion - versionCode 24 - versionName "1.10.8" + versionCode 25 + versionName "1.10.9" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" aaptOptions { // Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps. diff --git a/mobile/package.json b/mobile/package.json index 40c67ae..8be079e 100644 --- a/mobile/package.json +++ b/mobile/package.json @@ -1,6 +1,6 @@ { "name": "shivao-mobile", - "version": "1.10.8", + "version": "1.10.9", "description": "Shivao app nativo (Capacitor wrapper Android/iOS)", "main": "index.js", "type": "module", diff --git a/server/public/index.html b/server/public/index.html index 5833c85..6c75450 100644 --- a/server/public/index.html +++ b/server/public/index.html @@ -1979,9 +1979,9 @@ Marque zonas de proibição (alarme alto) ou atenção (aviso suave). Detecção
📋 Diagnóstico (logs do pareamento) -
- - +
+ +
@@ -5794,8 +5794,22 @@ async function ensureBleNativeReady(){ _bleNativeInitialized=true; } +// Envia log diagnóstico direto pro servidor (evita crash de clipboard/share em WebView) +async function sendDiagLogToServer(){ + const el=document.getElementById('bt-diag'); + if(!el){toast('Log vazio');return} + const txt=`Shivao v${APP_VERSION} · log diagnóstico\n\n`+(el.innerText||el.textContent||'').trim(); + if(!cloudConfigured()){toast('Faça login primeiro pra enviar log');return} + toast('📤 Enviando log pro servidor...'); + try{ + const r=await cloudFetch('/api/bms/diag-log',{method:'POST',body:JSON.stringify({log:txt})}); + const j=await r.json(); + if(j.ok)toast('✓ Log enviado · '+(j.file||'OK')); + else throw new Error(j.error||'falhou'); + }catch(e){toast('Erro: '+e.message)} +} + // Mostra log num modal pro usuário copiar/compartilhar manualmente -// (navigator.clipboard crasha em alguns WebViews Capacitor / Samsung One UI) function copyDiagLog(){ const el=document.getElementById('bt-diag'); if(!el){toast('Log vazio');return} @@ -6329,7 +6343,7 @@ async function removeBluetoothDevice(id){ renderBluetoothCard(); } -const APP_VERSION='1.10.8'; +const APP_VERSION='1.10.9'; function renderBluetoothCard(){ const el=document.getElementById('bt-list'); const supportEl=document.getElementById('bt-support'); diff --git a/server/src/index.js b/server/src/index.js index 3d923d5..ce885aa 100644 --- a/server/src/index.js +++ b/server/src/index.js @@ -126,6 +126,23 @@ app.get('/api/auth/me', requireAuth, (req, res) => { res.json(req.user); }); +// Diagnostic log endpoint — recebe log do BLE pra debugar +app.post('/api/bms/diag-log', requireAuth, (req, res) => { + const { log } = req.body || {}; + if (!log || typeof log !== 'string') return res.status(400).json({ error: 'log string required' }); + const dir = path.join(db.dataDir, 'diag-logs'); + try { fs.mkdirSync(dir, { recursive: true }); } catch {} + const ts = new Date().toISOString().replace(/[:.]/g, '-'); + const file = path.join(dir, `${req.user.id}-${ts}.txt`); + try { + fs.writeFileSync(file, log.slice(0, 50000)); // cap em 50KB + db.audit(req.user.id, 'bms_diag_log', 'bluetooth', null, { bytes: log.length, file: path.basename(file) }, req.ip); + res.json({ ok: true, file: path.basename(file) }); + } catch (e) { + res.status(500).json({ error: e.message }); + } +}); + // ===== Google Login via OAuth redirect (pra apps Capacitor onde GSI popup não funciona) ===== // In-memory store: session_id → { tokens, createdAt }. Auto-expira em 10min. const pendingGoogleSessions = new Map(); @@ -347,7 +364,7 @@ app.get('/.well-known/assetlinks.json', (req, res) => { }); // Atalho: /apk redireciona pra última APK release no Forgejo -const LATEST_APK_URL = 'https://git.pontualtech.work/karlao/shivao-projeto/releases/download/v1.10.8/Shivao-v1.10.8.apk'; +const LATEST_APK_URL = 'https://git.pontualtech.work/karlao/shivao-projeto/releases/download/v1.10.9/Shivao-v1.10.9.apk'; app.get('/apk', (req, res) => res.redirect(302, LATEST_APK_URL)); // Página A4 imprimível com QR Code + instruções (cola no barco/marina)