From f1af8c0a7918e17963ba3fa5ed4822afff827be9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Guti=C3=A9rrez?= <35082514+alezmad@users.noreply.github.com> Date: Mon, 6 Apr 2026 01:51:06 +0100 Subject: [PATCH] fix(web): payload at /payload route (cuidecar pattern) Replicate working cuidecar Payload setup: - require() instead of ESM import for withPayload - routes.admin = "/payload" to avoid /admin conflicts - (payload)/payload/ route group with own layout + importMap Co-Authored-By: Claude Opus 4.6 (1M context) --- apps/web/next.config.ts | 5 +- apps/web/payload.config.ts | 4 + apps/web/src/app/(payload)/layout.tsx | 14 + .../payload/[[...segments]]/page.tsx | 14 + .../src/app/(payload)/payload/importMap.js | 2 + apps/web/src/payload-types.ts | 543 ++++++++++++++++++ 6 files changed, 581 insertions(+), 1 deletion(-) create mode 100644 apps/web/src/app/(payload)/layout.tsx create mode 100644 apps/web/src/app/(payload)/payload/[[...segments]]/page.tsx create mode 100644 apps/web/src/app/(payload)/payload/importMap.js create mode 100644 apps/web/src/payload-types.ts diff --git a/apps/web/next.config.ts b/apps/web/next.config.ts index 8f83169..66fac57 100644 --- a/apps/web/next.config.ts +++ b/apps/web/next.config.ts @@ -1,5 +1,8 @@ import type { NextConfig } from "next"; +// eslint-disable-next-line @typescript-eslint/no-require-imports +const { withPayload } = require("@payloadcms/next/withPayload"); + import env from "./env.config"; const INTERNAL_PACKAGES = [ @@ -115,4 +118,4 @@ const withBundleAnalyzer = require("@next/bundle-analyzer")({ enabled: env.ANALYZE, }); -export default withBundleAnalyzer(config); +export default withPayload(withBundleAnalyzer(config)); diff --git a/apps/web/payload.config.ts b/apps/web/payload.config.ts index 4ee5c17..48c5f07 100644 --- a/apps/web/payload.config.ts +++ b/apps/web/payload.config.ts @@ -15,6 +15,10 @@ const usePostgres = !!process.env.DATABASE_URL; export default buildConfig({ secret: process.env.PAYLOAD_SECRET || "claudemesh-dev-secret-change-in-production", + routes: { + admin: "/payload", + }, + admin: { user: "users", meta: { diff --git a/apps/web/src/app/(payload)/layout.tsx b/apps/web/src/app/(payload)/layout.tsx new file mode 100644 index 0000000..bdcfe53 --- /dev/null +++ b/apps/web/src/app/(payload)/layout.tsx @@ -0,0 +1,14 @@ +import "@payloadcms/next/css"; +import type { ReactNode } from "react"; + +export const metadata = { + title: "CMS — claudemesh", +}; + +export default function PayloadLayout({ children }: { children: ReactNode }) { + return ( + + {children} + + ); +} diff --git a/apps/web/src/app/(payload)/payload/[[...segments]]/page.tsx b/apps/web/src/app/(payload)/payload/[[...segments]]/page.tsx new file mode 100644 index 0000000..d72f5cd --- /dev/null +++ b/apps/web/src/app/(payload)/payload/[[...segments]]/page.tsx @@ -0,0 +1,14 @@ +/* eslint-disable */ +// @ts-nocheck — Payload generates these types at build time +import { RootPage, generatePageMetadata } from "@payloadcms/next/views"; +import { importMap } from "../importMap"; +import config from "@payload-config"; + +type Args = { params: Promise<{ segments: string[] }> }; + +export const generateMetadata = ({ params }: Args) => + generatePageMetadata({ config, params }); + +export default function Page({ params }: Args) { + return ; +} diff --git a/apps/web/src/app/(payload)/payload/importMap.js b/apps/web/src/app/(payload)/payload/importMap.js new file mode 100644 index 0000000..1666e8f --- /dev/null +++ b/apps/web/src/app/(payload)/payload/importMap.js @@ -0,0 +1,2 @@ +// Auto-generated by Payload at build time. Start empty. +export const importMap = {}; diff --git a/apps/web/src/payload-types.ts b/apps/web/src/payload-types.ts new file mode 100644 index 0000000..318de5c --- /dev/null +++ b/apps/web/src/payload-types.ts @@ -0,0 +1,543 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * This file was automatically generated by Payload. + * DO NOT MODIFY IT BY HAND. Instead, modify your source Payload config, + * and re-run `payload generate:types` to regenerate this file. + */ + +/** + * Supported timezones in IANA format. + * + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "supportedTimezones". + */ +export type SupportedTimezones = + | 'Pacific/Midway' + | 'Pacific/Niue' + | 'Pacific/Honolulu' + | 'Pacific/Rarotonga' + | 'America/Anchorage' + | 'Pacific/Gambier' + | 'America/Los_Angeles' + | 'America/Tijuana' + | 'America/Denver' + | 'America/Phoenix' + | 'America/Chicago' + | 'America/Guatemala' + | 'America/New_York' + | 'America/Bogota' + | 'America/Caracas' + | 'America/Santiago' + | 'America/Buenos_Aires' + | 'America/Sao_Paulo' + | 'Atlantic/South_Georgia' + | 'Atlantic/Azores' + | 'Atlantic/Cape_Verde' + | 'Europe/London' + | 'Europe/Berlin' + | 'Africa/Lagos' + | 'Europe/Athens' + | 'Africa/Cairo' + | 'Europe/Moscow' + | 'Asia/Riyadh' + | 'Asia/Dubai' + | 'Asia/Baku' + | 'Asia/Karachi' + | 'Asia/Tashkent' + | 'Asia/Calcutta' + | 'Asia/Dhaka' + | 'Asia/Almaty' + | 'Asia/Jakarta' + | 'Asia/Bangkok' + | 'Asia/Shanghai' + | 'Asia/Singapore' + | 'Asia/Tokyo' + | 'Asia/Seoul' + | 'Australia/Brisbane' + | 'Australia/Sydney' + | 'Pacific/Guam' + | 'Pacific/Noumea' + | 'Pacific/Auckland' + | 'Pacific/Fiji'; + +export interface Config { + auth: { + users: UserAuthOperations; + }; + blocks: {}; + collections: { + users: User; + media: Media; + authors: Author; + categories: Category; + posts: Post; + changelog: Changelog; + 'payload-kv': PayloadKv; + 'payload-locked-documents': PayloadLockedDocument; + 'payload-preferences': PayloadPreference; + 'payload-migrations': PayloadMigration; + }; + collectionsJoins: {}; + collectionsSelect: { + users: UsersSelect | UsersSelect; + media: MediaSelect | MediaSelect; + authors: AuthorsSelect | AuthorsSelect; + categories: CategoriesSelect | CategoriesSelect; + posts: PostsSelect | PostsSelect; + changelog: ChangelogSelect | ChangelogSelect; + 'payload-kv': PayloadKvSelect | PayloadKvSelect; + 'payload-locked-documents': PayloadLockedDocumentsSelect | PayloadLockedDocumentsSelect; + 'payload-preferences': PayloadPreferencesSelect | PayloadPreferencesSelect; + 'payload-migrations': PayloadMigrationsSelect | PayloadMigrationsSelect; + }; + db: { + defaultIDType: number; + }; + fallbackLocale: null; + globals: {}; + globalsSelect: {}; + locale: null; + widgets: { + collections: CollectionsWidget; + }; + user: User; + jobs: { + tasks: unknown; + workflows: unknown; + }; +} +export interface UserAuthOperations { + forgotPassword: { + email: string; + password: string; + }; + login: { + email: string; + password: string; + }; + registerFirstUser: { + email: string; + password: string; + }; + unlock: { + email: string; + password: string; + }; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "users". + */ +export interface User { + id: number; + name?: string | null; + role?: ('admin' | 'editor') | null; + updatedAt: string; + createdAt: string; + email: string; + resetPasswordToken?: string | null; + resetPasswordExpiration?: string | null; + salt?: string | null; + hash?: string | null; + loginAttempts?: number | null; + lockUntil?: string | null; + sessions?: + | { + id: string; + createdAt?: string | null; + expiresAt: string; + }[] + | null; + password?: string | null; + collection: 'users'; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "media". + */ +export interface Media { + id: number; + alt: string; + updatedAt: string; + createdAt: string; + url?: string | null; + thumbnailURL?: string | null; + filename?: string | null; + mimeType?: string | null; + filesize?: number | null; + width?: number | null; + height?: number | null; + focalX?: number | null; + focalY?: number | null; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "authors". + */ +export interface Author { + id: number; + name: string; + slug: string; + bio?: string | null; + role?: string | null; + avatar?: (number | null) | Media; + links?: { + github?: string | null; + twitter?: string | null; + website?: string | null; + }; + updatedAt: string; + createdAt: string; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "categories". + */ +export interface Category { + id: number; + name: string; + slug: string; + description?: string | null; + updatedAt: string; + createdAt: string; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "posts". + */ +export interface Post { + id: number; + title: string; + /** + * URL-friendly identifier. Auto-generated from title if left blank. + */ + slug: string; + /** + * 1-2 sentence summary for cards and meta descriptions. + */ + excerpt?: string | null; + content: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + }; + coverImage?: (number | null) | Media; + author: number | Author; + categories?: (number | Category)[] | null; + publishedAt?: string | null; + status?: ('draft' | 'published') | null; + seo?: { + metaTitle?: string | null; + metaDescription?: string | null; + ogImage?: (number | null) | Media; + }; + updatedAt: string; + createdAt: string; + _status?: ('draft' | 'published') | null; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "changelog". + */ +export interface Changelog { + id: number; + version: string; + date: string; + type: 'feat' | 'fix' | 'docs' | 'breaking'; + summary: string; + body?: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + npmUrl?: string | null; + githubUrl?: string | null; + updatedAt: string; + createdAt: string; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "payload-kv". + */ +export interface PayloadKv { + id: number; + key: string; + data: + | { + [k: string]: unknown; + } + | unknown[] + | string + | number + | boolean + | null; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "payload-locked-documents". + */ +export interface PayloadLockedDocument { + id: number; + document?: + | ({ + relationTo: 'users'; + value: number | User; + } | null) + | ({ + relationTo: 'media'; + value: number | Media; + } | null) + | ({ + relationTo: 'authors'; + value: number | Author; + } | null) + | ({ + relationTo: 'categories'; + value: number | Category; + } | null) + | ({ + relationTo: 'posts'; + value: number | Post; + } | null) + | ({ + relationTo: 'changelog'; + value: number | Changelog; + } | null); + globalSlug?: string | null; + user: { + relationTo: 'users'; + value: number | User; + }; + updatedAt: string; + createdAt: string; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "payload-preferences". + */ +export interface PayloadPreference { + id: number; + user: { + relationTo: 'users'; + value: number | User; + }; + key?: string | null; + value?: + | { + [k: string]: unknown; + } + | unknown[] + | string + | number + | boolean + | null; + updatedAt: string; + createdAt: string; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "payload-migrations". + */ +export interface PayloadMigration { + id: number; + name?: string | null; + batch?: number | null; + updatedAt: string; + createdAt: string; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "users_select". + */ +export interface UsersSelect { + name?: T; + role?: T; + updatedAt?: T; + createdAt?: T; + email?: T; + resetPasswordToken?: T; + resetPasswordExpiration?: T; + salt?: T; + hash?: T; + loginAttempts?: T; + lockUntil?: T; + sessions?: + | T + | { + id?: T; + createdAt?: T; + expiresAt?: T; + }; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "media_select". + */ +export interface MediaSelect { + alt?: T; + updatedAt?: T; + createdAt?: T; + url?: T; + thumbnailURL?: T; + filename?: T; + mimeType?: T; + filesize?: T; + width?: T; + height?: T; + focalX?: T; + focalY?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "authors_select". + */ +export interface AuthorsSelect { + name?: T; + slug?: T; + bio?: T; + role?: T; + avatar?: T; + links?: + | T + | { + github?: T; + twitter?: T; + website?: T; + }; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "categories_select". + */ +export interface CategoriesSelect { + name?: T; + slug?: T; + description?: T; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "posts_select". + */ +export interface PostsSelect { + title?: T; + slug?: T; + excerpt?: T; + content?: T; + coverImage?: T; + author?: T; + categories?: T; + publishedAt?: T; + status?: T; + seo?: + | T + | { + metaTitle?: T; + metaDescription?: T; + ogImage?: T; + }; + updatedAt?: T; + createdAt?: T; + _status?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "changelog_select". + */ +export interface ChangelogSelect { + version?: T; + date?: T; + type?: T; + summary?: T; + body?: T; + npmUrl?: T; + githubUrl?: T; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "payload-kv_select". + */ +export interface PayloadKvSelect { + key?: T; + data?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "payload-locked-documents_select". + */ +export interface PayloadLockedDocumentsSelect { + document?: T; + globalSlug?: T; + user?: T; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "payload-preferences_select". + */ +export interface PayloadPreferencesSelect { + user?: T; + key?: T; + value?: T; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "payload-migrations_select". + */ +export interface PayloadMigrationsSelect { + name?: T; + batch?: T; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "collections_widget". + */ +export interface CollectionsWidget { + data?: { + [k: string]: unknown; + }; + width: 'full'; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "auth". + */ +export interface Auth { + [k: string]: unknown; +} + + +declare module 'payload' { + export interface GeneratedTypes extends Config {} +} \ No newline at end of file