Make Redirects.urlPrefix actually gate which route a code resolves under
resolveAndTrackRedirect() now filters on urlPrefix in addition to code, with each route.ts passing its own literal prefix — previously the field was admin-display-only, so a code marked "/sticker" in Payload silently kept resolving under /r/<code> too. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G5mssdCBir9kyXTmqBjV3h
This commit is contained in:
+16
-9
@@ -1251,20 +1251,27 @@ export async function getSeoSettings(): Promise<SeoSettings> {
|
||||
};
|
||||
}
|
||||
|
||||
// Powers app/r/[code]/route.ts — a static short link (e.g. printed on a QR
|
||||
// code) that redirects to a `targetPath` editable in Payload at any time,
|
||||
// so the QR code itself never needs reprinting. `cache: "no-store"`
|
||||
// (unlike this file's other public-catalog fetches) since a stale hit here
|
||||
// would send a visitor to a since-changed target, and the PATCH below needs
|
||||
// the just-fetched id/clickCount, not a 60s-old ISR snapshot.
|
||||
// Powers app/r/[code]/route.ts and app/sticker/[code]/route.ts — a static
|
||||
// short link (e.g. printed on a QR code) that redirects to a `targetPath`
|
||||
// editable in Payload at any time, so the QR code itself never needs
|
||||
// reprinting. `cache: "no-store"` (unlike this file's other public-catalog
|
||||
// fetches) since a stale hit here would send a visitor to a since-changed
|
||||
// target, and the PATCH below needs the just-fetched id/clickCount, not a
|
||||
// 60s-old ISR snapshot.
|
||||
type PayloadRedirect = { id: number; targetPath: string; clickCount: number };
|
||||
|
||||
// PATCH failure only logs — click tracking is informational, never worth
|
||||
// stranding a visitor on a broken link over.
|
||||
export async function resolveAndTrackRedirect(code: string): Promise<string | null> {
|
||||
// `urlPrefix` filters the match to whichever fixed frontend route is
|
||||
// actually calling this — Redirects.urlPrefix is otherwise just an admin
|
||||
// label, not something either route enforced, so a code edited to
|
||||
// urlPrefix "/sticker" in Payload would silently keep resolving under
|
||||
// /r/<code> too without this. Each call site passes its own literal
|
||||
// prefix (see route.ts files), so this actually makes the field mean
|
||||
// something rather than only decorate the admin list.
|
||||
export async function resolveAndTrackRedirect(code: string, urlPrefix: "/r" | "/sticker"): Promise<string | null> {
|
||||
const params = new URLSearchParams({
|
||||
"where[tenant.slug][equals]": TENANT_SLUG,
|
||||
"where[code][equals]": code,
|
||||
"where[urlPrefix][equals]": urlPrefix,
|
||||
"where[active][equals]": "true",
|
||||
limit: "1",
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user