Skip to main content
SnackBase includes a powerful rule engine that compiles expression-based rules into efficient SQL WHERE clauses. This guide explains the syntax, variables, and best practices for writing rules.

Overview

Rules are boolean expressions associated with collection operations (list, view, create, update, delete).
# Rule example: Users can only see their own records
created_by = @request.auth.id

When to Use Rules

ScenarioExample
Record ownershipcreated_by = @request.auth.id
Role-based access@request.auth.role = "admin"
Status-based access`status = “published”@request.auth.role = “admin”`
Pattern matchingemail ~ "%@company.com"
Complex logic`(priority > 5 && @request.auth.role = “manager”)created_by = @request.auth.id`

Rule Syntax

Basic Expressions

# Field comparisons
@request.auth.id = "user_abc123"
@request.auth.email = "[email protected]"
status = "published"

# Numeric comparisons
views > 1000
priority >= 3
quantity <= 50

# Pattern matching (SQL LIKE)
title ~ "Draft%"  # Starts with Draft
email ~ "%@gmail.com"  # Ends with @gmail.com

# Negation
!is_archived
status != "archived"

Logical Operators

OperatorUsageDescription
&&cond1 && cond2Both conditions must be true
```cond1cond1`At least one condition must be true
!!conditionSimple negation
()`(c1c2) && c3`Grouping for precedence
Operator Precedence: () > ! > comparisons > && > ||

Evaluation Context

Rules have access to the following variables:

1. @request.auth (Standard)

FieldDescription
@request.auth.idCurrent user ID
@request.auth.emailCurrent user email
@request.auth.roleCurrent user role
@request.auth.account_idCurrent account context

2. @request.data (Action-specific)

Available during create and update operations.
  • @request.data.fieldname: Accesses the value being sent in the request body.
Example: [email protected]_admin (Don’t allow setting admin flag via this route).

3. Record Fields (Direct Access)

You can reference any field in the record directly by name.
  • created_by
  • status
  • your_custom_field

Built-in Macros

MacroDescriptionExample
@has_role(role)User has specific role@has_role("admin")
@has_group(group)User has specific group@has_group("managers")
@owns_record()User is the creator@owns_record()
@is_creator()Alias for @owns_record@is_creator()

Rule Examples

Example 1: Edit Own Drafts

Only allow editing if the user is the creator AND the status is “draft”.
@owns_record() && status = "draft"

Example 2: Admin or Owner

@request.auth.role = "admin" || @owns_record()

Example 3: String Pattern Matching

Allow viewing only if the record type starts with “public”.
type ~ "public%"

Example 4: Complex Multi-Condition

# User can edit if:
# - They're an admin, OR
# - They own it AND it's not locked
@request.auth.role = "admin" || (@owns_record() && !is_locked)

Testing Rules

Manual Testing in Admin UI

SnackBase provides a built-in Rule Tester in the Collections settings:
  1. Navigate to Collections -> Edit Collection -> Rules.
  2. Write your rule.
  3. Use the “Test Rule” button to simulate evaluation against a mock user and record.

API Testing

You can also test rules via the API:
POST /api/v1/roles/test-rule
{
  "rule": "@owns_record() && status = 'draft'",
  "user_id": "usr_123",
  "record": {"created_by": "usr_123", "status": "draft"}
}

Best Practices

  1. Keep Rules Simple: Complex logic is hard to debug. Use SQL Macros for complex multi-table checks.
  2. Use Parentheses: Always group conditions in complex expressions to ensure correct evaluation order.
  3. Optimistic Rules: In SnackBase, rules are compiled to WHERE clauses, so they are extremely fast.
  4. Deny by Default: If no rule is defined for an operation, access is denied.