back to all notes

backend2 min read

Serverless D1 Fulfillment Engine

For Apptork Labs, I wanted a purchase to lead to private GitHub repository access without sending each invitation manually. I used a Nuxt 3/Nitro API route, Lemon Squeezy license validation, the GitHub API, and Cloudflare D1 to record activations.

The implementation is an internal Apptork Labs deployment.

Activation flow

The client sends a license_key and github_username to POST /api/activate.

The route checks env.DB for an existing activation. If the license is recorded against a different GitHub username, it returns a 400 response. If both values match, it skips another Lemon Squeezy validation call and re-sends the repository invitation.

For a new activation, it validates the license through Lemon Squeezy and maps the product_id to the relevant GitHub repositories. That mapping also handles bundles and user-selected repository preferences. It sends collaborator invitations through GitHub and records the license, username, repositories, and activation time in D1. The note does not show the ordering or failure handling of those last two steps.

D1 provides a SQLite-compatible store in the Cloudflare runtime, without a Node-bound SQLite dependency. The license-to-username association is a database rule, not a cryptographic binding or proof that the caller owns the GitHub account.

Skipping revalidation for a recorded match saves an external request. It also means that this path alone does not check whether a license has since been revoked.

Deployment

Create the table:

npx wrangler d1 execute apptork-boilerplate-licenses --command "CREATE TABLE IF NOT EXISTS license_activations (license_key TEXT PRIMARY KEY, github_username TEXT NOT NULL, repos TEXT NOT NULL, activated_at TEXT DEFAULT CURRENT_TIMESTAMP);" --remote

Bind the apptork-boilerplate-licenses database as DB. For the Pages deployment described here, the binding is under Pages > Settings > Functions > D1 database bindings. Check the deployment's Wrangler configuration and dashboard settings; a local binding does not by itself establish the production binding.

Configure GITHUB_TOKEN and LEMON_SQUEEZY_API_KEY as secrets. The GitHub credential needs permission to invite collaborators to the target private repositories; the exact permissions depend on the token type.

The database record does not make the Lemon Squeezy, GitHub, and D1 operations one atomic transaction. Failure handling and concurrent activation checks need review separately.