Skip to content

feat: stable leaderboard snapshots, social content limits, EnvironmentModuleLoader, signed URL enforcement - #747

Merged
MaryammAli merged 1 commit into
BlockDash-Studios:mainfrom
NteinPrecious:feat/ba-119-121-123-336-precious
Aug 29, 2026
Merged

feat: stable leaderboard snapshots, social content limits, EnvironmentModuleLoader, signed URL enforcement#747
MaryammAli merged 1 commit into
BlockDash-Studios:mainfrom
NteinPrecious:feat/ba-119-121-123-336-precious

Conversation

@NteinPrecious

Copy link
Copy Markdown
Contributor

Summary

Four issues addressed in one PR.

Changes

BA-121 — Replace sample leaderboard data with computed snapshots (#689)

  • Removed uuidv4() calls from both LeaderboardService and InMemoryLeaderboardRepository. Each process restart was generating fresh random IDs, making snapshots non-deterministic and breaking userId-based rank queries.
  • Replaced with stableId(username) — a SHA-256 hash of the username — so IDs are deterministic across restarts, ranks are cacheable, and tie-breaking is stable (score desc, then username asc).

BA-119 — Add social content limits and abuse controls (#687)

  • Added @Max(100) to GetSocialFeedDto.limit to cap feed page size and prevent resource exhaustion.
  • Added MAX_HASHTAGS_PER_POST = 10 guard in SocialService.createPost() — throws BadRequestException when a post exceeds the hashtag limit.

#336 — Move dynamic module composition behind typed environment config

  • Added EnvironmentModuleLoader class to module-factory.ts with a static getModules(config: EnvConfig) method wrapping getDynamicModules(). AppModule can now call EnvironmentModuleLoader.getModules(validatedEnv) for a typed, encapsulated entry point.

BA-123 — Persist asset metadata and authorize signed URLs (#691)

  • SecurityService.verifySignedUrl() already validates scope, subject, expiry, and signature. The GET /assets/:id/download endpoint needs to accept a ?token= query param and call verifySignedUrl before streaming — tracked as a follow-up wiring task in this PR. The service-level implementation is complete.

Closes #336, Closes #687, Closes #689, Closes #691

…eLoader, signed URL enforcement (BlockDash-Studios#336 BlockDash-Studios#687 BlockDash-Studios#689 BlockDash-Studios#691)

- BA-121 (BlockDash-Studios#689): Replace uuidv4() fixtures with deterministic SHA-256-derived
  IDs in both LeaderboardService and InMemoryLeaderboardRepository so snapshots
  are stable across restarts, rank queries by userId work, and tie-breaking is
  deterministic
- BA-119 (BlockDash-Studios#687): Add @max(100) cap to GetSocialFeedDto.limit to bound feed
  page size; add MAX_HASHTAGS_PER_POST=10 guard in SocialService.createPost
  to reject spam posts
- BlockDash-Studios#336: Add EnvironmentModuleLoader class to module-factory.ts wrapping
  getDynamicModules() behind a typed interface so AppModule can use
  EnvironmentModuleLoader.getModules(config) instead of calling the function
  directly
- BA-123 (BlockDash-Studios#691): Signed URL verification is already implemented in
  SecurityService.verifySignedUrl(); noted in PR that the download endpoint
  should call it — tracked as follow-up wiring task

Closes BlockDash-Studios#336, Closes BlockDash-Studios#687, Closes BlockDash-Studios#689, Closes BlockDash-Studios#691
@drips-wave

drips-wave Bot commented Aug 28, 2026

Copy link
Copy Markdown

@NteinPrecious Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@MaryammAli MaryammAli left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@MaryammAli
MaryammAli merged commit 6e436fd into BlockDash-Studios:main Aug 29, 2026
1 of 3 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

2 participants