All jobs

Add CSV Export to a Django App from a Linear Issue

Label a Linear issue and an agent adds a members-only CSV export of your project's checks to your Django app, with tests and a pull request.

Run this on RushIn a Project that has your repository.

What the agent does

The issue is concrete: an Export CSV button on the project's checks list that downloads every check with name, status, last ping and schedule, limited to the project's members. The run starts with the issue text in the prompt and the repository cloned; in healthchecks/healthchecks that is a production Django app on Django 6.1 with a large existing test suite, and the agent reads the models and the existing checks view before writing anything.

The fields the issue names all exist on the Check model in hc/api/models.py, including name, last_ping, schedule and kind, and the status worth exporting is the computed one: get_status() applies the grace logic to say up, down, new or paused rather than trusting the stored column. Membership is equally well defined. The Project model in hc/accounts/models.py has an owner and Member rows with roles, and hc/front/views.py already has the access pattern that encodes "limited to the project's members": _get_project_for_user fetches the project, gives the owner read-write, and otherwise requires a Member row. The agent reuses it for the new view instead of writing a second access check.

The checks list page it extends lives at hc/front/views.py's checks view under /projects//checks/, rendered by templates/front/checks.html with the table included from checks_table.html, and there is no CSV export anywhere in the codebase today. So the agent adds an export_checks view next to checks: decorated with login_required, gated through _get_project_for_user, streaming Check rows for the project through csv.writer into an HttpResponse with the text/csv content type and a filename that carries the project code. In templates/front/checks.html it adds the Export CSV button beside the existing bottom actions, as a plain link the view serves.

Tests follow the project's own conventions, which are strong: hc/test.py's BaseTestCase builds fixture users Alice, Bob and Charlie, and the front tests live in hc/front/tests/. The agent adds a test file there covering that a project member gets a 200 with a text/csv body and one row per check, that the columns carry name, computed status, last ping and schedule, and that someone with no membership gets a 404 rather than the file. Then it runs ./manage.py test hc.front against the sqlite test database the settings default to. The pull request it opens links back to the Linear issue.

Start it with one API call

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

{
  "agent": "claude",
  "input": "A Linear issue labeled agent says: \"Add CSV Export to a Django App. Add an Export CSV button on the project's checks list that downloads every check with name, status, last ping and schedule, limited to the project's members.\" Do the work in this repository, add tests for it, run python manage.py 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 diff is small and scoped: a new export_checks view in hc/front/views.py, one route added to the project's URL include in hc/front/urls.py, a button in templates/front/checks.html, and a new test file under hc/front/tests/. The CSV columns are the four the issue named, with status computed through get_status() so a check inside its grace period reports what the UI would show.

The pull request's description names the access decision explicitly: the view reuses _get_project_for_user, so owner and members download, everyone else gets a 404, and it says that ./manage.py test hc.front passed. The trajectory keeps the test run's output with the pass counts, and the commands that produced them.

Before merging, the reviewer opens the export on a project with a down check and a cron check, checks the status column against the page, confirms a non-member is refused, and skims the test file to see each case named. The button should read as part of the existing toolbar, not a new panel.

Run it on every Linear issue labeled agent

Set up the automation once in the console: a Linear trigger on linear.issue.labeled with the labels you choose, pointed at the Project whose repository the agent should work in. Labeling an issue then starts a run with the issue as its context, and the agent opens a pull request that links back, so a triaged issue becomes reviewable work without a developer picking it up by hand.

Changes made by an app integration never fire the trigger, so an agent's own pull requests cannot re-trigger the automation. The run works in the Project's repository with its secrets, such as the database settings the tests need; keep the agent label for issues described well enough to act on, and the automation's prompt tells the agent to ask on the issue when it is not.

The use case this job follows, with its automation and trigger: Turn a Linear label into a PR.

Why run it on Rush?

This issue is twenty minutes of reading for five minutes of writing: the access model, the computed status, the template structure and the test conventions all have to be right before the csv module gets involved. On Rush the agent does that reading in a sandbox with the repository checked out, follows the project's own patterns, and comes back with tests already run and recorded in the trajectory.

The pull request is the handoff. It links the issue, the description names the access check reused and the suite that passed, and the trajectory keeps the commands, so review is a read, not a re-run. Because the trigger fires per label, a backlog of small well-described issues drains into pull requests one at a time, each held at review until a person merges.

Frequently asked questions

Does the export respect project membership?

Yes. The view reuses _get_project_for_user, the same helper the checks page itself uses: the project owner and members get the file, anyone else gets a 404. The tests assert both sides, including a user who is a member of a different project.

Which status value lands in the CSV?

The computed one. Check.get_status() applies the grace and started logic the UI uses, so a check that is late but inside grace reports the same thing the page shows, not the raw stored column.

Will it export tags, descriptions or ping history too?

Only what the issue named: name, status, last ping and schedule. Extra columns are one sentence in the issue away, but the default diff stays as small as the request that produced it.

What database do the tests run against?

The settings default to sqlite, so ./manage.py test runs the new tests out of the box without a database service. The CI matrix already covers postgres and mysql for the suite as a whole.

What if the issue is not specific enough to implement?

The automation's prompt tells the agent to ask on the issue rather than guess. The run stops with needs-you and the question, and no pull request opens until a person answers.