diff --git a/server/server.js b/server/server.js index fcbdbef..2c64966 100644 --- a/server/server.js +++ b/server/server.js @@ -521,6 +521,11 @@ app.get('/api/update/check', (req, res) => { const latestVersion = VERSION; const updateAvailable = currentVersion && currentVersion !== latestVersion; + // #96: log every version check so the OTA is observable - which devices check in, their + // version, and whether they'll update. This diagnosability gap is part of why the 1.9.0 + // relaunch failure went unseen. + console.log(`[ota] update check from ${getClientIp(req)}: client=${currentVersion || 'unknown'} latest=${latestVersion} update_available=${!!updateAvailable} apk=${apkExists ? 'present' : 'MISSING'}`); + res.json({ latest_version: latestVersion, current_version: currentVersion || 'unknown', @@ -638,11 +643,15 @@ function resolveApkPath() { app.get('/download/apk', (req, res) => { const apkPath = resolveApkPath(); if (apkPath) { + // #96: an APK download means a device is actually applying an OTA - log it so the + // update is observable end to end (check -> download -> [relaunch]). + console.log(`[ota] APK download by ${getClientIp(req)} (${fs.statSync(apkPath).size} bytes) - OTA update in progress`); res.setHeader('Content-Type', 'application/vnd.android.package-archive'); res.setHeader('Content-Disposition', 'attachment; filename="ScreenTinker.apk"'); res.setHeader('Cache-Control', 'no-cache'); res.sendFile(apkPath); } else { + console.warn(`[ota] APK download requested by ${getClientIp(req)} but no APK is available (404)`); res.status(404).send(`APK Not Found

APK Not Available

The Android APK has not been compiled yet. To build it from source:

cd android
./gradlew assembleDebug
cp app/build/outputs/apk/debug/app-debug.apk ../ScreenTinker.apk

See the README for full build instructions.

In Docker, mount a built APK at /data/ScreenTinker.apk (the data dir).

Alternatively, use the web player in any browser.

`); } });