Skip to content

feat(jobs/challenges): Phase 2 — 7 more poll-based processors#841

Open
raymondjacobson wants to merge 1 commit into
api/challenges-phase-1from
api/challenges-phase-2
Open

feat(jobs/challenges): Phase 2 — 7 more poll-based processors#841
raymondjacobson wants to merge 1 commit into
api/challenges-phase-1from
api/challenges-phase-2

Conversation

@raymondjacobson
Copy link
Copy Markdown
Member

Summary

Stacked on #835 (Phase 1). Adds 7 more challenge processors. No new infra — all source tables already exist.

ID Source Notes
`c` first_weekly_comment `comments` grouped by ISO week One row per (user, ISO-year, ISO-week)
`cp` comment_pin `tracks.pinned_comment_id` + `users.is_verified` Commenter earns when verified track owner pins their (non-self) comment
`cs` cosign `remixes` + `reposts`/`saves` + `users.is_verified` Verified parent owner saves/reposts a remix → remixer earns. Cap: 5 cosigns per parent-owner per rolling 30 days. Currently `active=false` in catalog.
`t` tastemaker `track_trending_scores` (top-10) + `reposts`/`saves` Earliest 10 reposters + 10 savers per top-10 trending track. Top-N is 10 per direction (apps had 5).
`w` remix_contest_winner `events.event_data->>'winners'` JSONB Verified-host winners earn. Max 5 winners/contest, max 5 host rewards/rolling week.
`b` audio_matching_buyer `v_usdc_purchases` (incremental on slot) `amount = 1 × dollars` (dollars = micro-USDC / 1e6)
`s` audio_matching_seller same `amount = 5 × dollars`, gated on seller `is_verified`

Confirmations folded in

  • `cs` cap: 5 cosigns / 30 days ✓
  • `t` top-N: 10 (was 5 in apps) ✓
  • `w`: read winners directly from `events.event_data->>'winners'` JSONB ✓
  • `b`/`s` amount: catalog × dollars (b=1×, s=5×) ✓

Stack

```
#834 parity jobs
└─ #835 phase 1 challenges
└─ this PR — phase 2 challenges
```

Test plan

11 DB-backed tests in addition to the 12 from Phase 1:

  • `TestFirstWeeklyComment_OneRowPerUserPerWeek` — dedupe within week, separate weeks → separate rows
  • `TestCommentPin_VerifiedOwnerPinsOthersComment` — happy path
  • `TestCommentPin_SkippedWhenOwnerNotVerified` — gate enforced
  • `TestCommentPin_SkippedForSelfPin` — gate enforced
  • `TestCosign_VerifiedParentReposting` — happy path (activates the inactive catalog row for the test)
  • `TestCosign_MonthCap` — 6th cosign within 30d blocked
  • `TestTastemaker_EarliestRepostersAndSavers` — both action types earn
  • `TestRemixContestWinner_VerifiedHostMintsRows` — two winners → two rows
  • `TestRemixContestWinner_UnverifiedHostSkipped` — gate enforced
  • `TestAudioMatching_BuyerAndSeller` — both rows minted with correct amounts
  • `TestAudioMatching_SellerUnverifiedNoRow` — verified-seller gate
  • `TestAudioMatching_InvalidPurchaseExcluded` — `v_usdc_purchases` filters
  • All Phase 1 tests still pass (no regressions)
  • `go build ./...` clean

Next

PR B (signals endpoint + 5 Phase 3 processors) follows.

🤖 Generated with Claude Code

Adds 7 more challenge processors to api/jobs/challenges/ following the
same poll-based reconciliation pattern from Phase 1. No new infra; all
source tables already exist.

Processors:
  c   first_weekly_comment   one row per (user, ISO-week)
  cp  comment_pin            commenter earns when verified track owner
                             pins their comment (skips self-pin)
  cs  cosign                 verified parent owner saves/reposts a remix;
                             remixer earns; cap 5 cosigns per parent-owner
                             per rolling 30 days; currently inactive in catalog
  t   tastemaker             earliest 10 reposters + earliest 10 savers
                             of each top-10 trending track
  w   remix_contest_winner   winners of verified-host remix contest; max
                             5 winners per contest, max 5 winner rewards
                             per host per rolling week
  b   audio_matching_buyer   per USDC purchase; amount = 1 × dollars
  s   audio_matching_seller  same purchase; amount = 5 × dollars; gated
                             on seller verification

Audio matching reads from v_usdc_purchases (filtered to is_valid = TRUE);
checkpoint by sol_purchases.slot for incremental scanning.

Migration 0204 seeds the catalog rows from challenges.json with ON
CONFLICT DO UPDATE.

Tastemaker top-N bumped to 10 per direction (apps' historical value was
5). Per-track threshold of 10 reposters/savers kept as apps.

All 7 new processors registered in IndexChallengesJob (now 18 total).

Tests: 11 new DB-backed tests covering each processor's happy path and
its main gates (verified/unverified, cap enforcement, invalid purchases).
All passing against test_jobs template DB.
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