Keep listed published rules public and guest-claim rules unlisted, with semantic document markup and share chrome that stays clickable.

Guest publishes remain share-by-link but stay out of the catalog and sitemap, and their pages send noindex until claimed. The published-rule view now uses heading and list markup matching Markdown export, and top banners sit below the header so Share is not covered.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
adilalloandCursor committed 2026-09-17 17:42:01 -06:00
1 parent 77b0ec8ad8
commit 1445cb7e1e
27 files changed
+524 -86

No files matched your search

+10 -17
View File
@@ -1,7 +1,11 @@
import type { Prisma } from "@prisma/client";
import { NextRequest, NextResponse } from "next/server";
import { prisma } from "../../../lib/server/db";
import { getSessionPepper, isDatabaseConfigured } from "../../../lib/server/env";
import { listListedPublishedRules } from "../../../lib/server/publishedRules";
import {
getSessionPepper,
isDatabaseConfigured,
} from "../../../lib/server/env";
import {
hashSessionToken,
hashRuleClaimToken,
@@ -12,6 +16,7 @@ import { rateLimitKey } from "../../../lib/server/rateLimit";
import {
dbUnavailable,
errorJson,
internalError,
rateLimited,
serverMisconfigured,
} from "../../../lib/server/responses";
@@ -48,22 +53,10 @@ export const GET = apiRoute("rules.list", async (request: NextRequest) => {
const { searchParams } = new URL(request.url);
const take = Math.min(Number(searchParams.get("limit") ?? "50") || 50, 100);
/**
* Public catalog: owned rules only (last touched first). Guest / orphan rows
* (`userId` null) stay reachable at `/rules/[id]` and `GET /api/rules/[id]`.
*/
const rules = await prisma.publishedRule.findMany({
where: { userId: { not: null } },
orderBy: [{ updatedAt: "desc" }, { id: "asc" }],
take,
select: {
id: true,
title: true,
summary: true,
createdAt: true,
updatedAt: true,
},
});
const rules = await listListedPublishedRules(take);
if (rules === null) {
return internalError("Failed to list rules");
}
return NextResponse.json({ rules });
});