Skip to content

feat(automations): filter the automations list by creator - #539

Open
henriquehirako wants to merge 5 commits into
mainfrom
feat/list-automations-created-by-filter
Open

henriquehirako wants to merge 5 commits into
mainfrom
feat/list-automations-created-by-filter

Conversation

@henriquehirako

@henriquehirako henriquehirako commented Oct 1, 2026 •

Copy link
Copy Markdown

This PR was created by an AI agent (OpenHands) on behalf of the user.

Why

Agent Canvas is adding a "Created by" filter (Anyone / Me / Others) to the Automations list (OpenHands/OpenHands#17814). The list endpoint has no creator filter, so Canvas can only filter the rows it has already loaded. The list loads 50 at a time, newest first. In an org with more than 50 automations, "Me" checks only the newest 50: if none of them are the caller's, the user is told they have no automations when they do.

Summary

  • GET /api/automation/v1 takes an optional created_by query param: me keeps the caller's automations (Automation.user_id == user.user_id), others keeps the rest of the caller's org.
  • The filter applies before the count, so total and limit / offset paging cover only the matching automations. The org scope, the soft-delete filter, and the newest-first order do not change.
  • Without the param the response is the same as today. Any other value is a 422.
  • Automations imported by Git Sync belong to the admin who configured the sync, as for the existing creator checks. In local mode every automation has the one local user, so me returns all of them and others none.

Consumer: OpenHands/OpenHands#17814 sends created_by from the "Created by" filter. An automation service without this change ignores the unknown param, and Canvas keeps its client-side filter as the fallback.

How to Test

  1. uv run python -m pytest tests/test_router.py -k TestListAutomations. The new tests cover: no param lists every creator; me and others; two filtered pages keep the newest-first order with no duplicates, and total counts only the matches; an unknown value is a 422.
  2. End to end: run Agent Canvas on this checkout (OH_AUTOMATION_LOCAL_PATH=<this repo> npm run dev in OpenHands/OpenHands). Local mode has one user, so give some automations another user_id in the local SQLite DB. Results below.

What I ran:

Add an optional created_by query param to GET /api/automation/v1:
`me` keeps the caller's automations and `others` the rest of the org's.
The filter applies before counting, so `total` and offset paging cover
only the matching automations. Without the param the list is unchanged;
any other value is a 422.

Lets Agent Canvas filter "Created by" on the server instead of over the
page it has loaded.
Seed explicit created_at values so the creator-filter tests check the
newest-first order and that two pages hold no duplicates, and cover the
unfiltered list with both creators. Note in the docstring that Git Sync
imports belong to the admin who configured the sync.
@github-actions github-actions Bot added the type: feat A new feature label Oct 1, 2026
@github-actions

github-actions Bot commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Coverage

Warning

Your comment is too long (maximum is 65536 characters), so the coverage report was not added. See the job log for how to reduce it.

Give the no-filter case its own test with a shared seed helper, parse
each page once in the paging test, and drop the docstring line about
Git Sync ownership, which this endpoint does not decide.
The created_by branches read plainly in the code, so the docstring goes back to the original line.
The teammate's automation is the newer of the two, not the older.
@henriquehirako
henriquehirako marked this pull request as ready for review October 1, 2026 19:39
@henriquehirako
henriquehirako requested review from a team and hieptl and removed request for a team October 1, 2026 19:44

@all-hands-bot all-hands-bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This review was posted by an AI agent (OpenHands).

Review: feat(automations): filter the automations list by creator

Scope — Correct repository. The change extends GET /api/automation/v1 in the automation service, which is the component this repo owns (list endpoint, org scope, paging). The linked product requests are ready-for-dev: OpenHands/OpenHands#17816 and OpenHands/extensions#708. No product/architecture decision is pending.

What I verified on head 4384439

  • created_by is typed Literal["me", "others"] | None, so any other value is rejected with 422 by FastAPI validation, as documented and tested.
  • me / others add Automation.user_id == / != user.user_id to the base query, so the predicate runs inside the DB query, is applied before the count, and composes with the existing org_id + deleted_at IS NULL scope and the created_at DESC ordering. total and limit/offset therefore cover only the matching set — the stated bug (client-side filtering of the newest 50) is fixed at the correct layer.
  • With no param the query is byte-for-byte the previous behavior.
  • Automation.user_id is nullable=False and carries ix_automations_user_id, so the new predicate cannot miss NULL rows and is index-backed.
  • Consumer integration: Canvas builds the request via buildListQuery, which omits keys whose value is undefined; automations-list.tsx sets serverCreatedBy = createdByFilter !== "all" ? createdByFilter : undefined. "Anyone" sends no param (unfiltered), "Me"/"Others" send me/others — exactly the three accepted shapes. There is no path that sends all to the service, so the strict 422 cannot fire in normal use.
  • CI on the exact head: 8 checks passed, 2 skipped; no failures.

Tests — _seed_automation/_seed_mine_teammate_and_other_org cover unfiltered, me, others, filtered paging with total counting only matches, newest-first order, and the 422. Other-org exclusion is implicitly asserted (total == 2). I could not execute the suite here because it requires a Docker-backed PostgreSQL container and Docker is unavailable in this sandbox; CI unit-tests is green on this head, and the new tests read as correct against the implementation.

Non-blocking note — With created_by=me, an automation whose user_id differs from the caller is invisible to a member; admins/owners likewise cannot find another member's automation under "Me". That matches the stated product intent (automations imported by Git Sync belong to the configured admin), so it is not a blocker.

No blocking bugs, security problems, or design flaws found.

✅ APPROVED

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: feat A new feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants