fix: normalize packet hash case for deeplink lookups

This commit is contained in:
you
2026-03-21 05:50:29 +00:00
parent 9f53a059c7
commit ce190886ff
4 changed files with 12 additions and 10 deletions
+8 -6
View File
@@ -420,8 +420,9 @@ class PacketStore {
}
if (observer) results = this._transmissionsForObserver(observer, results);
if (hash) {
const tx = this.byHash.get(hash);
results = tx ? results.filter(p => p.hash === hash) : [];
const h = hash.toLowerCase();
const tx = this.byHash.get(h);
results = tx ? results.filter(p => p.hash === h) : [];
}
if (since) results = results.filter(p => p.timestamp > since);
if (until) results = results.filter(p => p.timestamp < until);
@@ -536,8 +537,9 @@ class PacketStore {
/** Get all siblings of a packet (same hash) — returns observations array */
getSiblings(hash) {
if (this.sqliteOnly) return this.db.prepare('SELECT * FROM packets WHERE hash = ? ORDER BY timestamp DESC').all(hash);
const tx = this.byHash.get(hash);
const h = hash.toLowerCase();
if (this.sqliteOnly) return this.db.prepare('SELECT * FROM packets WHERE hash = ? ORDER BY timestamp DESC').all(h);
const tx = this.byHash.get(h);
return tx ? tx.observations : [];
}
@@ -576,7 +578,7 @@ class PacketStore {
if (type !== undefined) { where.push('payload_type = ?'); params.push(Number(type)); }
if (route !== undefined) { where.push('route_type = ?'); params.push(Number(route)); }
if (observer) { where.push('observer_id = ?'); params.push(observer); }
if (hash) { where.push('hash = ?'); params.push(hash); }
if (hash) { where.push('hash = ?'); params.push(hash.toLowerCase()); }
if (since) { where.push('timestamp > ?'); params.push(since); }
if (until) { where.push('timestamp < ?'); params.push(until); }
if (region) { where.push('observer_id IN (SELECT id FROM observers WHERE iata = ?)'); params.push(region); }
@@ -593,7 +595,7 @@ class PacketStore {
if (type !== undefined) { where.push('payload_type = ?'); params.push(Number(type)); }
if (route !== undefined) { where.push('route_type = ?'); params.push(Number(route)); }
if (observer) { where.push('observer_id = ?'); params.push(observer); }
if (hash) { where.push('hash = ?'); params.push(hash); }
if (hash) { where.push('hash = ?'); params.push(hash.toLowerCase()); }
if (since) { where.push('timestamp > ?'); params.push(since); }
if (until) { where.push('timestamp < ?'); params.push(until); }
if (region) { where.push('observer_id IN (SELECT id FROM observers WHERE iata = ?)'); params.push(region); }
+1 -1
View File
@@ -89,7 +89,7 @@
<script src="nodes.js?v=1774290000" onerror="console.error('Failed to load:', this.src)"></script>
<script src="traces.js?v=1774290000" onerror="console.error('Failed to load:', this.src)"></script>
<script src="analytics.js?v=1774290000" onerror="console.error('Failed to load:', this.src)"></script>
<script src="live.js?v=1774350000" onerror="console.error('Failed to load:', this.src)"></script>
<script src="live.js?v=1774072222" onerror="console.error('Failed to load:', this.src)"></script>
<script src="observers.js?v=1774290000" onerror="console.error('Failed to load:', this.src)"></script>
<script src="observer-detail.js?v=1774028201" onerror="console.error('Failed to load:', this.src)"></script>
<script src="node-analytics.js?v=1774042199" onerror="console.error('Failed to load:', this.src)"></script>
+1 -1
View File
@@ -1822,7 +1822,7 @@
${rssi != null ? `<span>📡 ${rssi} dBm</span>` : ''}
${observer ? `<span>👁 ${escapeHtml(observer)}</span>` : ''}
</div>
${pkt.hash ? `<a class="fdc-link" href="#/packets/${pkt.hash}">View in packets →</a>` : ''}
${pkt.hash ? `<a class="fdc-link" href="#/packets/${pkt.hash.toLowerCase()}">View in packets →</a>` : ''}
<button class="fdc-replay">↻ Replay</button>
`;
card.querySelector('.fdc-close').addEventListener('click', (e) => { e.stopPropagation(); card.remove(); });
+2 -2
View File
@@ -611,7 +611,7 @@ for (const source of mqttSources) {
const fullPacket = pktStore.getById(packetId);
const tx = pktStore.byHash.get(pktData.hash);
const observation_count = tx ? tx.observation_count : 1;
const broadcastData = { id: packetId, raw: msg.raw, decoded, snr: msg.SNR, rssi: msg.RSSI, hash: msg.hash, observer: observerId, packet: fullPacket, observation_count };
const broadcastData = { id: packetId, raw: msg.raw, decoded, snr: msg.SNR, rssi: msg.RSSI, hash: pktData.hash, observer: observerId, packet: fullPacket, observation_count };
broadcast({ type: 'packet', data: broadcastData });
if (decoded.header.payloadTypeName === 'GRP_TXT') {
@@ -839,7 +839,7 @@ app.get('/api/packets/:id', (req, res) => {
let packet;
if (isHash) {
// Hash-based lookup
const tx = pktStore.byHash.get(param);
const tx = pktStore.byHash.get(param.toLowerCase());
packet = tx || null;
}
if (!packet) {