chore(mobile): add /api/dbg diagnostics sink + client reporter (build, overflow, viewport, scroll)

Temporary: the app POSTs its real runtime state to the server log so device-only bugs (budge source,
keyboard viewport numbers, chat-open scroll state) can be diagnosed from docker logs instead of
screenshots. Removed once mobile issues settle.
Build marker -> 2026-07-18-batch108.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-18 13:18:58 +05:30
parent 720b1f0c40
commit f9d6472f77
2 changed files with 36 additions and 1 deletions
+29 -1
View File
@@ -1112,7 +1112,7 @@
</head>
<body>
<script src="/icons.js?v=6"></script>
<script>window.__BUILD='2026-07-18-batch107';console.log('%cBiz Connect','color:#1F3B73;font-weight:bold','build '+window.__BUILD);
<script>window.__BUILD='2026-07-18-batch108';console.log('%cBiz Connect','color:#1F3B73;font-weight:bold','build '+window.__BUILD);
// Emoji are rendered with the OS's own (colour) emoji font — instant, zero network.
//
// We used to run Twemoji over every emoji, which swapped each one for an <img> pulled INDIVIDUALLY from
@@ -1145,6 +1145,33 @@ function twemojify(_el){ /* native emoji: nothing to do */ }</script>
}
}catch(_){} })();
</script>
<script>
// TEMP diagnostics → server log (/api/dbg): reports the app's REAL runtime state so mobile-only bugs can
// be diagnosed from `docker logs` instead of screenshots. Remove once the mobile issues are settled.
(function(){
function findOverflow(){
try{ var dw=document.documentElement.clientWidth, out=[], els=document.querySelectorAll('body *');
for(var i=0;i<els.length;i++){ var el=els[i]; var rct=el.getBoundingClientRect();
if(rct.width>0 && rct.right>dw+1){ out.push((el.tagName||'')+'.'+String(el.className||'').split(' ').filter(Boolean).slice(0,2).join('.')+' r='+Math.round(rct.right)+' w='+Math.round(rct.width)); if(out.length>=12) break; } }
return out;
}catch(e){ return ['err:'+(e&&e.message)]; }
}
window.bzDbg=function(tag, extra){
try{ var vv=window.visualViewport||{};
var p={ tag:tag, build:window.__BUILD, iw:window.innerWidth, ih:window.innerHeight,
cw:document.documentElement.clientWidth, ch:document.documentElement.clientHeight,
sw:document.documentElement.scrollWidth, dpr:window.devicePixelRatio,
vvW:Math.round(vv.width||0), vvH:Math.round(vv.height||0), vvTop:Math.round(vv.offsetTop||0),
ovf:(document.documentElement.scrollWidth>document.documentElement.clientWidth+1) };
if(extra) for(var k in extra) p[k]=extra[k];
fetch('/api/dbg',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(p)}).catch(function(){});
}catch(e){}
};
window.__bzFindOverflow=findOverflow;
window.addEventListener('load', function(){ setTimeout(function(){ bzDbg('load',{overflow:findOverflow()}); }, 900); });
if(window.visualViewport){ var t; window.visualViewport.addEventListener('resize', function(){ clearTimeout(t); t=setTimeout(function(){ bzDbg('kb',{overflow:findOverflow()}); }, 300); }); }
})();
</script>
<div class="loading" id="loading"><div class="ld-inner"><img src="/loaders/loader-orbit-dark.svg" alt="" width="72" height="72"><div class="ld-wm">Biz <b>Connect</b></div><span class="ld-sub">Loading…</span></div></div>
<header>
@@ -2824,6 +2851,7 @@ async function openConvo(kind,id){
// late content (avatars, images, day separators) settles, unless we deliberately stopped at a "New
// messages" divider. This is the safety net over renderThread()'s own pin.
[0,120,320,600].forEach((d)=>setTimeout(()=>{ if(selected&&selected.kind===kind&&selected.id===id){ const b=document.getElementById('msgs'); if(b && !b.querySelector('.new-sep')) b.scrollTop=b.scrollHeight; } }, d));
setTimeout(()=>{ try{ const b=document.getElementById('msgs'); if(b && window.bzDbg) bzDbg('convoOpen',{count:THREAD.length, scrollTop:Math.round(b.scrollTop), scrollH:Math.round(b.scrollHeight), clientH:Math.round(b.clientHeight), atBottom:(b.scrollHeight-b.scrollTop-b.clientHeight)<8, newsep:!!b.querySelector('.new-sep'), vis:b.style.visibility||'visible'}); }catch(_){} }, 700);
}
// ---------- @mentions (group chat) ----------
let mentionItems=[], mentionIdx=0, mentionStart=-1;
+7
View File
@@ -1004,6 +1004,13 @@ try {
} catch (_) {}
route('GET', '/api/build', (req, res) => json(res, 200, { build: APP_BUILD }));
// TEMP mobile debug sink: the app POSTs its real runtime state here so we can diagnose device-only issues
// from the server log (docker logs bizgaze-support) without screenshots. Remove once mobile bugs settle.
route('POST', '/api/dbg', async (req, res) => {
try { const b = await readBody(req); console.log('[MDBG]', JSON.stringify(b)); } catch (_) {}
json(res, 200, { ok: true });
});
// Mint a LiveKit join token for the signed-in user + a specific room (the 6-digit meeting code).
// The room-membership/host authorization already happens over the meeting WebSocket; this only
// hands the client a media-plane credential scoped to that room and its own identity.