import path from 'path'; import { fileURLToPath } from 'url'; import { buildConfig } from 'payload'; import { postgresAdapter } from '@payloadcms/db-postgres'; import { lexicalEditor } from '@payloadcms/richtext-lexical'; import sharp from 'sharp'; import { Users } from '@/collections/Users'; import { Posts } from '@/collections/Posts'; import { Media } from '@/collections/Media'; import { PAYLOAD_API_ROUTE, PAYLOAD_ADMIN_ROUTE } from '@/lib/payloadRoutes'; import { migrations } from '@/migrations'; const filename = fileURLToPath(import.meta.url); const dirname = path.dirname(filename); export default buildConfig({ admin: { user: Users.slug }, // Defined in lib/payloadRoutes.ts, which carries the reasoning and is what // the test asserts. Never inline these — /api belongs to the FastAPI proxy. routes: { api: PAYLOAD_API_ROUTE, admin: PAYLOAD_ADMIN_ROUTE }, collections: [Users, Posts, Media], editor: lexicalEditor(), secret: process.env.PAYLOAD_SECRET || '', typescript: { outputFile: path.resolve(dirname, 'payload-types.ts') }, db: postgresAdapter({ pool: { connectionString: process.env.DATABASE_URL }, // Its own schema, so no pipeline operation on `public` can reach blog // content. scripts/migrate_csv_to_db.py --drop lives in that blast radius, // as does Airflow's metadata. The schema itself is created by the initial // migration: schemaName says where tables go, it does not create anything. // // prodMigrations runs pending migrations during server init. Without it a // production container connects to an empty schema and fails its first // query with 42P01 — the adapter cannot self-create tables, because // db-postgres/connect.js gates push on NODE_ENV !== 'production'. schemaName: 'payload', prodMigrations: migrations, }), sharp, });