Skip to content

Add exact bounty source filters#736

Merged
ramimbo merged 3 commits into
ramimbo:mainfrom
Jorel97:codex/647-712-bounty-source-filters
Jun 1, 2026
Merged

Add exact bounty source filters#736
ramimbo merged 3 commits into
ramimbo:mainfrom
Jorel97:codex/647-712-bounty-source-filters

Conversation

@Jorel97
Copy link
Copy Markdown
Contributor

@Jorel97 Jorel97 commented May 31, 2026

Bounty #647
Source issue: #712

Summary

  • Adds exact repo and issue_number filters to /api/v1/bounties.
  • Applies the same filters to /api/v1/bounties/summary so capacity totals can be scoped to a source repo or exact source issue.
  • Wires /bounties through the same source filters and preserves them in the JSON results link/search form state.
  • Documents when agents should use exact source filters instead of broad q search.

Verification

  • PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 .\.venv\Scripts\python.exe -m pytest tests\test_bounty_api_routes.py tests\test_bounty_pages.py tests\test_public_routes.py tests\test_docs_public_urls.py -q -> 63 passed, 1 existing Starlette/httpx warning
  • .\.venv\Scripts\python.exe -m ruff check app\bounty_api.py app\public_routes.py tests\test_bounty_api_routes.py tests\test_bounty_pages.py tests\test_public_routes.py tests\test_docs_public_urls.py -> All checks passed
  • .\.venv\Scripts\python.exe -m ruff format --check app\bounty_api.py app\public_routes.py tests\test_bounty_api_routes.py tests\test_bounty_pages.py tests\test_public_routes.py tests\test_docs_public_urls.py -> 6 files already formatted
  • .\.venv\Scripts\python.exe scripts\docs_smoke.py -> docs smoke ok
  • git diff --check -> passed

Duplicate Check

Scope

No payout execution, proof generation, ledger mutation, treasury execution, wallet behavior, balance, exchange, bridge, cash-out, price, private data, or production mutation behavior changed.

Summary by CodeRabbit

  • New Features

    • Filter bounties by repository name and issue number via the web UI and API
    • UI preserves and displays active repository/issue filters (includes "Source filter") and includes them in the "View JSON results" link
    • /api/v1/bounties and /api/v1/bounties/summary accept repo and issue_number parameters (issue_number >= 1)
  • Validation

    • Repo input is validated; invalid values return a 400 error
  • Documentation

    • Docs and examples updated to show exact repo/issue_number queries
  • Tests

    • Added/updated tests covering repo+issue filtering and validation

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 31, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: a9c8ceed-3935-46d5-be55-2e553218d8e7

📥 Commits

Reviewing files that changed from the base of the PR and between 6423498 and 982304e.

📒 Files selected for processing (4)
  • app/public_routes.py
  • app/templates/bounties.html
  • tests/test_bounty_pages.py
  • tests/test_public_routes.py

📝 Walkthrough

Walkthrough

This PR adds optional repo and issue_number query filters to the bounty list, summary, and HTML page endpoints. The API helper validates repository names and normalizes both inputs before filtering. Public routes wire the parameters through the template context. The UI renders and persists the filters in form fields and displays an active source filter indicator.

Changes

Bounty Source Filtering

Layer / File(s) Summary
API filtering implementation and validation
app/bounty_api.py, tests/test_bounty_api_routes.py
Internal helper _list_bounties_by_status accepts repo and issue_number, validates repo for control characters, normalizes inputs (trim, lowercase), derives issue number from free-text q when present, and applies database equality filters. Endpoints /api/v1/bounties and /api/v1/bounties/summary expose and forward the parameters. API tests verify filtering combinations and control-character rejection with 400 response.
Public route wiring and template context
app/public_routes.py, tests/test_public_routes.py
_bounties_api_url and _bounties_page_url build encoded query strings including repo and issue_number; public_bounties_context normalizes and exposes them as selected_repo and selected_issue_number; /bounties endpoint accepts the parameters and threads them into listing and context calls; register_public_routes signature updated. Tests verify normalization and URL generation including limit behavior.
Web UI rendering and form persistence
app/templates/bounties.html, tests/test_bounty_pages.py
Template adds hidden form fields to preserve filter state during search submissions and renders conditional "Source filter" display when either filter is active. Page tests verify repo-scoped filtering shows matching bounty, excludes same-issue bounty from different repo, and confirms JSON results link preserves filters.
Documentation and API examples
docs/agent-guide.md, docs/api-examples.md, tests/test_docs_public_urls.py
Added examples demonstrating repo + issue_number filtering for bounty list and summary endpoints; guidance showing how to map a GitHub issue URL to repo and issue_number; documentation smoke tests updated to assert new query strings and wording.

Possibly related issues

Possibly related PRs

  • ramimbo/mergework#596: Also extends the JSON results URL builder in app/public_routes.py to preserve additional filters including repo and issue_number.
  • ramimbo/mergework#394: Extracted register_public_routes/public_bounties_context; this PR extends that plumbing to include repo/issue_number.
  • ramimbo/mergework#311: Introduced /api/v1/bounties/summary; this PR extends that endpoint to support repo/issue_number filters.
🚥 Pre-merge checks | ✅ 6
✅ Passed checks (6 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concretely names the changed surface: exact bounty source filters (repo and issue_number parameters) added across API and UI endpoints.
Description check ✅ Passed The description covers all required template sections: Summary (clear), Evidence (confusion/missing functionality addressed), intended surfaces, PR scope, and full Test Evidence verification with concrete commands and results.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Mergework Public Artifact Hygiene ✅ Passed No investment, price, cash-out, or off-ramp claims detected. PR adds only filtering functionality and API examples; MRWK characterized consistently as native ledger coin per existing guidance.
Bounty Pr Focus ✅ Passed All 9 stated files verified: bounty API filters by repo/issue_number with control char validation, normalization, UI preservation, and comprehensive tests. No unrelated scope creep.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 06dd5d1f-1d95-4405-b23d-16239f9dc814

📥 Commits

Reviewing files that changed from the base of the PR and between 0eb12a3 and e4d8032.

📒 Files selected for processing (9)
  • app/bounty_api.py
  • app/public_routes.py
  • app/templates/bounties.html
  • docs/agent-guide.md
  • docs/api-examples.md
  • tests/test_bounty_api_routes.py
  • tests/test_bounty_pages.py
  • tests/test_docs_public_urls.py
  • tests/test_public_routes.py

Comment thread app/templates/bounties.html
@Jorel97
Copy link
Copy Markdown
Contributor Author

Jorel97 commented May 31, 2026

Maintenance update for the CodeRabbit source-filter label comment:

  • Added the separator before issue-only source filters so the page renders Source filter: #649. instead of Source filter#649.
  • Updated the page test expectation for the repo + issue display.

Validation:

  • PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 .\.venv\Scripts\python.exe -m pytest tests\test_bounty_pages.py tests\test_public_routes.py -q -> 21 passed, 1 existing Starlette/httpx warning
  • .\.venv\Scripts\python.exe -m ruff check tests\test_bounty_pages.py tests\test_public_routes.py -> All checks passed
  • .\.venv\Scripts\python.exe -m ruff format --check tests\test_bounty_pages.py tests\test_public_routes.py -> 2 files already formatted
  • git diff --check -> clean

Copy link
Copy Markdown
Contributor

@Gwani-28 Gwani-28 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting changes for one UI state-preservation gap.\n\nThe API/list implementation now accepts exact source filters, and the page correctly shows the active source filter plus the JSON results link. But the status navigation in app/templates/bounties.html:27-31 is still built only from q/sort/limit/status. If a user lands on /bounties?repo=ramimbo%2Fmergework&issue_number=649 and then clicks Paid, the rendered link is /bounties?status=paid, so the exact source selector is dropped and the page switches from that GitHub issue to all paid bounties. The same omission applies to the All/Open/Closed links.\n\nFor #712, the main workflow is starting from a precise GitHub issue URL and keeping repo=owner/name plus issue_number=N as the source selector. The HTML surface should preserve those selector params across the status filter links the same way it already preserves q/sort/limit, otherwise /bounties is not consistent with the filtered API/summary surfaces after the first status click.\n\nLocal validation on current head 6423498:\n- .venv/bin/python -m pytest tests/test_bounty_api_routes.py tests/test_bounty_pages.py tests/test_public_routes.py tests/test_docs_public_urls.py -q -> 63 passed, 1 existing Starlette/httpx warning\n- .venv/bin/ruff check app/bounty_api.py app/public_routes.py tests/test_bounty_api_routes.py tests/test_bounty_pages.py tests/test_public_routes.py tests/test_docs_public_urls.py -> passed\n- .venv/bin/ruff format --check app/bounty_api.py app/public_routes.py tests/test_bounty_api_routes.py tests/test_bounty_pages.py tests/test_public_routes.py tests/test_docs_public_urls.py -> 6 files already formatted\n- .venv/bin/python scripts/docs_smoke.py -> docs smoke ok\n- git diff --check origin/main...HEAD -> clean\n- git merge-tree --write-tree origin/main HEAD -> clean tree 5e1fdf93ee26a248b84b2749149b3a2ddf2f6f29\n- gh pr checks 736 --repo ramimbo/mergework -> Quality/readiness/docs/image checks passed; CodeRabbit was still pending at review time\n\nNo private data, credentials, wallet material, production mutation, price/exchange/bridge/off-ramp behavior, or fabricated payout claims were used.

@Jorel97
Copy link
Copy Markdown
Contributor Author

Jorel97 commented May 31, 2026

Maintenance update for the requested status-link preservation gap:

  • Status filter links are now generated from the normalized page context instead of hand-built in the template.
  • All/Open/Paid/Closed links now preserve exact repo and issue_number selectors, along with q, sort, and limit.
  • Added page/context regression coverage for source-filter preservation.

Validation:

  • PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 .\.venv\Scripts\python.exe -m pytest tests\test_bounty_api_routes.py tests\test_bounty_pages.py tests\test_public_routes.py tests\test_docs_public_urls.py -q -> 63 passed, 1 existing Starlette/httpx warning
  • .\.venv\Scripts\python.exe -m ruff check app\bounty_api.py app\public_routes.py tests\test_bounty_api_routes.py tests\test_bounty_pages.py tests\test_public_routes.py tests\test_docs_public_urls.py -> All checks passed
  • .\.venv\Scripts\python.exe -m ruff format --check app\bounty_api.py app\public_routes.py tests\test_bounty_api_routes.py tests\test_bounty_pages.py tests\test_public_routes.py tests\test_docs_public_urls.py -> 6 files already formatted
  • .\.venv\Scripts\python.exe scripts\docs_smoke.py -> docs smoke ok
  • git diff --check -> clean

Thanks for catching this; the source selector now survives status navigation on the HTML surface.

Copy link
Copy Markdown
Contributor

@Gwani-28 Gwani-28 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed current head 982304e0d7418d14fa1f1f38cd98228d105047d2 after the status-link follow-up.

The previous blocker is resolved. Status filter links are now generated from normalized context and preserve exact repo and issue_number selectors alongside q, sort, and limit. The API/list and summary behavior still filters by normalized repo=owner/name and exact issue_number=N, and the public page keeps the active source filter visible with a matching JSON results link.

Local validation:

  • .venv/bin/python -m pytest tests/test_bounty_api_routes.py tests/test_bounty_pages.py tests/test_public_routes.py tests/test_docs_public_urls.py -q -> 63 passed, 1 existing Starlette/httpx warning
  • .venv/bin/ruff check app/bounty_api.py app/public_routes.py tests/test_bounty_api_routes.py tests/test_bounty_pages.py tests/test_public_routes.py tests/test_docs_public_urls.py -> passed
  • .venv/bin/ruff format --check app/bounty_api.py app/public_routes.py tests/test_bounty_api_routes.py tests/test_bounty_pages.py tests/test_public_routes.py tests/test_docs_public_urls.py -> 6 files already formatted
  • .venv/bin/python scripts/docs_smoke.py -> docs smoke ok
  • git diff --check origin/main...HEAD -> clean
  • git merge-tree --write-tree origin/main HEAD -> clean tree 6f295192c493ce7a2d7091d35318d82c3b152e60
  • gh pr checks 736 --repo ramimbo/mergework -> CodeRabbit passed/skipped and Quality/readiness/docs/image checks passed

No private data, credentials, wallet material, production mutation, price/exchange/bridge/off-ramp behavior, or fabricated payout claims were used.

Copy link
Copy Markdown
Contributor

@xyjk0511 xyjk0511 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed PR #736 at current head 982304e0d7418d14fa1f1f38cd98228d105047d2 as a non-author current-head review.

No blocker found in the exact source-filter implementation. I checked the REST API, public /bounties page context, template state preservation, docs, and focused regression tests against source issue #712 / bounty #647.

What I verified:

  • /api/v1/bounties and /api/v1/bounties/summary now compose exact repo=owner/name and issue_number=N filters with existing status, q, sort, and limit handling.
  • repo filters are normalized and reject control characters, while issue_number uses FastAPI's ge=1 validation rather than broad text search semantics.
  • /bounties passes the same source filters through to the API-backed list, keeps the selected source filter visible, preserves it in status-filter links, and includes it in the JSON results URL.
  • the prior status-link preservation issue from the earlier review is fixed on this head.
  • docs tell agents to use exact source filters when broad q search is ambiguous, without changing payout, proof, wallet, ledger, treasury execution, or price/off-ramp behavior.

Validation run locally:

  • PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 python -m pytest tests/test_bounty_api_routes.py tests/test_bounty_pages.py tests/test_public_routes.py tests/test_docs_public_urls.py -q -> 63 passed
  • python -m ruff check app/bounty_api.py app/public_routes.py tests/test_bounty_api_routes.py tests/test_bounty_pages.py tests/test_public_routes.py tests/test_docs_public_urls.py -> passed
  • python -m ruff format --check app/bounty_api.py app/public_routes.py tests/test_bounty_api_routes.py tests/test_bounty_pages.py tests/test_public_routes.py tests/test_docs_public_urls.py -> 6 files already formatted
  • python scripts/docs_smoke.py -> docs smoke ok
  • git diff --check origin/main...HEAD -> clean
  • git merge-tree --write-tree origin/main HEAD -> clean tree 6f295192c493ce7a2d7091d35318d82c3b152e60
  • gh pr checks 736 --repo ramimbo/mergework -> Quality/readiness/docs/image passed; CodeRabbit passed/skipped

No private data, credentials, wallet material, production mutation, payout/proof/ledger/treasury execution, exchange/bridge/cash-out, price behavior, or fabricated payout claims were used.

Copy link
Copy Markdown
Contributor

@JONASXZB JONASXZB left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed current head 982304e0d7418d14fa1f1f38cd98228d105047d2 as a non-author.

No blocker found for the exact bounty source-filter slice. Evidence checked:

  • inspected app/bounty_api.py and confirmed optional exact repo and issue_number filters compose with existing status, q, sort, and limit behavior;
  • verified repo is trimmed/lowercased for exact matching, blank repo is ignored, control-character repo input returns 400, and issue_number uses positive integer query bounds;
  • checked app/public_routes.py and app/templates/bounties.html to confirm the public /bounties page preserves source filters in JSON-results links, status links, form values, and visible labels;
  • checked docs in docs/agent-guide.md and docs/api-examples.md for exact source-filter examples and the distinction from broad q search;
  • ran MERGEWORK_DATABASE_URL=sqlite:////tmp/mergework-pr736-review-test.sqlite python -m pytest tests/test_bounty_api_routes.py tests/test_bounty_pages.py tests/test_public_routes.py tests/test_docs_public_urls.py -q -> 63 passed, 1 warning;
  • ran python scripts/docs_smoke.py, targeted Ruff check/format, python -m mypy app/bounty_api.py app/public_routes.py, and git diff --check origin/main...HEAD;
  • ran a local API/summary/page smoke confirming exact repo+issue filters return only the target bounty, issue-only filters can match across repositories, repo summaries work, page rendering preserves the exact filters, and control-character repo input returns 400;
  • checked mergeability with git merge-tree --write-tree origin/main HEAD -> exit 0.

Hosted status for this head is green (CodeRabbit: success; Quality, readiness, docs, and image checks: success).

Non-blocking follow-up: source-only zero-result /bounties pages currently fall through to the generic No bounties yet. empty state instead of the filtered empty-state copy. I did not treat that as a blocker for #712 because the API/summary exact selectors and positive page filter behavior satisfy the requested source-filter semantics, but it would be a nice small UI polish later.

@ramimbo ramimbo merged commit 4572036 into ramimbo:main Jun 1, 2026
2 checks passed
@ramimbo ramimbo added mrwk:accepted Maintainer accepted for payout mrwk:paid Ledger payment recorded labels Jun 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

mrwk:accepted Maintainer accepted for payout mrwk:paid Ledger payment recorded

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants