diff --git a/db.js b/db.js index c304804a..f5c0d3e1 100644 --- a/db.js +++ b/db.js @@ -106,6 +106,7 @@ db.exec(` CREATE INDEX IF NOT EXISTS idx_observations_transmission_id ON observations(transmission_id); CREATE INDEX IF NOT EXISTS idx_observations_observer_id ON observations(observer_id); CREATE INDEX IF NOT EXISTS idx_observations_timestamp ON observations(timestamp); + CREATE UNIQUE INDEX IF NOT EXISTS idx_observations_dedup ON observations(hash, observer_id, path_json); `); // --- Migrations for existing DBs --- @@ -186,7 +187,7 @@ const stmts = { `), updateTransmissionFirstSeen: db.prepare(`UPDATE transmissions SET first_seen = @first_seen WHERE id = @id`), insertObservation: db.prepare(` - INSERT INTO observations (transmission_id, hash, observer_id, observer_name, direction, snr, rssi, score, path_json, timestamp) + INSERT OR IGNORE INTO observations (transmission_id, hash, observer_id, observer_name, direction, snr, rssi, score, path_json, timestamp) VALUES (@transmission_id, @hash, @observer_id, @observer_name, @direction, @snr, @rssi, @score, @path_json, @timestamp) `), }; diff --git a/packet-store.js b/packet-store.js index bb8e0462..4cb08383 100644 --- a/packet-store.js +++ b/packet-store.js @@ -214,6 +214,10 @@ class PacketStore { decoded_json: pkt.decoded_json, route_type: pkt.route_type, }; + // Dedup: skip if same observer + same path already recorded for this transmission + const isDupe = tx.observations.some(o => o.observer_id === obs.observer_id && o.path_json === obs.path_json); + if (isDupe) return tx; + tx.observations.push(obs); tx.observation_count++;