47 lines
1.4 KiB
TypeScript
47 lines
1.4 KiB
TypeScript
import type { CollectionConfig } from 'payload'
|
|
|
|
/* One like per user per post. `likes`/`views` counters live on the post doc;
|
|
this collection records who liked what so the toggle is idempotent. */
|
|
const PostLikes: CollectionConfig = {
|
|
slug: 'post-likes',
|
|
admin: {
|
|
useAsTitle: 'id',
|
|
defaultColumns: ['user', 'post', 'createdAt'],
|
|
},
|
|
access: {
|
|
read: () => true,
|
|
create: ({ req }) => !!req.user,
|
|
delete: ({ req }) => {
|
|
// Admins and the like owner can unlike
|
|
const user = req.user as { id?: number | string; role?: string } | undefined
|
|
if (user?.role === 'admin') return true
|
|
return { user: { equals: user?.id } }
|
|
},
|
|
},
|
|
fields: [
|
|
{ name: 'user', type: 'relationship', relationTo: 'users', required: true, index: true },
|
|
{ name: 'post', type: 'relationship', relationTo: 'posts', required: true, index: true },
|
|
],
|
|
hooks: {
|
|
beforeValidate: [
|
|
async ({ data, req, operation }) => {
|
|
if (operation !== 'create' || !data || !req.payload) return data
|
|
const existing = await req.payload.find({
|
|
collection: 'post-likes',
|
|
where: {
|
|
and: [
|
|
{ user: { equals: data.user } },
|
|
{ post: { equals: data.post } },
|
|
],
|
|
},
|
|
limit: 1,
|
|
})
|
|
if (existing.docs.length > 0) throw new Error('already-liked')
|
|
return data
|
|
},
|
|
],
|
|
},
|
|
}
|
|
|
|
export default PostLikes
|