Possible in Flows? Limit number of posts based on a user role

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;
  });
});