Skip to content

feat(stats): track ROM downloads and add an admin statistics tab - #4087

Open
bikeborb wants to merge 3 commits into
rommapp:masterfrom
bikeborb:feat/download-statistics
Open

feat(stats): track ROM downloads and add an admin statistics tab#4087
bikeborb wants to merge 3 commits into
rommapp:masterfrom
bikeborb:feat/download-statistics

Conversation

@bikeborb

@bikeborb bikeborb commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Adds a download_events audit log plus denormalized per-ROM counters, so an operator can see what is actually being downloaded and identify content nobody uses.

  • New download_events table: user, ROM, platform, source, kind, byte count, client IP and user agent, with name snapshots so a row survives the deletions it exists to inform.
  • roms.download_count / roms.last_downloaded_at, incremented in SQL so concurrent downloads of the same ROM cannot lose an increment.
  • Recording hooks on the single-ROM, single-file and bulk-zip download endpoints. Inline media (soundtracks, manuals) is excluded, so opening a game page does not inflate its count.
  • HybridAuthBackend records how a request authenticated, which is what distinguishes a WebUI download from an API client.
  • Admin-gated /api/stats/downloads endpoints and a Downloads tab in the existing Administration page.
  • Optional retention via DOWNLOAD_EVENTS_RETENTION_DAYS, off by default.

Recording is best-effort and never fails a download.

Description
Explain the changes or enhancements you are proposing with this pull request.

Checklist
Please check all that apply.

  • I've tested the changes locally
  • I've updated relevant comments
  • I've assigned reviewers for this PR
  • I've added unit tests that cover the changes

Screenshots (if applicable)

image image

Adds a `download_events` audit log plus denormalized per-ROM counters, so
an operator can see what is actually being downloaded and identify content
nobody uses.

- New `download_events` table: user, ROM, platform, source, kind, byte count,
  client IP and user agent, with name snapshots so a row survives the
  deletions it exists to inform.
- `roms.download_count` / `roms.last_downloaded_at`, incremented in SQL so
  concurrent downloads of the same ROM cannot lose an increment.
- Recording hooks on the single-ROM, single-file and bulk-zip download
  endpoints. Inline media (soundtracks, manuals) is excluded, so opening a
  game page does not inflate its count.
- `HybridAuthBackend` records how a request authenticated, which is what
  distinguishes a WebUI download from an API client.
- Admin-gated `/api/stats/downloads` endpoints and a Downloads tab in the
  existing Administration page.
- Optional retention via `DOWNLOAD_EVENTS_RETENTION_DAYS`, off by default.

Recording is best-effort and never fails a download.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@bikeborb

bikeborb commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

Following the feedback that this diff is too large, and after re-reading
CONTRIBUTING.md, I've filed #4089 to discuss the feature first and split
the work into two reviewable halves:

  • Backend: 23 files, the event table, migration, API and tests
  • Frontend: 57 files, but 48 of those are locale key copies and generated
    API types; the hand-written UI is 9 files

I'll open those once there's a steer on #4089, so please don't spend
review time on this PR. Happy to close it now or leave it as context.

B0rb-0G and others added 2 commits August 3, 2026 14:07
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@gantoine
gantoine self-requested a review August 4, 2026 01:19
@gantoine gantoine added the on-hold Pending further research or blocked by another issue label Aug 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

on-hold Pending further research or blocked by another issue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants