Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions apps/docs/src/app/llms.txt/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ export async function GET() {

const content = `# Prisma Documentation

> **Prisma changes frequently — verify against the changelog and current docs before implementing.**
> Do not rely on training data for Prisma features. APIs, configuration, and conventions can change between versions.
>
> First, fetch https://www.prisma.io/changelog.md to check for recent or relevant breaking changes,
> then look up the relevant topic in the documentation below.

> This documentation covers the current docs plus legacy v6 pages.
> Prefer the Latest ORM section for current recommendations.
> v6 pages are maintained for backwards compatibility only.
Expand Down
6 changes: 6 additions & 0 deletions apps/docs/src/lib/llms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ const excludedLLMsProducts: LLMsExcludedProduct[] = [
];

export const commonQueries: LLMsLink[] = [
{
title: "Check the Prisma changelog for recent changes",
href: "https://www.prisma.io/changelog.md",
description:
"Prisma changes frequently. Fetch this machine-readable changelog before implementing any Prisma feature to check for breaking changes, API updates, or new conventions.",
},
{
title: "Start a new Prisma ORM project",
href: "/prisma-orm/quickstart/prisma-postgres",
Expand Down
63 changes: 63 additions & 0 deletions apps/site/src/app/changelog.md/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { getReleaseNotePreview, getSortedReleaseNotes } from "@/lib/changelog-source";
import { getBaseUrl } from "@/lib/url";

export const revalidate = false;

function formatTags(tags: string[] | undefined) {
if (!tags || tags.length === 0) return "";
return ` [${tags.join(", ")}]`;
}

export async function GET() {
const baseUrl = getBaseUrl();
const entries = getSortedReleaseNotes();

const entriesWithPreview = await Promise.all(
entries.map(async (entry) => {
const summary =
entry.data.summary ??
entry.data.description ??
(entry.slugs[0] ? await getReleaseNotePreview(entry.slugs[0]) : null);
return { entry, summary };
}),
);
Comment on lines +15 to +23
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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Make per-entry preview failures non-fatal.

A rejection from one getReleaseNotePreview(...) call (Line 20) will reject the whole Promise.all and fail /changelog.md for all entries. Handle errors per entry so one bad note doesn’t take down the feed.

💡 Suggested fix
-  const entriesWithPreview = await Promise.all(
-    entries.map(async (entry) => {
-      const summary =
-        entry.data.summary ??
-        entry.data.description ??
-        (entry.slugs[0] ? await getReleaseNotePreview(entry.slugs[0]) : null);
-      return { entry, summary };
-    }),
-  );
+  const entriesWithPreview = await Promise.all(
+    entries.map(async (entry) => {
+      const preview =
+        entry.slugs[0]
+          ? await getReleaseNotePreview(entry.slugs[0]).catch(() => null)
+          : null;
+      const summary = entry.data.summary ?? entry.data.description ?? preview;
+      return { entry, summary };
+    }),
+  );
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const entriesWithPreview = await Promise.all(
entries.map(async (entry) => {
const summary =
entry.data.summary ??
entry.data.description ??
(entry.slugs[0] ? await getReleaseNotePreview(entry.slugs[0]) : null);
return { entry, summary };
}),
);
const entriesWithPreview = await Promise.all(
entries.map(async (entry) => {
const preview =
entry.slugs[0]
? await getReleaseNotePreview(entry.slugs[0]).catch(() => null)
: null;
const summary = entry.data.summary ?? entry.data.description ?? preview;
return { entry, summary };
}),
);
🤖 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 `@apps/site/src/app/changelog.md/route.ts` around lines 15 - 23, The
Promise.all mapping over entries makes a single getReleaseNotePreview rejection
fatal; update the entriesWithPreview creation (the entries.map async callback
that computes summary) to catch errors from getReleaseNotePreview for each entry
and handle them locally (e.g., return null or a safe fallback summary) so one
failing getReleaseNotePreview call won’t reject the entire Promise.all;
specifically wrap the await getReleaseNotePreview(entry.slugs[0]) in a try/catch
inside the async mapper and use the caught error to set summary to null (and
optionally log the error) while still returning { entry, summary }.


const entryLines = entriesWithPreview
.map(({ entry, summary }) => {
const url = `${baseUrl}${entry.url}`;
const tags = formatTags(entry.data.tags as string[] | undefined);
const date =
entry.data.date instanceof Date
? entry.data.date.toISOString().slice(0, 10)
: String(entry.data.date);
const lines = [
`## ${entry.data.version} — ${entry.data.title}`,
`Date: ${date}${tags}`,
`URL: ${url}`,
];
if (summary && summary.length > 30) lines.push(``, summary);
return lines.join("\n");
})
.join("\n\n---\n\n");

const content = `# Prisma Changelog

> Prisma changes frequently. Before implementing Prisma features, verify against this changelog and the current documentation at https://www.prisma.io/docs.
> Do not rely solely on training data for Prisma APIs, configuration, or conventions — these can change between versions.
>
> How to use: fetch this file to check for recent or breaking changes, then look up the relevant topic in the documentation.

Canonical URL: ${baseUrl}/changelog
Machine-readable index: ${baseUrl}/changelog.md

---

${entryLines}
`;

return new Response(content, {
headers: {
"Content-Type": "text/markdown; charset=utf-8",
},
});
}
20 changes: 20 additions & 0 deletions apps/site/src/app/llms-content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ const sitePages: LlmsPage[] = [
title: SITE_HOME_TITLE,
description: SITE_HOME_DESCRIPTION,
},
{
path: "/changelog",
title: "Prisma Changelog — Release Notes & Product Updates",
description:
"All Prisma release notes, breaking changes, and product improvements. Check here before implementing Prisma features to verify API and configuration details against the current version.",
},
{
path: "/postgres",
title: "Prisma Postgres | Instant Global Databases",
Expand Down Expand Up @@ -83,13 +89,16 @@ export function buildLlmsIndexContent(baseUrl = getBaseUrl()) {

Prisma provides Prisma ORM, Prisma Postgres, Prisma Studio, and the Prisma MCP Server.

> Prisma changes frequently. Before implementing Prisma features, check the changelog at ${toAbsoluteUrl(baseUrl, "/changelog")} for recent breaking changes or API updates.

## Key Pages

${pagesList}

## Options

- [Full website content](${toAbsoluteUrl(baseUrl, "/llms-full.txt")})
- [Changelog (machine-readable)](${toAbsoluteUrl(baseUrl, "/changelog.md")})
`;
}

Expand Down Expand Up @@ -219,6 +228,17 @@ Enterprise page highlights:
- Tailored support for enterprises and solution providers
- Positioning around build, fortify, and grow application lifecycle workflows

## Changelog

URL: ${toAbsoluteUrl(baseUrl, "/changelog")}
Machine-readable index: ${toAbsoluteUrl(baseUrl, "/changelog.md")}
Title: Prisma Changelog — Release Notes & Product Updates
Description: All Prisma release notes, breaking changes, and product improvements.

IMPORTANT: Prisma changes frequently. Before implementing any Prisma feature, fetch the changelog to check for breaking changes or API updates. Do not rely solely on training data for Prisma APIs, configuration, or conventions — these can change between versions.

How to use: fetch https://www.prisma.io/changelog.md for a machine-readable index, then look up the relevant topic in the current documentation at https://www.prisma.io/docs.
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.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Avoid hardcoded production URLs in buildLlmsFullContent.

Line 240 bypasses baseUrl, so preview/test outputs become mixed-domain while the rest of this function stays environment-aware.

💡 Suggested fix
-How to use: fetch https://www.prisma.io/changelog.md for a machine-readable index, then look up the relevant topic in the current documentation at https://www.prisma.io/docs.
+How to use: fetch ${toAbsoluteUrl(baseUrl, "/changelog.md")} for a machine-readable index, then look up the relevant topic in the current documentation at ${toAbsoluteUrl(baseUrl, "/docs")}.
🤖 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 `@apps/site/src/app/llms-content.ts` at line 240, The code in
buildLlmsFullContent hardcodes a production URL for fetching the changelog,
bypassing the environment-aware baseUrl; update buildLlmsFullContent to use the
existing baseUrl (or a passed-in baseUrl parameter) when constructing the fetch
URL instead of the literal "https://www.prisma.io/changelog.md" so preview/test
runs use the same domain logic as the rest of the function and avoid
mixed-domain outputs.


## Stack and ecosystem

Stack URL: ${toAbsoluteUrl(baseUrl, "/stack")}
Expand Down
Loading