# Fix Jira Bug Tickets With Pull Requests in a Next.js App

Yes. An agent reads the Jira bug through the Atlassian connection, reproduces it in your Next.js team or billing code, opens a pull request and comments the link.

[Run this on Rush](https://cloud.getrush.ai/run/fix-jira-bugs/nextjs/), in a Project that has your repository.

## What the agent does

The agent reads the ticket key and summary after the prompt, then fetches the full issue, its description and every comment through the Atlassian connection. Bug tickets written by support rarely name a file, so it reads for the user-visible symptom: a team member who could not be removed, a checkout that sent someone back to pricing, a subscription that stayed on the old plan after Stripe changed it.

In a Next.js app like nextjs/saas-starter that symptom maps to a small set of files. `package.json` pins `next` to 15.6.0-canary.59 with React 19.1, `drizzle-orm`, `postgres`, `stripe`, `jose` and `zod`, with a `pnpm-lock.yaml` and no test runner at all. The team code is the server actions in `app/(login)/actions.ts`, `inviteTeamMember`, `removeTeamMember`, `updateAccount`, `updatePassword` and `deleteAccount`, each wrapped in `validatedActionWithUser` from `lib/auth/middleware.ts`, plus `app/api/team/route.ts`, which returns `getTeamForUser()` from `lib/db/queries.ts`. The tables are `users`, `teams`, `teamMembers`, `activityLogs` and `invitations` in `lib/db/schema.ts`.

The billing code is `lib/payments/stripe.ts` and `lib/payments/actions.ts`. `checkoutAction` and `customerPortalAction` are `withTeam` actions; `createCheckoutSession` redirects to `/sign-up` when there is no team or user and otherwise creates a subscription checkout with a 14-day trial and a `client_reference_id` of the user id; `app/api/stripe/checkout/route.ts` reads that session back, expands customer and subscription and throws when either is missing; and `app/api/stripe/webhook/route.ts` verifies the Stripe signature and passes `customer.subscription.updated` and `deleted` to `handleSubscriptionChange`, which writes `planName`, `stripeProductId` and `subscriptionStatus` through `updateTeamSubscription`. Each `throw new Error` in that path is a place a ticket can originate.

Because the repository has no tests, the agent adds Vitest as a dev dependency with a minimal `vitest.config.ts`, writes one test that calls the action or handler with the inputs the ticket describes, with `getUser`, `db` or `stripe` stubbed, and watches it fail. Then it changes the code until `npx vitest run` passes, runs `pnpm build` so the Next.js type check runs, and opens a pull request whose title starts with the ticket key. Last, it comments the pull request link on the Jira issue through the same connection.

## Start it with one API call

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

```json
{
  "agent": "claude",
  "input": "A Jira bug ticket was created; its key and summary follow this prompt. Use the Atlassian connection to read the ticket, its description and all comments. Find the code the report describes in the team actions (app/(login)/actions.ts, app/api/team/route.ts, lib/db/queries.ts) or the billing code (lib/payments/stripe.ts, lib/payments/actions.ts, app/api/stripe/checkout/route.ts, app/api/stripe/webhook/route.ts). This repository has no test runner: add vitest as a dev dependency with a minimal vitest.config.ts, write one test that reproduces the ticket with getUser, db and stripe stubbed, and confirm it fails. Fix the cause, not the symptom, until npx vitest run passes, then run pnpm build. Open a pull request whose title starts with the ticket key and whose description quotes the failing test output, and comment the pull request link on the ticket. If you cannot reproduce the bug, comment on the ticket with what you tried and open no pull request.",
  "connections": [
    "atlassian"
  ],
  "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 named after the ticket key. In a saas-starter shaped app it usually changes one action in `app/(login)/actions.ts` or one function in `lib/payments/stripe.ts`, adds a test file beside it, and adds `vitest` plus `vitest.config.ts` if the repository had none. The description restates the ticket in one line, names the file and function at fault, quotes the test output before and after, and lists the commands it ran, `npx vitest run` and `pnpm build`.

The reviewer checks that the test exercises the real action and not a copy of it, that any stub of `stripe` or `db` returns a shape the real client would return, and that the change leaves the other actions alone; a fix in `handleSubscriptionChange` must not alter what `createCheckoutSession` does. A Stripe-related change also deserves a look at whether the webhook path still answers 400 on a bad signature.

On the Jira side the ticket gains one comment with the pull request link and a one-sentence cause. Nothing else on the ticket changes: no transition, no assignee, so the team's workflow decides when it moves to done.

## Run it on every new Jira bug

Create a Jira automation rule with the trigger "Work item created", a condition that the issue type is Bug, and the action "Send web request" to a handler on your server with `{{issue.key}}` and `{{issue.summary}}` in the body. The handler appends them after the prompt, names your Atlassian connection in `connections`, sends the ticket key as `Idempotency-Key` and calls `POST /o/{org}/sessions` once per ticket. Jira cannot call a Rush `webhook` trigger itself, because the trigger needs `Authorization: Bearer` with its secret.

With a webhook URL on the API key, Rush POSTs `run.completed` or `run.failed` with the `session_url` when the turn finishes, so the handler can add a second Jira comment if the agent stopped without a pull request. A key runs at most `max_concurrent` sessions at once and answers 429 past that, which is the ceiling for a bug-bash afternoon.

## Why run it on Rush?

Reproducing a billing bug on a laptop means a local Postgres, a Stripe test key, a webhook forwarder and a browser, and most tickets are abandoned at that step. The agent sets that up in its own sandbox each time, from `pnpm install` through `pnpm db:migrate`, and the engineer only reads the pull request. Ten tickets from a triage session can be ten sessions.

The pull request carries proof rather than a promise: the transcript shows the test failing before the change and passing after, and the `pnpm build` output that the type check ran. Because Vitest is added in the same pull request, the next ticket starts with a test runner already in place.

## Frequently asked questions

### The repository has no tests. Is adding Vitest in a bug-fix pull request acceptable?

It is the smallest honest way to show the bug existed. The pull request adds `vitest` as a dev dependency, one config file and one test file; nothing else in the toolchain changes. If you would rather keep that separate, say so in the prompt and the agent reproduces the bug with a script instead.

### How does the agent read Jira?

Through the Atlassian connection named in `connections`, which is the Atlassian remote MCP server signed in as you. It reads the issue and its comments, and at the end posts one comment with the pull request link. It changes no fields and performs no transition.

### Can it call Stripe?

Not in the test. `stripe` from `lib/payments/stripe.ts` is stubbed so the test runs without a key and without network. If the fix needs a real Stripe object shape, the agent reads the `Stripe.Subscription` and `Stripe.Checkout.Session` types the `stripe` package ships and builds the stub from them.

### What if the ticket is not a bug in this code?

The agent comments on the ticket with what it tried, for example that `removeTeamMember` behaves as described only when the caller has no team, and opens no pull request. The run's result says the same, so the handler can route the ticket back to a person.

### Will it touch the database migrations?

Only if the cause is in the schema, which is rare for a bug ticket. If it must, the pull request includes a new file under `lib/db/migrations/` generated with `pnpm db:generate` and says so in the description, so the reviewer can plan the deploy.
