Skip to content

fix: sync GitHub issue state for org bounty pages#221

Open
trasnake87 wants to merge 1 commit intoalgora-io:mainfrom
trasnake87:fix/org-bounty-stale-state
Open

fix: sync GitHub issue state for org bounty pages#221
trasnake87 wants to merge 1 commit intoalgora-io:mainfrom
trasnake87:fix/org-bounty-stale-state

Conversation

@trasnake87
Copy link

Proposed Changes

Fix org bounty pages (/:org/bounties) showing stale bounties as "open" with "0 claims" when the linked GitHub issues have been closed, PRs merged, or /claim commands posted.

Root cause

When GitHub webhooks are missed or not configured for a repo, ticket.state stays at its default (:open) in the database even after the GitHub issue is closed. The bounty query correctly filters by t.state == :open (line 1218 of bounties.ex), but the state is never updated for repos without reliable webhook delivery.

The main /bounties page appeared unaffected because its visibility filter (o.featured == true) happens to exclude orgs with stale webhook data — not because it handles state differently.

Fix

  1. Background sync job (SyncBountyTickets): An Oban worker that fetches current GitHub issue state for all open bounties belonging to an org. Enqueued when an org bounty page is visited, deduplicated to run at most once per hour per org to avoid API spam. Uses the existing Workspace.update_ticket_from_github/4 which already handles syncing state, closed_at, and merged_at.

  2. Include ticket.state in select: Added state: t.state to the bounty query's select map so the UI has access to the current ticket state for display purposes.

How it works

User visits /ZIO/bounties
  → handle_params enqueues SyncBountyTickets job (if connected)
  → Oban deduplicates: skips if already ran for this org in the last hour
  → Job fetches open bounties for the org
  → For each, calls Workspace.update_ticket_from_github/4
  → Ticket state updated from GitHub API (open → closed)
  → Next page load: query filters out closed tickets correctly

Proof

  • Project compiles cleanly with --warnings-as-errors
  • Test verifying job enqueue behavior included
  • Minimal change: 3 files modified, 1 new file (the Oban worker)

Checklist

  • Code compiles without warnings
  • Tests added for the sync job
  • Follows existing patterns (Oban workers in jobs/ directories, Github.TokenPool for API tokens)
  • No breaking changes to existing queries or schemas

Fixes #213

/claim #213

Org bounty pages (/org/bounties) showed stale bounties as "open" with
"0 claims" even when the linked GitHub issues had been closed or had
merged PRs. The main /bounties page was unaffected because its
visibility filter (featured orgs only) happened to exclude orgs with
stale webhook data.

Root cause: when GitHub webhooks are missed or not configured for a
repo, the ticket.state field in the database stays at its default
(:open) even after the GitHub issue is closed. The query correctly
filters by ticket state, but the state is never updated.

Fix: add an Oban background job (SyncBountyTickets) that refreshes
ticket state from the GitHub API when an org bounty page is visited.
The job is deduplicated to run at most once per hour per org, so
repeated page loads don't spam the API. It uses the existing
Workspace.update_ticket_from_github/4 function which already handles
syncing issue state, closed_at, and merged_at fields.

Also include ticket.state in the bounty list_bounties_with select so
the UI has access to the current ticket state for display purposes.

Fixes algora-io#213
@CLAassistant
Copy link

CLAassistant commented Mar 20, 2026

CLA assistant check
All committers have signed the CLA.

@trasnake87
Copy link
Author

Friendly ping — this is ready for review whenever you get a chance. Happy to address any feedback.

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.

UI Bug: Org bounty pages show stale bounties as open with 0 claims despite GitHub activity

2 participants