Published public, drafts private

Readers see published posts; authors also see their drafts.
  • Any of these rules pass:
    • Compare values: $record.status equals published
    • Owns the record (field) author_id
Use for list and get. (Per-row, so totals can be null; see evaluation.)

Hide deleted records

With a nullable deleted_at column (soft delete):
  • All of these rules pass:
    • Owns the record (field) owner_id
    • Check a value: $record.deleted_at is empty

Scheduled publishing

Visible once publish_at has passed:
  • Any of these rules pass:
    • Check a value: $record.publish_at is empty
    • Compare values: $record.publish_at is at most $now
A null publish_at means “publish immediately”. Without the empty branch, those rows would never be visible (lte with a missing side is false).

Expiring content

  • Any of these rules pass:
    • Check a value: $record.expires_at is empty
    • Compare values: $record.expires_at is greater than $now

Locked records

No edits once locked:
  • All of these rules pass:
    • Owns the record (field) owner_id
    • Compare values: $record.locked does not equal yes
as update and delete. A rule can’t unlock; do that from a service or a role: { "any": [{ "role": "admin" }, <the rule above>] }.

Only forward state changes

Let the owner move a record from draft to submitted, but not edit approved ones:
  • All of these rules pass:
    • Owns the record (field) owner_id
    • Compare values: $record.status is one of draft, submitted
    • Compare values: $input.status is one of draft, submitted
as update. Approval is a separate step done by role:reviewer through another route.

Limit values

  • All of these rules pass:
    • Is signed in: yes
    • Compare values: $input.quantity is at most 10
    • Compare values: $input.quantity is at least 1
as create. For hard limits that must hold however the record is written, also set the column’s minimum/maximum (Columns).

Rate-limited by state

“At most 3 open orders” can’t be a rule built in Studio: it needs a count of other rows. Do it in a route, or a unique partial index, such as one open cart per customer. A comment is visible if its post is. Comments can’t look at the post in a rule built in Studio. Either copy the post’s visibility onto the comment on create, or give comments the rule public and only expose them through the post with expand, which reads comments under the comments table’s rule.

Patterns

Database designs.

Values and paths

Missing-value pitfalls.