Skip to content

Limit public activity feed rows#751

Open
Jorel97 wants to merge 4 commits into
ramimbo:mainfrom
Jorel97:codex/activity-limit-656
Open

Limit public activity feed rows#751
Jorel97 wants to merge 4 commits into
ramimbo:mainfrom
Jorel97:codex/activity-limit-656

Conversation

@Jorel97
Copy link
Copy Markdown
Contributor

@Jorel97 Jorel97 commented Jun 1, 2026

/claim #656

Summary

  • Add a bounded limit query parameter to /api/v1/activity and /activity.
  • Apply the limit to public activity list sections after filtering while keeping aggregate totals for the full matching set.
  • Return FastAPI validation errors for invalid limits instead of silently ignoring them.
  • Preserve q and non-default limit in the activity page JSON link, and document the activity limit response shape.

Evidence

Intended scope

  • Files/surfaces: app/activity.py, app/serializers.py, app/templates/activity.html, docs/api-examples.md, and focused tests.
  • Expected PR size: small route/serializer validation fix plus activity docs and regression coverage.
  • Out of scope: payout logic, treasury proposal flow, ledger accounting, and unrelated activity UI changes.

Checklist

  • /claim #656 included.
  • Bounty capacity checked before submission.
  • API and HTML activity handlers pass the bounded limit value through the shared context.
  • Invalid limit values return FastAPI validation errors.
  • Regression tests cover valid limits, filtered limits, non-integer limits, exact-size limits, over-dataset limits, and numeric boundaries 0 and 201.
  • Regression tests prove contributors, recent, and pending_payouts are all limited.
  • Activity docs describe default/range/returned rows vs totals.
  • HTML activity page keeps filtered JSON inspection links aligned with the selected limit.

Validation

.\.venv\Scripts\python.exe -m pytest -q
593 passed, 1 warning in 57.82s

.\.venv\Scripts\python.exe -m pytest tests/test_activity.py tests/test_activity_routes.py tests/test_serializers.py::test_activity_serializers_skip_malformed_public_proofs tests/test_docs_public_urls.py::test_api_examples_document_activity_limit -q
9 passed, 1 warning in 2.06s

.\.venv\Scripts\python.exe -m ruff check app/activity.py app/serializers.py tests/test_activity.py tests/test_activity_routes.py tests/test_serializers.py tests/test_docs_public_urls.py
All checks passed!

.\.venv\Scripts\python.exe -m ruff format --check app/activity.py app/serializers.py tests/test_activity.py tests/test_activity_routes.py tests/test_serializers.py tests/test_docs_public_urls.py
6 files already formatted

.\.venv\Scripts\python.exe -m mypy app/activity.py app/serializers.py
Success: no issues found in 2 source files

git diff --check
# pass

Safety

Testing and reproduction were read-only against public MRWK endpoints. This PR only changes list limiting/validation for activity surfaces and adds regression/documentation coverage.

Summary by CodeRabbit

  • New Features

    • Added a limit query parameter to activity endpoints (default 100, range 1–200). Returned arrays (contributors, pending_payouts, recent) are capped to limit while totals reflect the full matching set; responses include the effective limit.
  • UI

    • Activity page’s “View JSON activity” link preserves the effective limit in the query string.
  • Tests

    • Added/updated tests covering valid/invalid limits and rendered links.
  • Documentation

    • API docs updated with limit examples and behavior.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 1, 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: 998934d8-13d7-4073-8fc8-236684436ca8

📥 Commits

Reviewing files that changed from the base of the PR and between 4e4acd1 and 64147ac.

📒 Files selected for processing (1)
  • tests/test_activity.py

📝 Walkthrough

Walkthrough

This PR adds optional limit query parameter support to activity endpoints. The limit (validated 1–200) is threaded through route handlers into the shared context builder and then applied in the serializer to slice output lists while preserving aggregate totals.

Changes

Activity Limit Parameter

Layer / File(s) Summary
Route handlers and context builder
app/activity.py
activity_context signature expands to accept optional limit and forwards it to activity_to_dict. /api/v1/activity and /activity handlers add bounded limit query parameter (1–200), import Annotated/urlencode, add URL helper, and pass limit through to the shared context builder.
Serializer limit implementation
app/serializers.py
activity_to_dict adds a keyword-only limit parameter and computes sliced subsets (contributors, pending_payouts, recent) using [:limit]. Returned payload includes limit and uses sliced lists while totals are computed from full, unsliced collections.
Docs, template, and tests
app/templates/activity.html, docs/api-examples.md, tests/*
Template uses api_results_url. Docs updated to document limit default (100) and max (200) and to show "limit": 25 in examples. Tests added/updated to assert API validation (422 on invalid), correct echoing of limit and q, list truncation behavior, preserved totals, and page link includes limit.

Possibly related PRs

  • ramimbo/mergework#733: Introduces pending_payouts/pending_totals fields in activity_to_dict; this PR applies limit truncation to those pending fields.
  • ramimbo/mergework#328: Recent changes to activity row parsing that activity_to_dict depends on; related to how serializers compute accepted work and contributors.
🚥 Pre-merge checks | ✅ 5 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Bounty Pr Focus ⚠️ Warning PR lacks Bounty/Issue reference and includes substantial unrelated changes (treasury, accounts, test refactoring) outside stated activity-limit scope. Add Bounty #N or Refs #N reference and exclude unrelated files (accounts, treasury, treasury_routes, test refactors) from scope.
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Limit public activity feed rows' directly and concisely names the main change—adding a bounded limit parameter to activity feed endpoints.
Description check ✅ Passed The description covers all required template sections: Summary, Evidence, Intended scope, Test Evidence checklist, MRWK bounty reference, Validation output, and Safety considerations.
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 fabricated payout claims found. MRWK correctly described as native. Activity docs properly document the limit parameter.

✏️ 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: 4e55e57a-ba6f-4a9d-9a67-a22b1941e3ec

📥 Commits

Reviewing files that changed from the base of the PR and between 98bdaa3 and 1cf9959.

📒 Files selected for processing (3)
  • app/activity.py
  • app/serializers.py
  • tests/test_activity.py

Comment thread tests/test_activity.py
Copy link
Copy Markdown
Contributor

@attaboy11 attaboy11 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 #751 at current head 4f708a9be789ce92ff0aca2585702d694d2076c1 as a non-author.

No blocking issue found in the activity limit fix.

What I checked:

  • app/activity.py now exposes a typed limit query parameter on both /api/v1/activity and /activity, bounded to 1..200 by FastAPI validation.
  • app/serializers.py applies the limit after filtering to contributors, pending_payouts, and recent while keeping totals over the full matching set.
  • Omitted limit preserves the existing default behavior: full contributor rows plus existing 100-row caps for pending/recent.
  • tests/test_activity.py covers valid limiting, combined q + limit, invalid non-integer input, and the 0 / 201 boundary validation cases added in the latest commit.

Validation run from an isolated PR worktree:

  • /Users/mycomputo/Documents/Codex/2026-05-31/goal-goal-find-and-execute-legitimate/work/repos/mergework/.venv/bin/python -m pytest tests/test_activity.py tests/test_activity_routes.py -q -> 7 passed, 1 warning
  • targeted Ruff check -> passed
  • targeted Ruff format check -> 3 files already formatted
  • mypy app/activity.py app/serializers.py -> passed
  • git diff --check origin/main...HEAD -> passed
  • git merge-tree --write-tree origin/main HEAD -> clean tree 4a080b04da1f487d37ab160a4fe65e009077e5fc
  • hosted Quality/readiness/docs/image check is successful on this head; CodeRabbit was still pending at review time.

Minor non-blocking note: the HTML page itself now accepts and applies limit; the existing “View JSON activity” link does not preserve limit, but that does not block the reported API correctness fix.

No private data, credentials, wallet material, production mutation, payout execution, exchange, bridge, cash-out, price claims, or fabricated payout claims used.

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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
tests/test_activity.py (2)

227-249: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Consider edge cases where limit equals or exceeds the dataset size.

The test proves valid limiting (limit=1), combined filtering+limiting (q+limit=2), and boundary validation (0, 201). Adding cases for limit=3 (exact dataset size) and limit=100 (exceeds dataset) would verify the implementation gracefully handles these realistic scenarios without error.

Proposed additions
     limited = client.get("/api/v1/activity?limit=1")
     filtered_limited = client.get("/api/v1/activity?q=github&limit=2")
+    exact_size = client.get("/api/v1/activity?limit=3")
+    exceeds_size = client.get("/api/v1/activity?limit=100")
     invalid = client.get("/api/v1/activity?limit=notanint")
@@
     assert len(filtered_payload["contributors"]) == 2
     assert len(filtered_payload["recent"]) == 2
 
+    assert exact_size.status_code == 200
+    exact_payload = exact_size.json()
+    assert len(exact_payload["contributors"]) == 3
+    assert len(exact_payload["recent"]) == 3
+
+    assert exceeds_size.status_code == 200
+    exceeds_payload = exceeds_size.json()
+    assert len(exceeds_payload["contributors"]) == 3
+    assert len(exceeds_payload["recent"]) == 3
+
     assert invalid.status_code == 422

201-242: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Verify that pending_payouts is also subject to limiting.

The test proves contributors and recent are constrained by the limit parameter, but pending_payouts cannot be verified because the test setup contains no pending proposals. Line 242 only confirms an empty list remains empty. Consider adding one or two pending proposals to the setup to prove all three arrays mentioned in the serializer contract are properly limited.

Example setup addition

After creating the bounty and before the pay_bounty loop, add:

from app.treasury import propose_treasury_action

pending_bounty = create_bounty(
    session,
    repo="ramimbo/mergework", 
    issue_number=657,
    issue_url="https://github.com/ramimbo/mergework/issues/657",
    title="Pending limit test",
    reward_mrwk="50",
    acceptance="Pending payouts should also respect limit.",
)
propose_treasury_action(
    session,
    action="pay_bounty",
    payload={
        "bounty_id": pending_bounty.id,
        "to_account": "github:alice",
        "submission_url": "https://github.com/ramimbo/mergework/pull/657",
        "accepted_by": "maintainer",
    },
    proposed_by="maintainer",
)
propose_treasury_action(
    session,
    action="pay_bounty", 
    payload={
        "bounty_id": pending_bounty.id,
        "to_account": "github:bob",
        "submission_url": "https://github.com/ramimbo/mergework/pull/658",
        "accepted_by": "maintainer",
    },
    proposed_by="maintainer",
)

Then update line 242:

-    assert len(limited_payload["pending_payouts"]) == 0
+    assert len(limited_payload["pending_payouts"]) == 1

As per coding guidelines for tests/**/*.py: "Focus on whether tests prove the changed behavior and include negative, replay, boundary, or regression cases where relevant."


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 352eef96-2435-441b-85ab-44e3d43e937a

📥 Commits

Reviewing files that changed from the base of the PR and between 1cf9959 and 4f708a9.

📒 Files selected for processing (1)
  • tests/test_activity.py

Copy link
Copy Markdown
Contributor

@attaboy11 attaboy11 left a comment

Choose a reason for hiding this comment

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

Reviewed updated PR #751 head 64147ac5e2388c410ea4a8a8802c34909b082589 after the author added docs, page-link preservation, default limit echoing, and the CodeRabbit-suggested edge-case coverage.

No blocking issue found in the updated activity limit implementation.

What I checked:

  • limit now defaults to 100 and is echoed in the activity API payload.
  • /activity preserves non-default limit in its “View JSON activity” link.
  • The serializer caps contributors, pending_payouts, and recent while preserving full-set totals.
  • The new tests cover pending-payout limiting, exact-size and exceeds-size limits, docs examples, and default empty-feed shape.
  • The follow-up diff from my earlier reviewed head 4f708a9 to 64147ac is limited to activity route/serializer/template/docs/tests.

Validation from the isolated PR worktree:

  • full suite: /Users/mycomputo/Documents/Codex/2026-05-31/goal-goal-find-and-execute-legitimate/work/repos/mergework/.venv/bin/python -m pytest -q -> 593 passed, 1 warning
  • targeted pytest: tests/test_activity.py tests/test_activity_routes.py tests/test_docs_public_urls.py::test_api_examples_document_activity_limit tests/test_serializers.py::test_activity_serializers_skip_malformed_public_proofs -> 9 passed, 1 warning
  • targeted Ruff check -> passed
  • targeted Ruff format check -> 6 files already formatted
  • mypy app/activity.py app/serializers.py -> passed
  • git diff --check origin/main...HEAD -> passed
  • git merge-tree --write-tree origin/main HEAD -> clean tree be7af5696f8802440d58014851266b674702ceab
  • hosted Quality/readiness/docs/image is successful on this head; CodeRabbit was still pending at review time.

No private data, credentials, wallet material, production mutation, payout execution, exchange, bridge, cash-out, price claims, or fabricated payout claims used.

@Jorel97
Copy link
Copy Markdown
Contributor Author

Jorel97 commented Jun 1, 2026

Scope sanity for the latest head 64147ac5e2388c410ea4a8a8802c34909b082589 after the earlier CodeRabbit bounty-focus warning:

  • PR body includes /claim #656 and the MRWK bounty reference/report link.
  • Current changed files are limited to the activity limit scope: app/activity.py, app/serializers.py, app/templates/activity.html, docs/api-examples.md, and focused activity/docs/serializer tests.
  • The latest CodeRabbit review reports no actionable comments and both hosted checks are successful.
  • No treasury, account, payout, wallet, transfer, proof, exchange, bridge, cash-out, price, or private-data behavior is changed.

This is intended to make the current scope easy to verify without relying on the stale earlier warning text.

Copy link
Copy Markdown
Contributor

@prettyboyvic prettyboyvic 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 64147ac5e2388c410ea4a8a8802c34909b082589 as a non-author against refreshed origin/main 9792898ea3ee754490ccb4abb9f2ecebe0759777.

The activity limit implementation still looks focused and healthy on its own, but the PR now needs a current-main refresh before it can merge:

  • GitHub reports mergeStateStatus: DIRTY for PR #751.
  • git merge-tree --write-tree origin/main refs/remotes/origin/pr-751 exits non-zero with content conflicts in app/activity.py and tests/test_activity.py.
  • The conflict is real integration work: current main added activity q control-character rejection in app/activity.py, plus UTC-explicit activity timestamp expectations in tests/test_activity.py; this PR adds the activity limit route/serializer behavior and related tests in the same areas.
  • The earlier approval was valid for the then-current base, but it used origin/main 05faf1f89932d59f2935e83b71fc42ffef363c7f; the current base has moved since then.

What I inspected:

  • app/activity.py, app/serializers.py, app/templates/activity.html, docs/api-examples.md, tests/test_activity.py, tests/test_activity_routes.py, tests/test_docs_public_urls.py, and tests/test_serializers.py.
  • The current-main activity changes from merge base 05faf1f89932d59f2935e83b71fc42ffef363c7f to 9792898ea3ee754490ccb4abb9f2ecebe0759777.

Branch-local validation on the PR head still passes:

  • uv run --extra dev python -m pytest tests/test_activity.py tests/test_activity_routes.py tests/test_serializers.py::test_activity_serializers_skip_malformed_public_proofs tests/test_docs_public_urls.py::test_api_examples_document_activity_limit -q -> 9 passed, 1 warning.
  • uv run --extra dev ruff check app/activity.py app/serializers.py tests/test_activity.py tests/test_activity_routes.py tests/test_serializers.py tests/test_docs_public_urls.py -> passed.
  • uv run --extra dev ruff format --check app/activity.py app/serializers.py tests/test_activity.py tests/test_activity_routes.py tests/test_serializers.py tests/test_docs_public_urls.py -> 6 files already formatted.
  • uv run --extra dev python -m mypy app/activity.py app/serializers.py -> success.
  • git diff --check origin/main...HEAD -> clean.
  • Hosted Quality/readiness/docs/image and CodeRabbit are successful on the reviewed head.

Suggested path: rebase or merge current main, resolve app/activity.py so it preserves both raw q control-character rejection and the new bounded limit parameter, then update tests/test_activity.py without losing the UTC timestamp assertions or the activity-limit coverage. After that, rerun the targeted activity/docs/serializer tests plus Ruff/mypy.

No private data, credentials, wallet material, production mutation, payout execution, ledger mutation, 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.

REQUEST CHANGES — reviewed current open head 64147ac5e2388c410ea4a8a8802c34909b082589 against current origin/main f8fc36265ea763bcaabb3555d3ee4e0c885a4953 as a non-author.

The activity limit behavior still validates on the branch head, but this PR is not merge-ready against current main.

Evidence checked:

  • Files inspected: app/activity.py, app/serializers.py, app/templates/activity.html, docs/api-examples.md, tests/test_activity.py, tests/test_activity_routes.py, tests/test_docs_public_urls.py, and tests/test_serializers.py.
  • Branch-local focused validation passes: .venv/bin/python -m pytest tests/test_activity.py tests/test_activity_routes.py tests/test_serializers.py tests/test_docs_public_urls.py -q -> 49 passed, 1 warning.
  • Docs smoke passes: .venv/bin/python scripts/docs_smoke.py -> docs smoke ok.
  • Ruff passes: .venv/bin/ruff check app/activity.py app/serializers.py tests/test_activity.py tests/test_activity_routes.py tests/test_serializers.py tests/test_docs_public_urls.py -> all checks passed; format check reports 6 files already formatted.
  • git diff --check origin/main...HEAD is clean.
  • Current-base mergeability is blocked: git merge-tree --write-tree origin/main HEAD exits non-zero with content conflicts in app/activity.py and tests/test_activity.py.
  • GitHub reports mergeable=false / mergeable_state=dirty; CodeRabbit and the hosted quality/readiness/docs/image check are success on the branch head.

Requested follow-up: rebase or merge current main, resolve the activity route/test conflicts, then rerun the focused activity/docs/serializer tests and Ruff checks.

@MyTH-zyxeon
Copy link
Copy Markdown

Reviewed current head 64147ac5e2388c410ea4a8a8802c34909b082589 as a non-author review for the #654 review bounty.

Requesting changes until the current-main conflict is resolved.

Evidence checked:

  • Inspected app/activity.py, app/serializers.py, app/templates/activity.html, docs/api-examples.md, tests/test_activity.py, tests/test_activity_routes.py, tests/test_docs_public_urls.py, and tests/test_serializers.py.
  • Confirmed the branch-head behavior is focused: it adds an activity limit query parameter, caps contributors, pending_payouts, and recent, preserves full totals, preserves the filtered page JSON link, and documents the 1..200 range.
  • Checked PR metadata at this head: GitHub reports mergeable=CONFLICTING / mergeStateStatus=DIRTY, while the hosted Quality, readiness, docs, and image checks is SUCCESS.
  • Ran read-only production probes against https://mrwk.online: current production /api/v1/activity?limit=1, ?limit=201, and ?limit=notanint all still return HTTP 200 without a limit key; the returned arrays stay at the current default shape (contributors 146, recent 100, pending_payouts 13 in this probe). That confirms the PR addresses a live public activity-feed bounding gap.
  • The merge blocker is still current-main integration, not the branch-local activity-limit behavior: current main has overlapping activity route/test changes, and the PR needs a refresh that preserves both the newer q validation / timestamp expectations and the new bounded limit behavior.

Suggested follow-up: refresh against current main, resolve app/activity.py and tests/test_activity.py, then rerun the focused activity/docs/serializer tests plus Ruff/mypy. Keep the live behavior contract from this PR: limit defaults to 100, accepts only 1..200, caps contributors, pending_payouts, and recent, and does not shrink the aggregate totals.

No private data, credentials, wallet material, production mutation, payout/proof/ledger execution, exchange, bridge, cash-out, live trading, local code mutation, git command, or worktree change was used.

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.

5 participants