From be959bb34b14063981ceab795c1e08b662e5643c Mon Sep 17 00:00:00 2001 From: Erwin Fiten Date: Thu, 18 Jun 2026 10:04:24 +0200 Subject: [PATCH] fix(ci): freshen all observation timestamps in e2e fixture, not just zeroed ones MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit freshen-fixture.sh shifted nodes/transmissions/observers/neighbor_edges timestamps to ~now, but for observations.timestamp it only rewrote rows where timestamp = 0 OR IS NULL. Real-timestamped observations stayed frozen at capture time, so once the committed fixture aged past a query's window they fell out of it. Per-node reach (/api/nodes/{pk}/reach?days=N, node_reach.go scanReachRows) filters `observations.timestamp >= sinceEpoch`. ~30 days after the fixture was captured the newest observation (verified: 31 days old) dropped out of the 30-day window, so reach returned no links and test-issue-1630-reach-mobile-e2e.js failed in pickRepeaterWithReach ("no repeater with reach links found") — a CI failure unrelated to any code change, tracking only the wall clock. Shift all non-zero observation timestamps forward by the same offset (preserving order), mirroring the other tables; the uncorrelated MAX subquery is evaluated once on the pre-update state. Verified on test-fixtures/e2e-fixture.db: newest observation goes 31d → 0d old, all 500 land within the 30-day window. Co-Authored-By: Claude Opus 4.8 (1M context) --- tools/freshen-fixture.sh | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tools/freshen-fixture.sh b/tools/freshen-fixture.sh index 5c1dcc215..c0574be34 100755 --- a/tools/freshen-fixture.sh +++ b/tools/freshen-fixture.sh @@ -23,7 +23,18 @@ UPDATE transmissions SET first_seen = strftime('%Y-%m-%dT%H:%M:%SZ', first_seen, (SELECT printf('+%d seconds', CAST((julianday('now') - julianday(MAX(first_seen))) * 86400 AS INTEGER)) FROM transmissions) ) WHERE first_seen IS NOT NULL; --- Sync observations.timestamp (Unix seconds) to match their transmission's freshened first_seen. +-- Shift all real (non-zero) observation timestamps (Unix seconds) forward so the +-- newest is ~now, preserving relative ordering — same approach as the columns +-- above. Per-node reach (/api/nodes/{pk}/reach?days=N) filters on +-- observations.timestamp >= sinceEpoch, so without this the fixture's observations +-- age out of the window ~N days after capture and reach returns no links (the +-- #1630 reach-mobile e2e then can't find a repeater with reach and fails). The +-- subquery is uncorrelated, so SQLite evaluates MAX once on the pre-update state. +UPDATE observations SET timestamp = timestamp + + (SELECT CAST(strftime('%s', 'now') AS INTEGER) - MAX(timestamp) FROM observations WHERE timestamp > 0) +WHERE timestamp > 0; + +-- Sync observations.timestamp to match their transmission's freshened first_seen. -- Observations with timestamp=0 break the SQL since-filter in buildTransmissionWhere. UPDATE observations SET timestamp = CAST(strftime('%s', (SELECT first_seen FROM transmissions WHERE id = transmission_id)