Add tracker/company reverse lookup, methodology page, sitemap and social metadata - #16
Add tracker/company reverse lookup, methodology page, sitemap and social metadata#16kasnder wants to merge 3 commits into
Conversation
|
CI was red on the Pushed a lockfile-only fix in a separate commit (671e791):
Both are patch bumps inside the existing semver ranges ( It is a separate commit so it can be dropped cleanly if Dependabot is already handling these, or if you would rather keep dependency changes out of a feature PR. Generated by Claude Code |
…ial metadata The site could only answer "what is in this app?". Reporters and researchers normally arrive with the opposite question, and with a need to check how a number was produced before quoting it. Reverse lookup: lib/reverseIndex.js builds an inverted tracker -> apps and company -> apps index from the stored analyses, cached and rebuilt on the same signature as the aggregate site data so requests do no extra work. New pages /trackers, /companies, /tracker/:slug and /company/:slug list every tracker and company with the apps they were found in, most reviewed first and paginated. App reports and the statistics tables now link into them. Methodology: /methodology documents the sample (free UK App Store apps, queued on demand and ordered by popularity, so not a random sample), how detection works and what a detection does and does not mean, the jurisdiction classification rules, counting rules, limitations and citation guidance. Discoverability: canonical links, Open Graph and Twitter card metadata per page, with the app icon as the card image on reports; /sitemap.xml re-enabled and extended to the lookup and reference pages with real lastmod timestamps; /robots.txt points at it. SITE_URL pins the public origin behind a TLS proxy. Also memoises jurisdiction.resolveTrackerName, whose substring scan over the company database now runs once per distinct tracker name instead of once per app occurrence. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011VVgEEw2J1LensebivHrwW
CI runs `npm audit` as a hard gate. Two advisories published since main last ran CI now fail it on any branch, including this one, whose dependency files are otherwise identical to main: - body-parser <1.20.6 (GHSA-v422-hmwv-36x6), reachable here because the app configures body size limits from environment variables - brace-expansion 3.0.0-5.0.8 (GHSA-3jxr-9vmj-r5cp and two related), transitive Both are patch bumps within the existing semver ranges (express depends on body-parser ~1.20.5), so package.json is unchanged. `npm audit` reports no vulnerabilities afterwards and the full suite still passes, including the body limit tests that exercise the affected body-parser behaviour. Kept as a separate commit so it can be dropped if these are handled elsewhere. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011VVgEEw2J1LensebivHrwW
671e791 to
104811d
Compare
Makes the site usable by journalists and researchers, who arrive with the opposite question to the one the site answered ("which apps contain this tracker?", not "what is in this app?") and who need to check how a number was produced before quoting it.
Reverse lookup
lib/reverseIndex.jsbuilds an inverted index — tracker → apps and company → apps — from the stored analyses. It is normalised (app metadata stored once, referenced by bundle ID), cached underCACHE_DIRin its own entry, and rebuilt on the same database signature as the aggregate site data, so requests do no extra work and the homepage cache stays small.New pages:
/trackersand/companies— directories of everything seen in an analysed app, with a client-side filter (public/js/filter.js, external file so it passes the existing CSP)./tracker/:slugand/company/:slug— the apps a tracker or company was found in, most reviewed first, 50 per page.Slugs are derived from names, deduplicated deterministically so a collision (
Mob.comvsMob com) resolves the same way on every rebuild. Lookups use own-property checks, so/tracker/__proto__404s rather than reaching an inherited property.App reports and the statistics tables now link into these pages, so a reader can go from an app to a tracker to every other app carrying it.
Apple system APIs the analyser reports (
AdID access,Get device information) are labelled as system APIs rather than being listed as unattributed trackers;jurisdiction.isSystemSignatureis exported for that.Methodology page
/methodologydocuments what a figure on this site means:Linked from the nav and from
/about.Discoverability
/sitemap.xmlre-enabled (was commented out) and extended to lookup and reference pages, with reallastmodtimestamps instead of "now" for every URL./robots.txtpointing at the sitemap.SITE_URLpins the public origin so these URLs arehttps://behind a TLS-terminating proxy; it falls back to the request otherwise.Incidental
jurisdiction.resolveTrackerNameis memoised. Its substring scan over the company database now runs once per distinct tracker name instead of once per app occurrence, which is what makes building the index over the whole corpus cheap.Testing
npm test— 57 tests pass (was 35).test/reverseIndex.test.js: counting and denominators, ordering by popularity, company grouping, system-signature flagging, slug collisions, rejection of invalid and inherited-property slugs, JSON cache round-trip, pagination clamping.test/lookupPages.test.js: boots the server against a stubbed database and asserts the new pages render, unknown slugs 404, trackers link from app reports and statistics, and the sitemap, robots.txt and social metadata contain what they should.Both suites run without a database. Rendered output was also checked by hand for markup and spacing.
Notes for review
/statisticson a cold cache builds both the site data and the reverse index, so it reads all apps twice once. Both are cached afterwards. Say the word if you would rather they share one read.Generated by Claude Code