feat: reusable, time-windowed leaderboard (@cozy-games/leaderboard) #1

Merged
ayo merged 1 commit from feat/reusable-leaderboard into main 2026-07-03 11:41:15 +00:00
Owner

Extract the leaderboard into a generic, backend-agnostic package and add
rolling Today/Week/Month/All-Time windows, a web component, and local-first
development against the Firestore emulator.

Package (leaderboard/):

  • LeaderBoardService: backend-agnostic core via a storage-adapter seam, with
    Firebase and Supabase adapters (Supabase client injected, no added dep)
  • Rolling time windows (last 24h / 7d / 30d) with hover tooltips; top-N by score
  • web component built on web-component-base: compose the UI
    in HTML, configure the backend once in JS
  • Every user-facing string is configurable (labels, tooltips, empty/loading/
    error messages, anonymous name) so i18n lives in the app; README + CONFIGURATION

App (mnswpr.com):

  • Compose the board declaratively in index.html via
  • Nickname + randomized greeting bar; score submission through the element
  • Legends: the current all-time leaders frozen into a static /legends page
  • Firebase config and leaderboard namespace via Vite env vars; emulator-first
    local dev (VITE_FIRESTORE_EMULATOR)

Firebase schema-as-code:

  • firebase.json, .firebaserc, firestore.rules (public reads, create-only scores,
    no client updates/deletes, namespace-generalized), empty indexes (rolling
    windows need none)
  • prod (mw-) vs dev/test (mw-test-) separation by collection namespace
  • emulator config, seed script, and docs (firebase-leaderboards.md,
    leaderboard-env-migration.md, AYO.md)

Utils/tests: UTC date-bucket helper (retained as metadata) with Vitest coverage.

Extract the leaderboard into a generic, backend-agnostic package and add rolling Today/Week/Month/All-Time windows, a web component, and local-first development against the Firestore emulator. Package (leaderboard/): - LeaderBoardService: backend-agnostic core via a storage-adapter seam, with Firebase and Supabase adapters (Supabase client injected, no added dep) - Rolling time windows (last 24h / 7d / 30d) with hover tooltips; top-N by score - <cozy-leaderboard> web component built on web-component-base: compose the UI in HTML, configure the backend once in JS - Every user-facing string is configurable (labels, tooltips, empty/loading/ error messages, anonymous name) so i18n lives in the app; README + CONFIGURATION App (mnswpr.com): - Compose the board declaratively in index.html via <cozy-leaderboard> - Nickname + randomized greeting bar; score submission through the element - Legends: the current all-time leaders frozen into a static /legends page - Firebase config and leaderboard namespace via Vite env vars; emulator-first local dev (VITE_FIRESTORE_EMULATOR) Firebase schema-as-code: - firebase.json, .firebaserc, firestore.rules (public reads, create-only scores, no client updates/deletes, namespace-generalized), empty indexes (rolling windows need none) - prod (mw-*) vs dev/test (mw-test-*) separation by collection namespace - emulator config, seed script, and docs (firebase-leaderboards.md, leaderboard-env-migration.md, AYO.md) Utils/tests: UTC date-bucket helper (retained as metadata) with Vitest coverage.
ayo added 1 commit 2026-07-03 11:40:32 +00:00
Extract the leaderboard into a generic, backend-agnostic package and add
rolling Today/Week/Month/All-Time windows, a web component, and local-first
development against the Firestore emulator.

Package (leaderboard/):
- LeaderBoardService: backend-agnostic core via a storage-adapter seam, with
  Firebase and Supabase adapters (Supabase client injected, no added dep)
- Rolling time windows (last 24h / 7d / 30d) with hover tooltips; top-N by score
- <cozy-leaderboard> web component built on web-component-base: compose the UI
  in HTML, configure the backend once in JS
- Every user-facing string is configurable (labels, tooltips, empty/loading/
  error messages, anonymous name) so i18n lives in the app; README + CONFIGURATION

App (mnswpr.com):
- Compose the board declaratively in index.html via <cozy-leaderboard>
- Nickname + randomized greeting bar; score submission through the element
- Legends: the current all-time leaders frozen into a static /legends page
- Firebase config and leaderboard namespace via Vite env vars; emulator-first
  local dev (VITE_FIRESTORE_EMULATOR)

Firebase schema-as-code:
- firebase.json, .firebaserc, firestore.rules (public reads, create-only scores,
  no client updates/deletes, namespace-generalized), empty indexes (rolling
  windows need none)
- prod (mw-*) vs dev/test (mw-test-*) separation by collection namespace
- emulator config, seed script, and docs (firebase-leaderboards.md,
  leaderboard-env-migration.md, AYO.md)

Utils/tests: UTC date-bucket helper (retained as metadata) with Vitest coverage.
ayo merged commit 9e1114be78 into main 2026-07-03 11:41:15 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: ayo/mnswpr#1
No description provided.