Skip to content

Refresh Exodus tracker data on a schedule instead of by hand - #20

Merged
kasnder merged 1 commit into
mainfrom
claude/exodus-trackers-json-updates-f71j4y
Aug 12, 2026
Merged

Refresh Exodus tracker data on a schedule instead of by hand#20
kasnder merged 1 commit into
mainfrom
claude/exodus-trackers-json-updates-f71j4y

Conversation

@kasnder

@kasnder kasnder commented Aug 12, 2026

Copy link
Copy Markdown
Member

exodusTrackers.json had not been refreshed since January 2025. This adds a refresh script and a monthly workflow that opens a PR when the data actually changed, and applies the pending refresh.

Why not fetch at build or boot time

The obvious alternative is to fetch the catalogue during the Railway build. That would attach a third-party network call to the highest-frequency operation in the project — main took ~70 pushes in the last four months — in service of data that changed meaningfully 8 times in 19 months. routes/index.js reads the file with readFileSync + JSON.parse at module load, so a truncated or failed fetch means the container does not boot, blocking unrelated hotfixes whenever Exodus has a bad afternoon. It would also make deploys non-reproducible and ship unreviewed third-party content straight into rendered pages.

A monthly PR gets merged and deployed within days at this cadence, so it buys the same freshness without the coupling.

Changes

  • scripts/update-exodus-trackers.js — fetches, validates and normalises the Exodus API payload, writing only when the content actually changed. Supports --check (validate, never write), --input (local file), --summary (Markdown change summary for the PR body). Exposed as npm run update-trackers.
  • .github/workflows/update-exodus-trackers.yml — runs it monthly and on demand, opening or updating a single PR when something changed. Uses gh with GITHUB_TOKEN rather than a third-party action.
  • test/updateExodusTrackers.test.js — covers field projection, sort stability, the truncation and malformed-payload guards, and change detection.
  • README.md — new "Tracker Metadata" section documenting what the file is for and how to refresh it.
  • exodusTrackers.json — the refresh itself.

Normalisation

The payload is projected down to the three fields views/form.pug reads (id, name, categories), with keys and categories sorted. Exodus returns categories in an unstable order: 93 of the 96 entries that differed against the committed copy differed only by category array ordering. Writing the raw response would open a churny PR every month with the real changes invisible inside it. As a side effect the file drops from 570 KB to 50 KB, and pretty-printing makes future diffs readable.

Data changes in this refresh

432 trackers, up from 428.

  • Added: ACRA, Backtrace, Sentry, Yueying Crash SDK
  • Renamed: Gigya → SAP CDC (Gigya)
  • Recategorised: AccountKit [][Identification], AdTiming [][Advertisement], MixPanel drops Advertisement

This is display data only — detection comes from analyser/data/ios_signatures_v3.json, so a stale file costs a link and some badges, never a missed tracker. Of the changes above only Sentry matches a name the analyser currently detects. The other 34 signature names without an Exodus entry (Facebook, Google Firebase, WeChat, __ALL_CLASSES__, …) are naming mismatches or non-Exodus concepts that no refresh will fix; an alias map would be the separate change for that.

Testing

  • node --test test/updateExodusTrackers.test.js — 5/5 pass.
  • npm test — 25 pass, 9 fail; the same 9 fail on a clean checkout in this environment (they need a live PostgreSQL).
  • Verified the refreshed file still builds the name → tracker map routes/index.js expects, including the renamed and newly added entries.
  • Verified the script is idempotent (--input on its own output reports "already up to date") and that --check never writes.

🤖 Generated with Claude Code

https://claude.ai/code/session_01TT3FoeNrXRT7A6BETh3yc1


Generated by Claude Code

exodusTrackers.json had not been refreshed since January 2025. Rather than
fetch it during the Railway build or at boot, which would make every deploy
depend on reports.exodus-privacy.eu.org being up for data that changes a
handful of times a year, refresh it on a schedule and land it as a PR.

- scripts/update-exodus-trackers.js fetches, validates and normalises the
  Exodus API payload, writing only when the content actually changed. It keeps
  just the fields views/form.pug reads (id, name, categories) and sorts keys
  and categories: Exodus returns categories in an unstable order, so writing
  the raw response produced ~90 spurious entry changes per refresh and buried
  the real ones. Also emits a Markdown change summary for the PR body.
- .github/workflows/update-exodus-trackers.yml runs it monthly and opens or
  updates a PR when something changed.
- Refreshed the data itself: adds ACRA, Backtrace, Sentry and Yueying Crash
  SDK, renames Gigya to SAP CDC (Gigya), and fixes categories for AccountKit,
  AdTiming and MixPanel. Of these only Sentry matches a name the analyser can
  currently detect. The rest of the diff is the one-time reformat, which also
  takes the file from 570 KB to 50 KB.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TT3FoeNrXRT7A6BETh3yc1
@kasnder
kasnder marked this pull request as ready for review August 12, 2026 16:57
@kasnder
kasnder merged commit c7adbd8 into main Aug 12, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants