Here is a question worth sitting with. What happens if you connect the same repository twice? Maybe the user clicks "Connect" twice because the first click felt slow. Maybe the network hiccuped and the request was retried. Maybe a webhook redelivered an event GitHub already sent. In a naive system, the second run duplicates every pull request and doubles everyone's XP. In ours, nothing bad happens: run it again and the result is the same. That property has a name, idempotency, and the importer earns it with two different techniques for two different kinds of work.
The write: upsert
When the importer processes a pull request, it does not blindly create a row. It upserts. Upsert is a portmanteau of update and insert: "if a row like this already exists, update it in place; otherwise create it." The trick is choosing the right key to decide "a row like this". Ours is the pair (repoId, githubId), the repo plus GitHub's own PR number, which is unique and stable. So on a reimport, PR #42 does not become a second PR #42; it finds the existing row and refreshes it.
await prisma.pullRequest.upsert({
where: { repoId_githubId: { repoId, githubId: pull.number } },
update: { title, state, additions, deletions /* ... */ },
create: { /* the full row */ },
});
That one word, upsert, is why reimporting is safe for the data. The rows converge to the same state no matter how many times you run it. This is the first lesson: give your records a natural key and write through it, so a repeated write changes nothing rather than duplicating.
The side effect: a guard
But data is not the only thing an import does. When a pull request is merged, we award XP. That is a side effect, and side effects do not get idempotency for free. The upsert protects the PR row, but if the merge handler ran twice it would happily award the merge bonus twice, and someone's score would drift upward every time an event redelivered.
So awarding XP needs its own guard. Before paying the merge bonus, the importer asks the ledger a question: has this pull request already earned its merge XP?
const alreadyAwarded = await prisma.xPTransaction.findFirst({
where: { pullRequestId: prRow.id, reason: 'PR_MERGED' },
});
if (!alreadyAwarded) {
await awardXP({ /* PR_MERGED, and the right sized bonus */ });
}
The ledger row is not just a record of the payment; it is the guard. Its existence means "this already happened, do not do it again." This is exactly once from at least once machinery: the event may arrive many times, but the effect lands once.
The lesson
The two halves are the whole point. A robust operation separates the work into:
- Idempotent writes, made safe by a natural key and an upsert. Run them a hundred times, same result.
- Side effects, made safe by an explicit guard that records "done" and is checked before acting.
The mindset to carry into your own code: assume it will run twice. Networks retry, users double click, queues redeliver, cron overlaps. If your operation would misbehave on a second run, it has a bug that has not happened yet. Make the writes idempotent, guard the side effects, and you can hand someone a "Connect" button without fear of what a nervous second click will do.

