Skip to content

Add authenticated developer API for public stats and streaming data - #201

Open
Zulut30 wants to merge 1 commit into
borisbabic:masterfrom
Zulut30:feat/developer-stats-api
Open

Add authenticated developer API for public stats and streaming data#201
Zulut30 wants to merge 1 commit into
borisbabic:masterfrom
Zulut30:feat/developer-stats-api

Conversation

@Zulut30

@Zulut30 Zulut30 commented Jul 22, 2026

Copy link
Copy Markdown

Summary

This adds a versioned Developer API for the public aggregate data already used by HSGuru's Meta, Archetype, Decks, and Streaming pages.

Developers can sign in with Battle.net, create a key from Profile Settings, and use the documented JSON endpoints without scraping rendered pages.

API surface

  • GET /api/v1/meta
  • GET /api/v1/archetypes
  • GET /api/v1/archetypes/:archetype
  • GET /api/v1/decks
  • GET /api/v1/streamers
  • GET /api/v1/streamers/:twitch_login/decks
  • GET /api/v1/streamer-decks
  • GET /api/v1/streams/live

The endpoints support the corresponding public filters, including format, period, rank, opponent class, coin state, minimum sample sizes, card inclusion/exclusion, streamer rank and activity filters, sorting, and bounded pagination.

Authentication and safety

  • API keys are created, rotated, and revoked from the existing Battle.net profile.
  • The plaintext key is displayed once; only a SHA-256 digest and a non-secret prefix are persisted.
  • Key rotation and revocation are serialized with a row lock, while a partial unique index guarantees one active key per user.
  • Requests accept Authorization: Bearer or X-API-Key and are limited to 60 requests per minute per key by default.
  • Parameter allowlists, bounded arrays and integers, deterministic pagination, and structured JSON errors prevent unsupported or unexpectedly expensive queries.

This intentionally exposes public aggregate data only. Personal games and the premium-only region and force_fresh filters are not part of the v1 contract.

The rate limiter is node-local, consistent with the application's current in-memory cache model. Its module boundary allows a distributed backend to be introduced later without changing the API plugs or public contract.

UI and documentation

  • Adds API key management to Profile Settings.
  • Adds /api-docs with endpoint navigation, authentication examples, parameter tables, response conventions, rate-limit headers, and error semantics.
  • Adds an API Docs link under the existing Misc menu.
  • Documents the API in the project README.

Implementation notes

  • Reuses the existing DeckTracker and Streaming query paths instead of introducing a second statistics pipeline.
  • Adds stable tie-breakers and cursor pagination for the newest-deck feed.
  • Preserves Twitch and HSReplay login fallbacks and normalizes case-insensitive streamer lookup.
  • Returns complete deck lists, streamer performance, matchup data, and card mulligan/drawn/kept statistics using consistent serializers.

Validation

  • 48 focused ExUnit tests covering API keys, authentication, rate limiting, validation, real aggregate SQL queries, cursor pagination, streamer fallbacks, controllers, navigation, and Profile Settings.
  • mix compile
  • mix assets.build
  • formatting checks for every changed Elixir file
  • strict Credo checks for the new API code and tests
  • migration verified against PostgreSQL, including both unique indexes
  • desktop and mobile rendering checks for /api-docs
  • git diff --check

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.

1 participant