From d4b2532c9ac78ffb747db33686b78e663eed5a94 Mon Sep 17 00:00:00 2001 From: ScreenTinker Date: Tue, 30 Jun 2026 21:57:55 -0500 Subject: [PATCH] fix(#146) P1.1: resolveIdentity short-circuits on device_id (zero-lookup hot path) resolveIdentity runs on every register (block + flap gates). It already returned on device_id before any DB access; memoized the device_fingerprints statement (prepared once, lazily) and documented the invariant. Test asserts a device_id-present resolve prepares/runs ZERO device_fingerprints queries; a device_id-absent resolve does. Co-Authored-By: Claude Opus 4.8 (1M context) --- server/lib/device-identity.js | 15 ++++++++- server/test/identity-resolver.test.js | 45 +++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 server/test/identity-resolver.test.js diff --git a/server/lib/device-identity.js b/server/lib/device-identity.js index 5726200..7d059a8 100644 --- a/server/lib/device-identity.js +++ b/server/lib/device-identity.js @@ -19,9 +19,21 @@ const { db } = require('../db/database'); const ANON_KEY = 'anon:global'; +// Memoized statement — prepared once, lazily (safe on a partially-migrated DB). +let _fpStmt = null; +function fpStmt() { + if (!_fpStmt) { try { _fpStmt = db.prepare('SELECT device_id FROM device_fingerprints WHERE fingerprint = ?'); } catch (_) { return null; } } + return _fpStmt; +} + // Returns { key, kind, deviceId } — `key` is stable for keying; `deviceId` is the // resolved device id when the chain produced one (device_id directly or via // fingerprint), else null. +// +// #146 P1: SHORT-CIRCUITS on device_id — the common case (a device that sends its +// device_id) returns immediately with ZERO DB lookups. The device_fingerprints SELECT +// runs ONLY when device_id is absent. Called on every register (block + flap gates), so +// the hot path must stay lookup-free. function resolveIdentity(payload = {}) { const { device_id, fingerprint, device_token } = payload; @@ -30,7 +42,8 @@ function resolveIdentity(payload = {}) { if (fingerprint) { let mapped = null; try { - const row = db.prepare('SELECT device_id FROM device_fingerprints WHERE fingerprint = ?').get(fingerprint); + const st = fpStmt(); + const row = st && st.get(fingerprint); mapped = row && row.device_id ? row.device_id : null; } catch (_) { /* table may not exist on a partially-migrated DB */ } if (mapped) return { key: 'd:' + mapped, kind: 'fingerprint->device_id', deviceId: mapped }; diff --git a/server/test/identity-resolver.test.js b/server/test/identity-resolver.test.js new file mode 100644 index 0000000..b4cc93d --- /dev/null +++ b/server/test/identity-resolver.test.js @@ -0,0 +1,45 @@ +'use strict'; + +// #146 P1.1 — resolveIdentity() runs on EVERY register. It must SHORT-CIRCUIT on +// device_id (the common case) and query device_fingerprints ONLY when device_id is +// absent — zero extra DB lookups for a device that sends its id. + +const os = require('node:os'); +const path = require('node:path'); +const crypto = require('node:crypto'); +process.env.DATA_DIR = path.join(os.tmpdir(), 'st-ident-' + crypto.randomBytes(4).toString('hex')); + +const { test } = require('node:test'); +const assert = require('node:assert/strict'); +const { db } = require('../db/database'); +const { resolveIdentity } = require('../lib/device-identity'); + +// Spy on db.prepare to record whether the device_fingerprints query is ever prepared/run. +function withPrepareSpy(fn) { + const real = db.prepare.bind(db); + const prepared = []; + db.prepare = (sql) => { prepared.push(sql); return real(sql); }; + try { fn(); } finally { db.prepare = real; } + return prepared; +} + +test('a device_id-present resolve does ZERO fingerprint lookups', () => { + // warm the memoized statement first so a lazy prepare doesn't confuse the spy + resolveIdentity({ fingerprint: 'warm' }); + const prepared = withPrepareSpy(() => { + const r = resolveIdentity({ device_id: 'dev-1', fingerprint: 'fp', device_token: 'tok' }); + assert.equal(r.kind, 'device_id'); + assert.equal(r.deviceId, 'dev-1'); + }); + assert.equal(prepared.filter((s) => /device_fingerprints/.test(s)).length, 0, + 'no device_fingerprints query when device_id is present'); +}); + +test('a device_id-absent resolve DOES query device_fingerprints (only then)', () => { + db.pragma('foreign_keys = OFF'); + db.prepare("INSERT OR REPLACE INTO device_fingerprints (fingerprint, device_id) VALUES ('fp-x', 'dev-x')").run(); + db.pragma('foreign_keys = ON'); + const r = resolveIdentity({ fingerprint: 'fp-x' }); + assert.equal(r.kind, 'fingerprint->device_id'); + assert.equal(r.deviceId, 'dev-x'); +});