Files
shiftcraft/.claude/skills/pocketbase-best-practices/rules/rules-cross-collection.md
2026-04-17 23:26:01 +00:00

2.6 KiB

title, impact, impactDescription, tags
title impact impactDescription tags
Use @collection for Cross-Collection Lookups HIGH Enables complex authorization without denormalization api-rules, security, cross-collection, relations

Use @collection for Cross-Collection Lookups

The @collection reference allows rules to query other collections, enabling complex authorization patterns like role-based access, team membership, and resource permissions.

Incorrect (denormalizing data for access control):

// Duplicating team membership in every resource
const documentsSchema = [
  { name: 'title', type: 'text' },
  { name: 'team', type: 'relation' },
  // Duplicated member list for access control - gets out of sync!
  { name: 'allowedUsers', type: 'relation', options: { maxSelect: 999 } }
];

// Rule checks duplicated data
listRule: 'allowedUsers ?= @request.auth.id'
// Problem: must update allowedUsers whenever team membership changes

Correct (using @collection lookup):

// Clean schema - no duplication
const documentsSchema = [
  { name: 'title', type: 'text' },
  { name: 'team', type: 'relation', options: { collectionId: 'teams' } }
];

// Check team membership via @collection lookup
listRule: '@collection.team_members.user ?= @request.auth.id && @collection.team_members.team ?= team'

// Alternative: check if user is in team's members array
listRule: 'team.members ?= @request.auth.id'

// Role-based access via separate roles collection
listRule: '@collection.user_roles.user = @request.auth.id && @collection.user_roles.role = "admin"'

Common patterns:

// Team-based access
// teams: { name, members (relation to users) }
// documents: { title, team (relation to teams) }
viewRule: 'team.members ?= @request.auth.id'

// Organization hierarchy
// orgs: { name }
// org_members: { org, user, role }
// projects: { name, org }
listRule: '@collection.org_members.org = org && @collection.org_members.user = @request.auth.id'

// Permission-based access
// permissions: { resource, user, level }
updateRule: '@collection.permissions.resource = id && @collection.permissions.user = @request.auth.id && @collection.permissions.level = "write"'

// Using aliases for complex queries
listRule: '@collection.memberships:m.user = @request.auth.id && @collection.memberships:m.team = team'

Performance considerations:

  • Cross-collection lookups add query complexity
  • Ensure referenced fields are indexed
  • Consider caching for frequently accessed permissions
  • Test performance with realistic data volumes

Reference: PocketBase Collection Reference