# Add Pagination to a Vapor API from a Linear Issue

Yes. An agent picks up the Linear issue, paginates GET /todos in your Vapor API with Fluent, runs swift test and opens a pull request.

[Run this on Rush](https://cloud.getrush.ai/run/add-todo-pagination/vapor/), in a Project that has your repository.

## What the agent does

The agent starts from the Linear issue and the repository in its own sandbox, and reads the Todo API as shipped. In a tree like vapor/template with Fluent enabled, `Sources/App/Controllers/TodoController.swift` registers `GET /todos`, `POST /todos` and `DELETE /todos/:todoID`. The index action is `Todo.query(on: req.db).all().map { $0.toDTO() }`, returning `[TodoDTO]` with no page metadata. `TodoDTO` carries `id` and `title`. The template's `Tests/AppTests/AppTests.swift` includes a "Getting all the Todos" test that decodes `[TodoDTO]` after seeding two rows.

It changes `index` to use Fluent's `paginate(for: req)` (honouring `page` and `per` query parameters) and returns the page's items plus metadata (page, per, total) as JSON. It updates `TodoDTO` or introduces a small page wrapper type so clients can read metadata without breaking field names on each todo. Delete and create stay as they are.

It rewrites the get-all test to assert a paginated payload, and adds cases for `?page=` / `?per=` boundaries (empty page, per capped). It runs `swift test` in the sandbox with the template's SQLite or configured database, fixing any Sendable or async test helper issues the Swift testing macros surface.

Last, it opens a pull request that links the Linear issue, shows the new response shape and the updated AppTests cases, and points at the `swift test` transcript.

## Start it with one API call

`POST https://api.prix.dev/o/{org}/sessions`

```json
{
  "agent": "claude",
  "input": "A Linear issue labeled agent says: \"Add Pagination to a Vapor API. Make GET /todos return a page of results with Fluent's paginate, with page and per query parameters and the page metadata in the response.\" Do the work in this repository, add tests for it, run swift test, and open a pull request that links back to the issue.",
  "resources": [
    {
      "url": "https://github.com/your-org/your-app"
    }
  ]
}
```

1. **Get an API key.** In the console, open Settings, then API keys, and create a key for your org. Send it in the Authorization header as a Bearer token.
2. **Send the request.** POST the body in request.json to https://api.prix.dev/o/{org}/sessions, with your repository as the resources URL. The run starts in its own cloud sandbox.
3. **Read what came back.** Follow the run on its live stream or wait for the run.completed webhook, then read the result and its trajectory.

## What comes back

What comes back is a pull request on its own branch. The description explains that `GET /todos` returned the full array, then shows the Fluent paginate call, query parameters and metadata fields. The Linear issue is linked.

The transcript keeps `swift test` (resolve, build, test) with full output. A broken Content conformance or migration shows up there before review.

Before merging, a reviewer checks default `per` limits, that clients still receive todo `id`/`title`, that invalid page values error cleanly and that the new tests fail if `paginate` is reverted to `.all()`.

## Run it on every Linear issue labelled agent

In the console, an automation with a `linear` trigger on `linear.issue.labeled` and the label `agent` starts one run per labelled issue, with the issue as its context, in the Project's repository. Changes made by an app integration never fire it, so the agent's own updates do not start new runs.

From your own server, the same run is one `POST /o/{org}/sessions` per issue: put the repository in `resources`, and add the issue's `https://linear.app/<workspace>/issue/<ID>` URL there too to have Rush read it through your Linear connection into the prompt. A webhook on the API key posts `run.completed` or `run.failed` when the turn finishes, with the `session_url` to read the result.

## Why run it on Rush?

Vapor and Fluent pagination need a real test Application with migrations (`autoMigrate` / `autoRevert` in the template's test helper). In a Rush sandbox the agent runs `swift test` on Linux with that lifecycle and keeps the log, so reviewers do not need a local Swift toolchain to trust the change.

A Linear label becomes a small API PR with tests. Several Vapor issues can run in parallel sandboxes under the key's `max_concurrent` limit, each with its own branch and transcript.

## Frequently asked questions

### Is the response still a bare JSON array?

No. Pagination needs metadata, so the agent returns an object with items and page fields (or Fluent's page Content shape). The PR documents the new schema so clients can update.

### Which query parameter names?

Fluent's defaults: `page` and `per`. The agent sticks to those unless the issue names aliases.

### Does POST /todos change?

No. Only `GET /todos` gains pagination. Create and delete keep their existing status codes and bodies.

### Will existing clients break?

Clients that decode a top-level array need a one-line update to the new envelope. The PR calls that out so API consumers are not surprised.
