Formulaic Docs

Define Abilities

Once you have defined the subjects that exist, you can define the actions that can be performed on each subject.

Formulaic’s Actions

Formulaic’s ACL package comes with a basic set of actions that are suitable for many applications, and are used internally in some libraries.

You may choose to use the built-in actions, supplement the actions, or ignore them and create your own enumeration of actions.

Built-in Actions

  • Manage

  • Create

  • Browse

  • Update

  • Delete

  • Remove

  • Submit

CRUD

Typically applications use CRUD (create, read, update, delete) actions to represent most operations - we’ve renamed read to browse to make all actions 6 letters long.

Hard/Soft Delete

We also supply both "delete" and "remove", intended for applications that use soft-deletion.

delete is intended to be the user’s primary thought of deletion - soft-delete if the application supports it, otherwise hard deletion.

remove is intended to always represent a hard-deletion, which may be an administrator-only action.

Submit

We find that we’re often in a position where there’s one additional action to add to entities, that’s relatively obvious given what the entity represents.

  • An article draft needs to be published/applied to go live

  • A user-submission in a moderation queue gets approved by a moderator

  • A shopping cart gets converted into an order

  • An action that’s been drafted/dry-run is approved to be executed

You may wish to create a unique action for each of these. Alternatively, Formulaic provides submit as a pre-defined action, to reduce the number of one-off actions you have to define.

Defining Abilities using Built-in Actions

src/ability.ts
import { Ability, AbilityClass } from "@casl/ability";
import { Action, CRUDAction } from "@formulaic/acl";
import {
  AclPost,
  AclUser,
} from "./subjects";

export type Abilities
  = [Action.MANAGE, "all"]
  | [Action, "AclPost" | AclPost]
  | [CRUDAction, "AclUser" | AclUser];

export type AppAbility = Ability<Abilities>;
export const AppAbility = Ability as AbilityClass<AppAbility>;