Commit 386ac75
contests: exclude shadow-banned hosts from /v1/events/remix-contests (#803)
## Summary
`v1EventsRemixContests`
([api/v1_events_remix_contests.go](api/v1_events_remix_contests.go)) —
the endpoint backing the contests discovery page on mobile + web —
previously surfaced contests whose host was shadow-banned.
`v1EventComments` already applies the two-signal shadow-ban filter to
comment authors; this PR mirrors the exact same pair against contest
hosts so the discovery list and comment list stay in lockstep.
This was originally drafted against
\`packages/discovery-provider/src/queries/get_events.py\` in the apps
monorepo (PR AudiusProject/apps#14297), but that Flask API was removed
in #14236 and the file is dead code on main. Reopening here in the
correct repo.
## The two signals
| Signal | What it catches | Source pattern |
|---|---|---|
| `aggregate_user.score < 0` (`low_abuse_score` CTE) | bots,
Audius-impersonators, fast-challenge-runners, low-engagement accounts |
Same CTE used at
[v1_event_comments.go:74-76](api/v1_event_comments.go#L74) |
| `muted_by_karma` CTE | hosts muted by users whose combined
`follower_count` crosses `karmaCommentCountThreshold` | Same CTE used at
[v1_event_comments.go:66-73](api/v1_event_comments.go#L66) |
Both CTEs are lifted verbatim from `v1_event_comments.go` so the filter
is byte-for-byte identical to what the comment system applies to comment
authors. Reuses the existing `karmaCommentCountThreshold` constant
(defined at
[v1_track_comment_count.go:8](api/v1_track_comment_count.go#L8)).
## Implementation
Added two CTEs at the top of the SQL, two `NOT IN` filters to the
existing `filters` slice, and bound the threshold constant:
```sql
WITH
muted_by_karma AS (
SELECT muted_user_id
FROM muted_users
JOIN aggregate_user ON muted_users.user_id = aggregate_user.user_id
WHERE muted_users.is_delete = false
GROUP BY muted_user_id
HAVING SUM(aggregate_user.follower_count) >= @karmaCommentCountThreshold
),
low_abuse_score AS (
SELECT user_id FROM aggregate_user WHERE score < 0
)
SELECT ...
WHERE ...
AND e.user_id NOT IN (SELECT user_id FROM low_abuse_score)
AND e.user_id NOT IN (SELECT muted_user_id FROM muted_by_karma)
```
- The existing `u.is_deactivated = false` and `u.is_available = true`
filters stay in place. Shadow-ban filtering layers on top.
- The contest's parent track filter (`e.entity_type != 'track' OR ...`)
is untouched.
- The sort priority, pagination, status filter, and `entry_counts`
LATERAL subquery are untouched.
- The `users` and `tracks` related lookups downstream are unaffected —
they just see fewer rows.
## Tests
New `TestRemixContestsExcludesShadowbannedHosts` test follows the exact
pattern of `TestRemixContestsExcludesUnavailableContent` already in this
file. Seeds three contests:
- clean host (score=0, no mutes)
- low-score host (score=-1)
- karma-muted host (muted by a high-follower user crossing the
threshold)
Three sub-assertions: only the clean contest is returned; low-score
contest absent; karma-muted contest absent.
\`go build ./api/...\` and \`go vet ./api/...\` both clean locally.
Integration test couldn't be run end-to-end without a local Postgres at
port 21300, but the test compiles fine and CI will run it against a
fresh DB.
## Test plan
- [ ] CI green on `go test ./api/...`
- [ ] Manual smoke after deploy: hit `/v1/events/remix-contests` on
staging, confirm a known shadow-banned account's contest no longer
appears in the response
- [ ] Confirm `useAllRemixContests` on mobile + web still returns the
expected (non-shadowbanned) contests
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent 921fe28 commit 386ac75
2 files changed
Lines changed: 129 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
36 | 36 | | |
37 | 37 | | |
38 | 38 | | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
39 | 48 | | |
40 | 49 | | |
41 | 50 | | |
| |||
49 | 58 | | |
50 | 59 | | |
51 | 60 | | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
52 | 73 | | |
53 | 74 | | |
54 | 75 | | |
| |||
92 | 113 | | |
93 | 114 | | |
94 | 115 | | |
95 | | - | |
96 | | - | |
97 | | - | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
98 | 120 | | |
99 | 121 | | |
100 | 122 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
| 4 | + | |
4 | 5 | | |
5 | 6 | | |
6 | 7 | | |
| |||
460 | 461 | | |
461 | 462 | | |
462 | 463 | | |
| 464 | + | |
| 465 | + | |
| 466 | + | |
| 467 | + | |
| 468 | + | |
| 469 | + | |
| 470 | + | |
| 471 | + | |
| 472 | + | |
| 473 | + | |
| 474 | + | |
| 475 | + | |
| 476 | + | |
| 477 | + | |
| 478 | + | |
| 479 | + | |
| 480 | + | |
| 481 | + | |
| 482 | + | |
| 483 | + | |
| 484 | + | |
| 485 | + | |
| 486 | + | |
| 487 | + | |
| 488 | + | |
| 489 | + | |
| 490 | + | |
| 491 | + | |
| 492 | + | |
| 493 | + | |
| 494 | + | |
| 495 | + | |
| 496 | + | |
| 497 | + | |
| 498 | + | |
| 499 | + | |
| 500 | + | |
| 501 | + | |
| 502 | + | |
| 503 | + | |
| 504 | + | |
| 505 | + | |
| 506 | + | |
| 507 | + | |
| 508 | + | |
| 509 | + | |
| 510 | + | |
| 511 | + | |
| 512 | + | |
| 513 | + | |
| 514 | + | |
| 515 | + | |
| 516 | + | |
| 517 | + | |
| 518 | + | |
| 519 | + | |
| 520 | + | |
| 521 | + | |
| 522 | + | |
| 523 | + | |
| 524 | + | |
| 525 | + | |
| 526 | + | |
| 527 | + | |
| 528 | + | |
| 529 | + | |
| 530 | + | |
| 531 | + | |
| 532 | + | |
| 533 | + | |
| 534 | + | |
| 535 | + | |
| 536 | + | |
| 537 | + | |
| 538 | + | |
| 539 | + | |
| 540 | + | |
| 541 | + | |
| 542 | + | |
| 543 | + | |
| 544 | + | |
| 545 | + | |
| 546 | + | |
| 547 | + | |
| 548 | + | |
| 549 | + | |
| 550 | + | |
| 551 | + | |
| 552 | + | |
| 553 | + | |
| 554 | + | |
| 555 | + | |
| 556 | + | |
| 557 | + | |
| 558 | + | |
| 559 | + | |
| 560 | + | |
| 561 | + | |
| 562 | + | |
| 563 | + | |
| 564 | + | |
| 565 | + | |
| 566 | + | |
0 commit comments