#100 · Resolve MR author from attrs.author_id, not body.user (avoid mis-credit)
Description
Context
The GitLab MR webhook at apps/scoreboard/src/api/webhook.ts resolves the contributor identity from body.user.username (and attrs.last_commit.author.email as fallback). Per GitLab's webhook docs, body.user is the actor that triggered the event — for a Merge Request "merge" event, that's whoever clicked merge, not the MR author.
For self-merged MRs (one person opens + merges) this is harmless. For the actual bounty workflow — community contributor opens an MR, maintainer reviews + merges — the maintainer gets credited, not the contributor. The contributor never sees their points and the maintainer's merge_pr count climbs unfairly.
The contributor's true identity is object_attributes.author_id (a numeric GitLab user ID), or you can fetch the MR's author object via the API.
Acceptance criteria
- [ ]
apps/scoreboard/src/api/webhook.tsresolves the contributor as the MR author (attrs.author_id), not the actor (body.user) - [ ] Lookup order in code: (1)
users.gitlab_usernamematched against the author's GitLab username, (2) commit author email fallback (existing behavior) - [ ] Add a small helper
fetchMrAuthorUsername(projectId, authorId, token)that hitsGET /users/<id>and returnsusername. Cache in module-scope Map for the lifetime of the request (rare to need >1 lookup per webhook). - [ ] When
body.user.id !== attrs.author_id, log ametadata.merger_usernamefield on the awardedpoint_eventsso admin auditors can see who clicked merge - [ ] Update unit/integration tests if any exist; add at least a doc-test snippet showing both scenarios (self-merge, maintainer-merge)
- [ ] Manually verify by opening a test MR as one user and merging as another (admin can do this with the test-account flow on git.irregularchat.com)
Technical hints
- Existing webhook handler logic reference:
apps/scoreboard/src/api/webhook.ts:99-130(the user-resolution block) - GitLab User API:
GET /api/v4/users/<id>returns{username, email, name, ...}— needsread_userscope, whichread_apialready covers body.userpayload for merge_request events: https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#merge-request-events- Don't break the fallback path — commit-email lookup must still work for users who haven't set
gitlab_username - Idempotency unchanged:
source_id = mr:<project>:<iid>already correctly uniques per-MR; this fix is purely about *which user* gets credited
Why this matters now
- 86 open bounties on the monorepo expecting community PRs
- Today's pipeline test (MR !1, merged 2026-05-04) — the test only worked because sac was both author and merger
- First real community MR will surface this bug — a maintainer will accidentally collect someone else's bounty
- Scope: only affects
git.irregularchat.comwebhook handling. Thegithubremote is read-only mirror; no GitHub webhook in scope.
--- *Submit a merge request that says Closes #<this iid> in the description. On merge to main, the GitLab webhook auto-awards your bounty (50 pts) + the standard merge_pr (40 pts) to your scoreboard account.*
Relevant files
No relevant files linked yet.
Hints
No hints yet.
Activity
- +50 Günther Van der Eecken earned S bounty Jun 14
Comments
Sign in to join the discussion.
No comments yet. Be the first to weigh in.