Skip to content

Add slow-query warning custom middleware example to prisma-next-demo#912

Merged
aqrln merged 2 commits into
mainfrom
examples/extensions-middleware-docs
Jul 7, 2026
Merged

Add slow-query warning custom middleware example to prisma-next-demo#912
aqrln merged 2 commits into
mainfrom
examples/extensions-middleware-docs

Conversation

@sorenbs

@sorenbs sorenbs commented Jul 3, 2026

Copy link
Copy Markdown
Member

Linked issue

n/a — companion example for the Prisma Next user docs Middleware section. The docs PR that embeds this example is prisma/web#8008; tracking for the docs work lives in the docs Linear project, and there is no framework ticket for this change.

At a glance

// examples/prisma-next-demo/src/prisma/slow-query-warning.ts
export function slowQueryWarning(options?: SlowQueryWarningOptions): SqlMiddleware {
  const thresholdMs = options?.thresholdMs ?? 250;

  return {
    name: 'slow-query-warning',
    familyId: 'sql',

    async afterExecute(plan, result, ctx) {
      if (result.latencyMs <= thresholdMs) return;
      ctx.log.warn({
        code: 'APP.SLOW_QUERY',
        message: `Query took ${result.latencyMs}ms (threshold: ${thresholdMs}ms)`,
        details: {
          sql: plan.sql,
          rowCount: result.rowCount,
          latencyMs: result.latencyMs,
          source: result.source,
          planExecutionId: ctx.planExecutionId,
        },
      });
    },
  };
}

Before this PR, prisma-next-demo registered only built-in middleware (cache, lints, budgets); the repo had no example of authoring a middleware from scratch.

Summary

This PR ships the canonical custom-middleware example: a slowQueryWarning observer in prisma-next-demo, registered on the demo runtime and covered by offline unit tests. The new Prisma Next docs page "Authoring custom middleware" (prisma/web#8008) embeds this file verbatim, so the doc example is code that compiles and has tests behind it.

How it fits together

  1. The example (examples/prisma-next-demo/src/prisma/slow-query-warning.ts) is a plain object literal typed as SqlMiddleware, so contextual typing infers every hook's parameters and the example needs no deep type imports. It implements only afterExecute and warns through ctx.log when result.latencyMs crosses the threshold.
  2. The wiring (examples/prisma-next-demo/src/prisma/db.ts) registers it at the end of the existing chain, with a comment noting that cache hits flow through it too, reporting source: 'middleware'.
  3. The tests (examples/prisma-next-demo/test/slow-query-warning.test.ts) drive afterExecute directly, no database required: a real DSL build() supplies the plan's ast and meta, and a hand-built SqlMiddlewareContext captures log.warn events. Three cases: warns above the threshold, silent at the threshold, and the 250ms default.

Reviewer notes

  • The built-ins wrap their middleware in Object.freeze(...) and annotate hook parameters explicitly; this example deliberately returns a plain literal instead, because the docs page teaches the minimal authoring shape and contextual typing from the SqlMiddleware return type keeps it fully typed.
  • The test constructs the context and result objects structurally (no casts); db.contract supplies a real contract and the plan's ast/meta come from a real DSL build, so the shapes stay honest to what the runtime passes.
  • The docs page in docs: add Prisma Next Middleware and Extensions sections web#8008 embeds slow-query-warning.ts verbatim. If this file changes shape later, the docs page needs the same edit.

Behavior changes & evidence

Testing performed

  • pnpm --filter prisma-next-demo typecheck
  • pnpm --filter prisma-next-demo exec vitest run slow-query-warning — 3 passed
  • biome check on the three touched files (also enforced by lint-staged on commit)

Skill update

n/a — example-only change; no CLI, public API, config, or error-code surface changed.

Alternatives considered

  • Throwing on slow queries instead of warning. The budgets built-in already demonstrates enforcement (BUDGET.TIME_EXCEEDED); the example's job is to show a pure observer, which is the more common authoring starting point, so it warns and never fails the query.
  • Placing the example next to the rewriting-middleware integration test. Kept in examples/prisma-next-demo instead, so the docs can link one runnable app that shows built-ins, an extension, and a custom middleware together, where users actually look first.

Checklist

  • All commits are signed off (git commit -s) per the DCO.
  • I read CONTRIBUTING.md and the change is scoped to one logical concern.
  • Tests are updated.
  • The PR title is in TML-NNNN: <sentence-case title> form — no framework Linear ticket exists for this companion-example work, so the title names the deliverable directly.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added slow-query warning middleware to the Prisma Next demo.
    • Warnings are emitted when observed query latency exceeds a configurable threshold, with a built-in default.
  • Tests
    • Added offline unit tests covering warning emission, exact-threshold behavior, and the default threshold.
  • Documentation
    • Updated the Prisma Next upgrade instructions to note this example-only addition and that it requires no action from consumers.

@sorenbs sorenbs requested a review from a team as a code owner July 3, 2026 21:42
@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 4efa2922-9544-4d92-9d7e-de7808187cf1

📥 Commits

Reviewing files that changed from the base of the PR and between 391d7eb and 3520774.

📒 Files selected for processing (4)
  • examples/prisma-next-demo/src/prisma/db.ts
  • examples/prisma-next-demo/src/prisma/slow-query-warning.ts
  • examples/prisma-next-demo/test/slow-query-warning.test.ts
  • skills/upgrade/prisma-next-upgrade/upgrades/0.14-to-0.15/instructions.md
✅ Files skipped from review due to trivial changes (1)
  • skills/upgrade/prisma-next-upgrade/upgrades/0.14-to-0.15/instructions.md
🚧 Files skipped from review as they are similar to previous changes (3)
  • examples/prisma-next-demo/test/slow-query-warning.test.ts
  • examples/prisma-next-demo/src/prisma/slow-query-warning.ts
  • examples/prisma-next-demo/src/prisma/db.ts

📝 Walkthrough

Walkthrough

Adds a new slowQueryWarning Prisma SQL middleware in the Next demo app, wires it into the demo Prisma client, adds offline tests for its threshold behavior, and documents the example in the upgrade instructions.

Changes

Slow Query Warning Middleware

Layer / File(s) Summary
Middleware implementation
examples/prisma-next-demo/src/prisma/slow-query-warning.ts
Defines SlowQueryWarningOptions with optional thresholdMs and exports slowQueryWarning(options?), which logs APP.SLOW_QUERY warnings from afterExecute when result.latencyMs exceeds the threshold.
Wiring into demo Prisma client
examples/prisma-next-demo/src/prisma/db.ts
Imports slowQueryWarning and adds slowQueryWarning({ thresholdMs: 250 }) to the runtime middleware chain after budgets(...), with comments about latency observation and warning emission.
Middleware tests
examples/prisma-next-demo/test/slow-query-warning.test.ts
Adds Vitest coverage for warning emission above a custom threshold, suppression at the threshold, and the default 250ms threshold using a mocked middleware context and Prisma SQL execution plan.
Upgrade note
skills/upgrade/prisma-next-upgrade/upgrades/0.14-to-0.15/instructions.md
Adds an upgrade-doc section describing the new example middleware, its wiring, and that it does not change framework contracts or emitted artifacts.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested reviewers: wmadden

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and accurately summarizes the main change: adding a slow-query warning middleware example to prisma-next-demo.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch examples/extensions-middleware-docs

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown

size-limit report 📦

Path Size
postgres / no-emit 148.97 KB (0%)
postgres / emit 126.45 KB (0%)
mongo / no-emit 98.2 KB (0%)
mongo / emit 89.39 KB (0%)
cf-worker / no-emit 175.52 KB (0%)
cf-worker / emit 150.97 KB (0%)

@pkg-pr-new

pkg-pr-new Bot commented Jul 3, 2026

Copy link
Copy Markdown

Open in StackBlitz

@prisma-next/extension-author-tools

npm i https://pkg.pr.new/@prisma-next/extension-author-tools@912

@prisma-next/mongo-runtime

npm i https://pkg.pr.new/@prisma-next/mongo-runtime@912

@prisma-next/family-mongo

npm i https://pkg.pr.new/@prisma-next/family-mongo@912

@prisma-next/sql-runtime

npm i https://pkg.pr.new/@prisma-next/sql-runtime@912

@prisma-next/family-sql

npm i https://pkg.pr.new/@prisma-next/family-sql@912

@prisma-next/extension-arktype-json

npm i https://pkg.pr.new/@prisma-next/extension-arktype-json@912

@prisma-next/middleware-cache

npm i https://pkg.pr.new/@prisma-next/middleware-cache@912

@prisma-next/mongo

npm i https://pkg.pr.new/@prisma-next/mongo@912

@prisma-next/extension-paradedb

npm i https://pkg.pr.new/@prisma-next/extension-paradedb@912

@prisma-next/extension-pgvector

npm i https://pkg.pr.new/@prisma-next/extension-pgvector@912

@prisma-next/extension-postgis

npm i https://pkg.pr.new/@prisma-next/extension-postgis@912

@prisma-next/postgres

npm i https://pkg.pr.new/@prisma-next/postgres@912

@prisma-next/sql-orm-client

npm i https://pkg.pr.new/@prisma-next/sql-orm-client@912

@prisma-next/sqlite

npm i https://pkg.pr.new/@prisma-next/sqlite@912

@prisma-next/extension-supabase

npm i https://pkg.pr.new/@prisma-next/extension-supabase@912

@prisma-next/target-mongo

npm i https://pkg.pr.new/@prisma-next/target-mongo@912

@prisma-next/adapter-mongo

npm i https://pkg.pr.new/@prisma-next/adapter-mongo@912

@prisma-next/driver-mongo

npm i https://pkg.pr.new/@prisma-next/driver-mongo@912

@prisma-next/contract

npm i https://pkg.pr.new/@prisma-next/contract@912

@prisma-next/utils

npm i https://pkg.pr.new/@prisma-next/utils@912

@prisma-next/config

npm i https://pkg.pr.new/@prisma-next/config@912

@prisma-next/errors

npm i https://pkg.pr.new/@prisma-next/errors@912

@prisma-next/framework-components

npm i https://pkg.pr.new/@prisma-next/framework-components@912

@prisma-next/operations

npm i https://pkg.pr.new/@prisma-next/operations@912

@prisma-next/ts-render

npm i https://pkg.pr.new/@prisma-next/ts-render@912

@prisma-next/contract-authoring

npm i https://pkg.pr.new/@prisma-next/contract-authoring@912

@prisma-next/ids

npm i https://pkg.pr.new/@prisma-next/ids@912

@prisma-next/psl-parser

npm i https://pkg.pr.new/@prisma-next/psl-parser@912

@prisma-next/psl-printer

npm i https://pkg.pr.new/@prisma-next/psl-printer@912

@prisma-next/cli

npm i https://pkg.pr.new/@prisma-next/cli@912

@prisma-next/cli-telemetry

npm i https://pkg.pr.new/@prisma-next/cli-telemetry@912

@prisma-next/config-loader

npm i https://pkg.pr.new/@prisma-next/config-loader@912

@prisma-next/emitter

npm i https://pkg.pr.new/@prisma-next/emitter@912

@prisma-next/language-server

npm i https://pkg.pr.new/@prisma-next/language-server@912

@prisma-next/migration-tools

npm i https://pkg.pr.new/@prisma-next/migration-tools@912

prisma-next

npm i https://pkg.pr.new/prisma-next@912

@prisma-next/vite-plugin-contract-emit

npm i https://pkg.pr.new/@prisma-next/vite-plugin-contract-emit@912

@prisma-next/mongo-codec

npm i https://pkg.pr.new/@prisma-next/mongo-codec@912

@prisma-next/mongo-contract

npm i https://pkg.pr.new/@prisma-next/mongo-contract@912

@prisma-next/mongo-value

npm i https://pkg.pr.new/@prisma-next/mongo-value@912

@prisma-next/mongo-contract-psl

npm i https://pkg.pr.new/@prisma-next/mongo-contract-psl@912

@prisma-next/mongo-contract-ts

npm i https://pkg.pr.new/@prisma-next/mongo-contract-ts@912

@prisma-next/mongo-emitter

npm i https://pkg.pr.new/@prisma-next/mongo-emitter@912

@prisma-next/mongo-schema-ir

npm i https://pkg.pr.new/@prisma-next/mongo-schema-ir@912

@prisma-next/mongo-query-ast

npm i https://pkg.pr.new/@prisma-next/mongo-query-ast@912

@prisma-next/mongo-orm

npm i https://pkg.pr.new/@prisma-next/mongo-orm@912

@prisma-next/mongo-query-builder

npm i https://pkg.pr.new/@prisma-next/mongo-query-builder@912

@prisma-next/mongo-lowering

npm i https://pkg.pr.new/@prisma-next/mongo-lowering@912

@prisma-next/mongo-wire

npm i https://pkg.pr.new/@prisma-next/mongo-wire@912

@prisma-next/sql-contract

npm i https://pkg.pr.new/@prisma-next/sql-contract@912

@prisma-next/sql-errors

npm i https://pkg.pr.new/@prisma-next/sql-errors@912

@prisma-next/sql-operations

npm i https://pkg.pr.new/@prisma-next/sql-operations@912

@prisma-next/sql-schema-ir

npm i https://pkg.pr.new/@prisma-next/sql-schema-ir@912

@prisma-next/sql-contract-psl

npm i https://pkg.pr.new/@prisma-next/sql-contract-psl@912

@prisma-next/sql-contract-ts

npm i https://pkg.pr.new/@prisma-next/sql-contract-ts@912

@prisma-next/sql-contract-emitter

npm i https://pkg.pr.new/@prisma-next/sql-contract-emitter@912

@prisma-next/sql-lane-query-builder

npm i https://pkg.pr.new/@prisma-next/sql-lane-query-builder@912

@prisma-next/sql-relational-core

npm i https://pkg.pr.new/@prisma-next/sql-relational-core@912

@prisma-next/sql-builder

npm i https://pkg.pr.new/@prisma-next/sql-builder@912

@prisma-next/target-postgres

npm i https://pkg.pr.new/@prisma-next/target-postgres@912

@prisma-next/target-sqlite

npm i https://pkg.pr.new/@prisma-next/target-sqlite@912

@prisma-next/adapter-postgres

npm i https://pkg.pr.new/@prisma-next/adapter-postgres@912

@prisma-next/adapter-sqlite

npm i https://pkg.pr.new/@prisma-next/adapter-sqlite@912

@prisma-next/driver-postgres

npm i https://pkg.pr.new/@prisma-next/driver-postgres@912

@prisma-next/driver-sqlite

npm i https://pkg.pr.new/@prisma-next/driver-sqlite@912

commit: 3520774

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
examples/prisma-next-demo/test/slow-query-warning.test.ts (1)

54-63: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Prefer separate expect() calls over toMatchObject.

Based on learnings, this repo's test convention favors individual field assertions for clearer failure messages rather than a single combined toMatchObject check.

♻️ Proposed refactor
     expect(warnEvents).toHaveLength(1);
-    expect(warnEvents[0]).toMatchObject({
-      code: 'APP.SLOW_QUERY',
-      details: {
-        sql: 'SELECT "id", "email" FROM "user" LIMIT 1',
-        latencyMs: 900,
-        rowCount: 1,
-        source: 'driver',
-        planExecutionId: 'test-plan-execution',
-      },
-    });
+    const event = warnEvents[0] as { code: string; details: Record<string, unknown> };
+    expect(event.code).toBe('APP.SLOW_QUERY');
+    expect(event.details.sql).toBe('SELECT "id", "email" FROM "user" LIMIT 1');
+    expect(event.details.latencyMs).toBe(900);
+    expect(event.details.rowCount).toBe(1);
+    expect(event.details.source).toBe('driver');
+    expect(event.details.planExecutionId).toBe('test-plan-execution');
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/prisma-next-demo/test/slow-query-warning.test.ts` around lines 54 -
63, The assertion in slow-query-warning.test.ts uses a single toMatchObject
check for warnEvents[0], but this test suite prefers separate expect() calls for
clearer failures. Update the assertion around warnEvents[0] to verify code and
each details field individually, keeping the same values for sql, latencyMs,
rowCount, source, and planExecutionId, and use the existing warnEvents array
access in the test.

Source: Learnings

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@examples/prisma-next-demo/test/slow-query-warning.test.ts`:
- Around line 54-63: The assertion in slow-query-warning.test.ts uses a single
toMatchObject check for warnEvents[0], but this test suite prefers separate
expect() calls for clearer failures. Update the assertion around warnEvents[0]
to verify code and each details field individually, keeping the same values for
sql, latencyMs, rowCount, source, and planExecutionId, and use the existing
warnEvents array access in the test.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 1d93a813-197a-4b73-8a27-e9942b0d2f6c

📥 Commits

Reviewing files that changed from the base of the PR and between a2791c5 and 391d7eb.

📒 Files selected for processing (3)
  • examples/prisma-next-demo/src/prisma/db.ts
  • examples/prisma-next-demo/src/prisma/slow-query-warning.ts
  • examples/prisma-next-demo/test/slow-query-warning.test.ts

sorenbs and others added 2 commits July 7, 2026 14:01
Adds a slowQueryWarning middleware to the prisma-next-demo example,
wired into the runtime middleware chain in db.ts, with offline unit
tests driving afterExecute directly. Written as the canonical custom
middleware example for the Prisma Next docs (middleware section).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Søren Bramer Schmidt <sorenbs@gmail.com>
…idental

The slow-query-warning middleware addition to prisma-next-demo is
example-only documentation code exercising the existing SqlMiddleware
afterExecute hook; no consumer upgrade action is required.

Signed-off-by: Alexey Orlenko's AI Agent <robot@aqrln.net>
@tensordreams tensordreams force-pushed the examples/extensions-middleware-docs branch from 391d7eb to 3520774 Compare July 7, 2026 12:03
@aqrln aqrln enabled auto-merge July 7, 2026 12:05
@aqrln aqrln added this pull request to the merge queue Jul 7, 2026
Merged via the queue into main with commit 4e11a2d Jul 7, 2026
21 checks passed
@aqrln aqrln deleted the examples/extensions-middleware-docs branch July 7, 2026 12:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants