polizy-schema

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Polizy Schema Design

Polizy Schema 设计

The schema is the heart of polizy. It defines your authorization model: what relationships exist and what actions they enable.
Schema是Polizy的核心,它定义了你的授权模型:存在哪些关系,以及这些关系支持哪些操作。

When to Apply

适用场景

  • User says "design permissions schema" or "define authorization model"
  • User asks "what relations do I need for X"
  • User says "add new relation" or "add new action"
  • User is confused about relation types (direct vs group vs hierarchy)
  • User wants to modify their existing schema
  • User asks about
    defineSchema
    or
    actionToRelations
  • 用户提到"设计权限Schema"或"定义授权模型"
  • 用户询问"针对X场景我需要哪些关系"
  • 用户提到"添加新关系"或"添加新操作"
  • 用户对关系类型(直接、群组、层级)感到困惑
  • 用户想要修改现有Schema
  • 用户询问
    defineSchema
    actionToRelations
    相关问题

Priority Table

优先级表

PriorityDecisionImpact
CriticalChoose correct relation typesWrong type = broken inheritance
CriticalMap all actions to relationsUnmapped = always denied
ImportantConfigure hierarchyPropagationWithout it, no parent→child inheritance
ImportantUse semantic namesClarity for future maintainers
OptionalKeep schema minimalStart simple, expand as needed
优先级决策影响
关键选择正确的关系类型类型错误会导致继承失效
关键为所有操作映射对应的关系未映射的操作会始终被拒绝
重要配置hierarchyPropagation没有它,父级到子级的权限继承将无法生效
重要使用语义化名称便于未来维护人员理解
可选保持Schema最小化从简单开始,按需扩展

Schema Structure

Schema结构

typescript
import { defineSchema } from "polizy";

const schema = defineSchema({
  // 1. Define relationship types
  relations: {
    owner: { type: "direct" },     // Direct permission
    editor: { type: "direct" },
    viewer: { type: "direct" },
    member: { type: "group" },     // Group membership
    parent: { type: "hierarchy" }  // Parent-child resources
  },

  // 2. Map actions to relations that grant them
  actionToRelations: {
    delete: ["owner"],
    edit: ["owner", "editor"],
    view: ["owner", "editor", "viewer"]
  },

  // 3. Optional: Define hierarchy propagation
  hierarchyPropagation: {
    view: ["view"],   // view on parent → view on child
    edit: ["edit"]    // edit on parent → edit on child
  }
});
typescript
import { defineSchema } from "polizy";

const schema = defineSchema({
  // 1. 定义关系类型
  relations: {
    owner: { type: "direct" },     // 直接权限
    editor: { type: "direct" },
    viewer: { type: "direct" },
    member: { type: "group" },     // 群组成员
    parent: { type: "hierarchy" }  // 父级资源
  },

  // 2. 为操作映射对应的授权关系
  actionToRelations: {
    delete: ["owner"],
    edit: ["owner", "editor"],
    view: ["owner", "editor", "viewer"]
  },

  // 3. 可选:定义层级传播规则
  hierarchyPropagation: {
    view: ["view"],   // 父级的view权限 → 子级的view权限
    edit: ["edit"]    // 父级的edit权限 → 子级的edit权限
  }
});

Relation Types Quick Reference

关系类型速查

TypePurposeExampleUse When
direct
User → Resourcealice is owner of doc1Specific user needs specific resource access
group
User → Group membershipalice is member of engineeringTeam-based access, organizational structure
hierarchy
Resource → Parent resourcedoc1's parent is folder1Folder/file, project/task, inherited permissions
See RELATION-TYPES.md for detailed explanations.
类型用途示例适用场景
direct
用户→资源alice是doc1的owner特定用户需要特定资源的访问权限
group
用户→群组成员alice是engineering群组的member基于团队的访问权限,组织结构场景
hierarchy
资源→父级资源doc1的parent是folder1文件夹/文件、项目/任务等需要权限继承的场景
详细说明请查看RELATION-TYPES.md

Common Schema Patterns

常见Schema模式

Basic Document Access

基础文档访问权限

typescript
const schema = defineSchema({
  relations: {
    owner: { type: "direct" },
    editor: { type: "direct" },
    viewer: { type: "direct" },
  },
  actionToRelations: {
    delete: ["owner"],
    edit: ["owner", "editor"],
    view: ["owner", "editor", "viewer"],
  },
});
typescript
const schema = defineSchema({
  relations: {
    owner: { type: "direct" },
    editor: { type: "direct" },
    viewer: { type: "direct" },
  },
  actionToRelations: {
    delete: ["owner"],
    edit: ["owner", "editor"],
    view: ["owner", "editor", "viewer"],
  },
});

Team-Based Access

基于团队的访问权限

typescript
const schema = defineSchema({
  relations: {
    owner: { type: "direct" },
    editor: { type: "direct" },
    viewer: { type: "direct" },
    member: { type: "group" },  // Required for addMember()
  },
  actionToRelations: {
    manage: ["owner"],
    edit: ["owner", "editor"],
    view: ["owner", "editor", "viewer"],
  },
});
typescript
const schema = defineSchema({
  relations: {
    owner: { type: "direct" },
    editor: { type: "direct" },
    viewer: { type: "direct" },
    member: { type: "group" },  // 调用addMember()必需
  },
  actionToRelations: {
    manage: ["owner"],
    edit: ["owner", "editor"],
    view: ["owner", "editor", "viewer"],
  },
});

Hierarchical Resources (Folders/Files)

层级资源(文件夹/文件)

typescript
const schema = defineSchema({
  relations: {
    owner: { type: "direct" },
    editor: { type: "direct" },
    viewer: { type: "direct" },
    parent: { type: "hierarchy" },  // Required for setParent()
  },
  actionToRelations: {
    delete: ["owner"],
    edit: ["owner", "editor"],
    view: ["owner", "editor", "viewer"],
  },
  hierarchyPropagation: {
    view: ["view"],  // CRITICAL: Without this, no inheritance
    edit: ["edit"],
  },
});
typescript
const schema = defineSchema({
  relations: {
    owner: { type: "direct" },
    editor: { type: "direct" },
    viewer: { type: "direct" },
    parent: { type: "hierarchy" },  // 调用setParent()必需
  },
  actionToRelations: {
    delete: ["owner"],
    edit: ["owner", "editor"],
    view: ["owner", "editor", "viewer"],
  },
  hierarchyPropagation: {
    view: ["view"],  // 关键:没有此配置则无法实现继承
    edit: ["edit"],
  },
});

Full-Featured Schema

全功能Schema

typescript
const schema = defineSchema({
  relations: {
    // Direct permissions
    owner: { type: "direct" },
    editor: { type: "direct" },
    viewer: { type: "direct" },
    commenter: { type: "direct" },

    // Group membership
    member: { type: "group" },

    // Hierarchy
    parent: { type: "hierarchy" },
  },
  actionToRelations: {
    // Destructive
    delete: ["owner"],
    transfer: ["owner"],

    // Modification
    edit: ["owner", "editor"],
    comment: ["owner", "editor", "commenter"],

    // Read
    view: ["owner", "editor", "viewer", "commenter"],
  },
  hierarchyPropagation: {
    view: ["view"],
    edit: ["edit"],
    comment: ["comment"],
  },
});
typescript
const schema = defineSchema({
  relations: {
    // 直接权限
    owner: { type: "direct" },
    editor: { type: "direct" },
    viewer: { type: "direct" },
    commenter: { type: "direct" },

    // 群组成员
    member: { type: "group" },

    // 层级关系
    parent: { type: "hierarchy" },
  },
  actionToRelations: {
    // 破坏性操作
    delete: ["owner"],
    transfer: ["owner"],

    // 修改操作
    edit: ["owner", "editor"],
    comment: ["owner", "editor", "commenter"],

    // 读取操作
    view: ["owner", "editor", "viewer", "commenter"],
  },
  hierarchyPropagation: {
    view: ["view"],
    edit: ["edit"],
    comment: ["comment"],
  },
});

Decision Guide: Which Relation Type?

决策指南:选择哪种关系类型?

Need to grant access to a specific user on a specific resource?
  → Use "direct" relation (owner, editor, viewer)

Need users to inherit access from a team/department?
  → Use "group" relation (member)
  → Add users to groups with addMember()
  → Grant group access with allow()

Need child resources to inherit parent permissions?
  → Use "hierarchy" relation (parent)
  → Set parent with setParent()
  → Configure hierarchyPropagation
需要为特定用户授予特定资源的访问权限?
  → 使用"direct"关系(owner、editor、viewer)

需要让用户从团队/部门继承访问权限?
  → 使用"group"关系(member)
  → 使用addMember()将用户添加到群组
  → 使用allow()为群组授予访问权限

需要让子资源继承父级的权限?
  → 使用"hierarchy"关系(parent)
  → 使用setParent()设置父级资源
  → 配置hierarchyPropagation

Common Mistakes

常见错误

MistakeSymptomFix
Missing relation in actionToRelations
check()
returns false
Add relation to the action's array
No
member: { type: "group" }
addMember()
throws error
Add group relation to schema
No
parent: { type: "hierarchy" }
setParent()
throws error
Add hierarchy relation to schema
Missing hierarchyPropagationParent permissions don't flow to childrenAdd hierarchyPropagation config
Using generic names ("access")Can't distinguish read/writeUse semantic names (viewer, editor)
错误症状修复方案
actionToRelations中缺少关系
check()
返回false
将关系添加到对应操作的数组中
未定义
member: { type: "group" }
addMember()
抛出错误
在Schema中添加群组关系
未定义
parent: { type: "hierarchy" }
setParent()
抛出错误
在Schema中添加层级关系
缺少hierarchyPropagation配置父级权限无法传递到子级添加hierarchyPropagation配置
使用通用名称(如"access")无法区分读写权限使用语义化名称(如viewer、editor)

Schema Evolution

Schema演进

When adding to an existing schema:
typescript
// v1: Basic
const schemaV1 = defineSchema({
  relations: {
    owner: { type: "direct" },
    viewer: { type: "direct" },
  },
  actionToRelations: {
    edit: ["owner"],
    view: ["owner", "viewer"],
  },
});

// v2: Add editor role
const schemaV2 = defineSchema({
  relations: {
    owner: { type: "direct" },
    editor: { type: "direct" },  // NEW
    viewer: { type: "direct" },
  },
  actionToRelations: {
    edit: ["owner", "editor"],  // UPDATED
    view: ["owner", "editor", "viewer"],  // UPDATED
  },
});

// v3: Add groups
const schemaV3 = defineSchema({
  relations: {
    owner: { type: "direct" },
    editor: { type: "direct" },
    viewer: { type: "direct" },
    member: { type: "group" },  // NEW
  },
  actionToRelations: {
    edit: ["owner", "editor"],
    view: ["owner", "editor", "viewer"],
  },
});
Important: Existing tuples remain valid when you add new relations/actions. No migration needed.
当为现有Schema添加内容时:
typescript
// v1: 基础版本
const schemaV1 = defineSchema({
  relations: {
    owner: { type: "direct" },
    viewer: { type: "direct" },
  },
  actionToRelations: {
    edit: ["owner"],
    view: ["owner", "viewer"],
  },
});

// v2: 添加编辑者角色
const schemaV2 = defineSchema({
  relations: {
    owner: { type: "direct" },
    editor: { type: "direct" },  // 新增
    viewer: { type: "direct" },
  },
  actionToRelations: {
    edit: ["owner", "editor"],  // 更新
    view: ["owner", "editor", "viewer"],  // 更新
  },
});

// v3: 添加群组功能
const schemaV3 = defineSchema({
  relations: {
    owner: { type: "direct" },
    editor: { type: "direct" },
    viewer: { type: "direct" },
    member: { type: "group" },  // 新增
  },
  actionToRelations: {
    edit: ["owner", "editor"],
    view: ["owner", "editor", "viewer"],
  },
});
重要提示:添加新的关系或操作后,现有元组仍然有效,无需迁移。

Related Skills

相关技能

  • polizy-patterns - Implementation patterns
  • polizy-troubleshooting - Schema debugging
  • polizy-patterns - 实现模式
  • polizy-troubleshooting - Schema调试

References

参考资料

  • RELATION-TYPES.md - Deep dive into each relation type
  • SCHEMA-EXAMPLES.md - 10+ domain-specific schema examples
  • TYPE-SAFETY.md - TypeScript generics and type inference
  • RELATION-TYPES.md - 各关系类型的深度解析
  • SCHEMA-EXAMPLES.md - 10+领域特定的Schema示例
  • TYPE-SAFETY.md - TypeScript泛型与类型推断