All jobs

Find Untested Code in a Next.js App

Yes. An agent runs your Next.js test suite with coverage in its own sandbox and reports the riskiest untested code, without changing anything.

What the agent does

The agent clones the app into its own cloud sandbox and reads how it tests before it runs anything. In an app like umami-software/umami, package.json pins pnpm 12 and Next.js 16 with Prisma 7, names a test script of vitest run, and declares a pretest of pnpm generate:db:client that runs prisma generate first. vitest.config.ts includes src/**/*.test.{ts,tsx} and sets a jsdom environment with src/test/setup.ts. The agent installs with pnpm, runs prisma generate, and runs the suite with the V8 coverage reporter so the numbers come from a real run rather than a guess.

With the coverage report in hand it reads the source behind the numbers. Umami has tests for helpers in src/lib/ and for its permission checks in src/permissions/, but its API route handlers are far thinner: of the route files under src/app/api/, only a fraction have a neighbouring route.test.ts, and whole areas like src/app/api/boards/, src/app/api/users/, src/app/api/share/ and most of src/app/api/websites/ have none. The Prisma query files under src/queries/prisma/ and the SQL builders under src/queries/sql/ are mostly untested too. The agent lists each file with uncovered lines and keeps the ones that matter: a route that writes data or checks a session, over a presentational component.

It ranks the gaps the prompt asks for by how much depends on them. Route handlers that authenticate a request, query files that every report calls, and the auth and session helpers rise to the top; a chart component or a formatting helper with a constant output falls to the bottom. For each of the ten it writes one sentence naming the test that would cover it: a route test that asserts a 401 for an unauthenticated caller and the shape of a successful response, a query test that checks the filter it builds, a permission test for the branch that denies access.

The prompt says to change no code, so the agent runs the suite and reads the report but writes no tests and opens no pull request. The install, the prisma generate step, the coverage run and the ranking all stay in the session transcript, and the result is coverage-gaps.md returned as an artifact on the session. Umami has real tests over large untested areas, so the report has to separate what is covered from what is not rather than declaring the whole app untested.

Start it with one API call

POST https://api.prix.dev/o/{org}/sessions with this body:

{
  "agent": "claude",
  "input": "Clone https://github.com/umami-software/umami, install with pnpm, run prisma generate, and run its test suite with coverage in the sandbox (vitest with the V8 coverage reporter). Write coverage-gaps.md: the overall coverage percentage, the ten files with the most uncovered lines that matter (data writes, auth, money), and one sentence each on what test would cover them. Rank them by how much other code depends on them. Change no code and open no pull request."
}
  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 coverage-gaps.md as an artifact on the session, which the session read returns with a download link good for an hour. It opens with the overall coverage percentage from the real vitest coverage run and the command that produced it, including the prisma generate step the suite needs, so a reader knows the number is measured rather than estimated. Then it lists the ten riskiest untested files, most depended-on first.

Each row names the file, the count of uncovered lines and which they are, says in one sentence what that code does and why its risk rank is what it is, and gives the one test that would cover it. Because umami already tests its helpers and permissions, the report's value is in surfacing the untested API routes and query builders under them, where a bug would reach real data.

A reviewer checks the report against the repository before acting on it: that the coverage number matches a run they do themselves, that the cited routes really lack tests, and that the risk ranking fits their own sense of what is dangerous in the app. Because the sandbox still holds the installed project, a follow-up message to the same session can ask the agent to write the top few route tests and open a pull request.

Run it on every Monday morning

Coverage in a Next.js app drifts a route handler at a time, so a weekly report catches it at a steady pace. A cron job on your server sends this request every Monday with the repository in the prompt, and the run measures vitest run --coverage against the app/api handlers and the Prisma queries they call, ranking the untested ones by how much traffic code they sit on.

When the run's run.completed webhook arrives with the session_url, your server takes coverage-gaps.md from the session's artifacts and posts the top five gaps to the team channel, so the week's test work starts from a list that names files rather than a percentage.

The use case this job follows, with its automation and trigger: Produce a report or file, no repo.

Why run it on Rush?

Running coverage on a Next.js app with Prisma on a laptop means installing with the right package manager, generating the Prisma client, and letting a large suite run, all while the machine is tied up. In a Rush sandbox the agent does the install, the prisma generate and the coverage run on its own disk, and the numbers and the ranking come back as a file you keep, with the commands that produced them beside each claim.

A coverage report is only useful if you trust the number and the priorities. Because the run and its output are in the session transcript, the person reading coverage-gaps.md can confirm the percentage and spot-check any route instead of taking it on faith. Several reports can run at once, one per application, up to the key's concurrent-run limit.

Frequently asked questions

Will it change anything in my repository?

No. The prompt says to change no code and open no pull request. The agent runs the suite with coverage and reads the report. What comes back is a Markdown report you download from the session's artifacts.

Does it need a database to run coverage?

Umami's suite runs a pretest that generates the Prisma client, which the agent runs. The unit tests the coverage reporter measures do not need a live database; the agent follows the project's own test scripts rather than standing up Postgres unless a test requires it.

My app already has some tests. Will it just say coverage is fine?

No. It separates what is covered from what is not and ranks only the untested code that matters, so even an app with a healthy helper suite gets a list of the untested routes and queries where a bug would reach real data.

Can it run against a private repository?

Yes. Install the Rush GitHub App on the repository and add it to the request as a resource, {"url": "https://github.com/your-org/your-app"}, instead of a public URL. The agent starts with that repository already cloned and runs its suite the same way.