Repository navigation
Conversation
…ioLab#1247) Add a background worker that aggregates per-user milestone metrics from the indexer projection tables (participants, credit_events, claim_events, referral_credits) and grants global achievement badges. - services/achievementBadgeService: validated badge catalog plus pure evaluation and progress helpers - dal/sqliteUserBadgeRepository: keyset-paginated metric aggregation and a transactional, idempotent save (badges are never revoked) - jobs/achievementBadgesJob: batched run with per-user error isolation and a guard against a non-advancing cursor - migration 049: user_badges and user_milestone_progress tables - wired into the job runner hourly (BADGE_CALCULATOR_INTERVAL_MS, BADGE_CALCULATOR_BATCH_SIZE) Also teach the migration runner the `export const migration = {...}` shape used by 046_session_tokens, 047_campaign_tenant_isolation and 048_campaign_reward_notifications. Those files export no numeric `version`, so runMigrations threw at 046 and no later migration (including 049) could apply. Closes FinesseStudioLab#1247 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@brunomeno 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! 🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #1247
Adds a background worker that calculates aggregate milestone progress per user and grants global achievement badges.
The source data is the indexer projection tables from migration 033 (
participants,credit_events,claim_events,referral_credits). The worker reads that on-chain-derived state, so it needs no new contract calls and changes no Soroban contracts, SDKs or existing APIs.What's included
services/achievementBadgeService.jsvalidateBadgeCatalog,normalizeMetrics,evaluateBadgesandbadgeProgressdal/sqliteUserBadgeRepository.jsjobs/achievementBadgesJob.jsdb/migrations/049_user_achievement_badges.jsuser_badges(PK(user, badge_id)) anduser_milestone_progressindex.js,dal/index.js,.env.exampleachievement_badgeshandler on the existing job runner (retries, dead-letter and distributed lock) and schedules it hourlyDesign notes
INSERT OR IGNOREon(user, badge_id). They are never revoked, so a user who leaves a campaign keeps what they earned. Re-running the job only refreshes the snapshots.user > ? ORDER BY user LIMIT ?(default 500, capped at 5,000). Each branch of the userUNIONfilters on an indexed column.badgeProgress()derives per-badge progress from them. Changing the catalog therefore needs no data migration.Migration runner fix (needed for this PR)
046_session_tokens,047_campaign_tenant_isolationand048_campaign_reward_notificationsexportmigration = { name, description, up }instead of the documentedversion/description/up. As a result,runMigrationsthrowsMigration 046_session_tokens.js must export a numeric "version", andcreateDalfails before migration 049 can apply.migrate.jsnow adapts that shape the same way it already adapts.sqlfiles, taking the version from theNNN_prefix. Files that use the documented exports behave exactly as before.Configuration
BADGE_CALCULATOR_INTERVAL_MS3600000BADGE_CALCULATOR_BATCH_SIZE500The job is skipped when
disableJobsis set, like the other scheduled jobs.Release / rollback / operational impact
[achievementBadges] Calculation completedwithusersScanned,badgesGrantedandfailures. Failed runs follow the existing retry and dead-letter path.Tests
services/achievementBadgeService.test.js: catalog validation, metric normalisation, badge evaluation and progress.jobs/achievementBadgesJob.test.js: badge grants, idempotency, keyset paging including an exactly full last page, per-user failure isolation, the non-advancing cursor guard, and batch-size clamping.dal/sqliteUserBadgeRepository.test.js: runs the real migrations on in-memory SQLite and covers aggregation, paging, upsert without revoking, transaction rollback, and the job end to end.