I’m building a directory and I would like to limit the number of posts a user can add to a collection based on user role.
ie.
Guest Role - can create 1 post
Premium Role - can create 4 posts
Can this be done with Flows? So far I haven’t been able to solve.
Yes, you can use a ‘filter’ event hook flow on post.create which is a middleware where you can query the user’s role type and number of existing posts for that user.
and if the role is guest and the postcount > 0, you can block the request.
This works great because it’s at the API level, so if you’re building a separate frontend for your users, the validation will continue to work.
I was able to figure out the condition filter for user role:
{
"$accountability": {
"role": {
"_eq": "{USER_ROLE_ID}"
}
}
}
I think adding post count would be something like this, but I’m not sure how to get the actual user postcount.
{
"_and": [
{
"$accountability": {
"role": "{USER_ROLE_ID}"
}
},
{
"postcount": {
"_gt": "0"
}
}
]
}
Hello, @EpicLayer
You can solve this in two ways:
1. Using Flows (No Code)
- Create a Before Create Flow on your
posts
collection.
- Query the same collection filtering by
user_created = $CURRENT_USER
.
- Count how many posts the user has already created.
- Compare against the allowed limit (e.g. 1 for Guest, 4 for Premium).
- If they’ve reached their quota, throw an error using the Throw Error operation to block the creation.
This works well if your rules are simple and don’t change often.
2. Using a Custom Extension (Code Approach)
If you want more flexibility (e.g. different limits per role, easier maintenance), you can write a custom hook.
Here’s a simple example:
// extensions/hooks/limit-posts/index.ts
import { defineHook } from '@directus/extensions-sdk';
export default defineHook(({ filter }, { services }) => {
const { ItemsService } = services;
filter('posts.create', async (input, { accountability, database }) => {
if (!accountability?.user) return input; // unauthenticated safeguard
const roleId = accountability.role;
const userId = accountability.user;
// Define role-based limits
const limits: Record<string, number> = {
'guest-role-id': 1,
'premium-role-id': 4,
};
const limit = limits[roleId];
if (!limit) return input; // no restriction for other roles
// Query how many posts the user already has
const postsService = new ItemsService('posts', {
accountability,
knex: database,
});
const userPosts = await postsService.readByQuery({
filter: { user_created: { _eq: userId } },
aggregate: { count: '*' },
});
const count = userPosts?.[0]?.count || 0;
if (count >= limit) {
throw new Error(
`You have reached your post limit (${limit}). Upgrade your plan to add more.`
);
}
return input;
});
});