chore(agent): configure AI agents and tools

Add configuration for BMad, Claude, OpenCode, and other AI agent tools and workflows.
This commit is contained in:
2026-02-11 11:51:23 +08:00
parent 9c2181f743
commit ad8e2e313e
977 changed files with 157625 additions and 0 deletions

View File

@@ -0,0 +1,312 @@
# Collections Reference
## Basic Collection Config
```ts
import type { CollectionConfig } from 'payload'
export const Posts: CollectionConfig = {
slug: 'posts',
admin: {
useAsTitle: 'title',
defaultColumns: ['title', 'author', 'status', 'createdAt'],
group: 'Content', // Groups in sidebar
},
fields: [...],
timestamps: true, // Adds createdAt, updatedAt
}
```
## Auth Collection
Enable authentication on a collection:
```ts
export const Users: CollectionConfig = {
slug: 'users',
auth: {
tokenExpiration: 7200, // 2 hours
verify: true, // Email verification
maxLoginAttempts: 5,
lockTime: 600 * 1000, // 10 min lockout
},
fields: [
{ name: 'name', type: 'text', required: true },
{
name: 'roles',
type: 'select',
hasMany: true,
options: ['admin', 'editor', 'user'],
defaultValue: ['user'],
},
],
}
```
## Upload Collection
Handle file uploads:
```ts
export const Media: CollectionConfig = {
slug: 'media',
upload: {
staticDir: 'media',
mimeTypes: ['image/*', 'application/pdf'],
imageSizes: [
{ name: 'thumbnail', width: 400, height: 300, position: 'centre' },
{ name: 'card', width: 768, height: 1024, position: 'centre' },
],
adminThumbnail: 'thumbnail',
},
fields: [
{ name: 'alt', type: 'text', required: true },
{ name: 'caption', type: 'textarea' },
],
}
```
## Versioning & Drafts
Enable draft/publish workflow:
```ts
export const Posts: CollectionConfig = {
slug: 'posts',
versions: {
drafts: true,
maxPerDoc: 10, // Keep last 10 versions
},
fields: [...],
}
```
Query drafts:
```ts
// Get published only (default)
await payload.find({ collection: 'posts' })
// Include drafts
await payload.find({ collection: 'posts', draft: true })
```
## Live Preview
Real-time preview for frontend:
```ts
export const Pages: CollectionConfig = {
slug: 'pages',
admin: {
livePreview: {
url: ({ data }) => `${process.env.NEXT_PUBLIC_URL}/preview/${data.slug}`,
},
},
versions: { drafts: true },
fields: [...],
}
```
## Access Control
```ts
export const Posts: CollectionConfig = {
slug: 'posts',
access: {
create: ({ req }) => !!req.user, // Logged in users
read: () => true, // Public read
update: ({ req }) => req.user?.roles?.includes('admin'),
delete: ({ req }) => req.user?.roles?.includes('admin'),
},
fields: [...],
}
```
## Hooks Configuration
```ts
export const Posts: CollectionConfig = {
slug: 'posts',
hooks: {
beforeValidate: [...],
beforeChange: [...],
afterChange: [...],
beforeRead: [...],
afterRead: [...],
beforeDelete: [...],
afterDelete: [...],
// Auth-only hooks
afterLogin: [...],
afterLogout: [...],
afterMe: [...],
afterRefresh: [...],
afterForgotPassword: [...],
},
fields: [...],
}
```
## Custom Endpoints
Add API routes to a collection:
```ts
export const Posts: CollectionConfig = {
slug: 'posts',
endpoints: [
{
path: '/publish/:id',
method: 'post',
handler: async (req) => {
const { id } = req.routeParams
await req.payload.update({
collection: 'posts',
id,
data: { status: 'published', publishedAt: new Date() },
req,
})
return Response.json({ success: true })
},
},
],
fields: [...],
}
```
## Admin Panel Options
```ts
export const Posts: CollectionConfig = {
slug: 'posts',
admin: {
useAsTitle: 'title',
defaultColumns: ['title', 'status', 'createdAt'],
group: 'Content',
description: 'Manage blog posts',
hidden: false, // Hide from sidebar
listSearchableFields: ['title', 'slug'],
pagination: {
defaultLimit: 20,
limits: [10, 20, 50, 100],
},
preview: (doc) => `${process.env.NEXT_PUBLIC_URL}/${doc.slug}`,
},
fields: [...],
}
```
## Labels & Localization
```ts
export const Posts: CollectionConfig = {
slug: 'posts',
labels: {
singular: 'Article',
plural: 'Articles',
},
fields: [...],
}
```
## Database Indexes
```ts
export const Posts: CollectionConfig = {
slug: 'posts',
fields: [
{ name: 'slug', type: 'text', unique: true, index: true },
{ name: 'publishedAt', type: 'date', index: true },
],
// Compound indexes via dbName
dbName: 'posts',
}
```
## Disable Operations
```ts
export const AuditLogs: CollectionConfig = {
slug: 'audit-logs',
admin: {
enableRichTextRelationship: false,
},
disableDuplicate: true, // No duplicate button
fields: [...],
}
```
## Full Example
```ts
import type { CollectionConfig } from 'payload'
import { slugField } from './fields/slugField'
export const Posts: CollectionConfig = {
slug: 'posts',
admin: {
useAsTitle: 'title',
defaultColumns: ['title', 'author', 'status', 'publishedAt'],
group: 'Content',
livePreview: {
url: ({ data }) => `${process.env.NEXT_PUBLIC_URL}/posts/${data.slug}`,
},
},
access: {
create: ({ req }) => !!req.user,
read: ({ req }) => {
if (req.user?.roles?.includes('admin')) return true
return { status: { equals: 'published' } }
},
update: ({ req }) => {
if (req.user?.roles?.includes('admin')) return true
return { author: { equals: req.user?.id } }
},
delete: ({ req }) => req.user?.roles?.includes('admin'),
},
versions: {
drafts: true,
maxPerDoc: 10,
},
hooks: {
beforeChange: [
async ({ data, operation }) => {
if (operation === 'create') {
data.slug = data.title?.toLowerCase().replace(/\s+/g, '-')
}
if (data.status === 'published' && !data.publishedAt) {
data.publishedAt = new Date()
}
return data
},
],
},
fields: [
{ name: 'title', type: 'text', required: true },
{ name: 'slug', type: 'text', unique: true, index: true },
{ name: 'content', type: 'richText', required: true },
{
name: 'author',
type: 'relationship',
relationTo: 'users',
required: true,
defaultValue: ({ user }) => user?.id,
},
{
name: 'status',
type: 'select',
options: ['draft', 'published', 'archived'],
defaultValue: 'draft',
},
{ name: 'publishedAt', type: 'date' },
{ name: 'featuredImage', type: 'upload', relationTo: 'media' },
{
name: 'categories',
type: 'relationship',
relationTo: 'categories',
hasMany: true,
},
],
timestamps: true,
}
```