Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions content/docs/concepts/architecture.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -144,12 +144,12 @@ That's the job of the other layers.

```typescript
// packages/crm/src/permissions/sales_rep.permission.ts
import type { PermissionSet } from '@objectstack/spec/security';
import { definePermissionSet } from '@objectstack/spec/security';

// A permission set is keyed by object name. Each object grants the four
// CRUD verbs (allowCreate / allowRead / allowEdit / allowDelete), and
// optional field-level security keyed by "object.field".
export const SalesRep: PermissionSet = {
export const SalesRep = definePermissionSet({
name: 'sales_rep',
isProfile: true,
objects: {
Expand All @@ -163,7 +163,7 @@ export const SalesRep: PermissionSet = {
fields: {
'customer.annual_revenue': { readable: true, editable: false }, // Read-only
},
};
});
```

### Example: Workflow Automation
Expand Down
10 changes: 5 additions & 5 deletions content/docs/concepts/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -150,9 +150,9 @@ Access control is declared as **permission set** metadata (the `PermissionSet` s

```typescript
// packages/crm/src/permissions/sales_rep.permission.ts
import type { PermissionSet } from '@objectstack/spec';
import { definePermissionSet } from '@objectstack/spec';

export const salesRep: PermissionSet = {
export const salesRep = definePermissionSet({
name: 'sales_rep',
label: 'Sales Rep',
isProfile: true,
Expand All @@ -167,10 +167,10 @@ export const salesRep: PermissionSet = {
fields: {
'customer.annual_revenue': { readable: true, editable: false }, // Read-only
},
};
});

// packages/crm/src/permissions/sales_manager.permission.ts
export const salesManager: PermissionSet = {
export const salesManager = definePermissionSet({
name: 'sales_manager',
label: 'Sales Manager',
isProfile: true,
Expand All @@ -182,7 +182,7 @@ export const salesManager: PermissionSet = {
allowDelete: true,
},
},
};
});
```

### Example: Flow Automation
Expand Down
6 changes: 3 additions & 3 deletions content/docs/getting-started/architecture.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -144,10 +144,10 @@ That's the job of the other layers.

```typescript
// src/permissions/sales_rep.permission.ts
import type { PermissionSet } from '@objectstack/spec';
import { definePermissionSet } from '@objectstack/spec';

// A permission set (here used as a profile) keyed by object and field.
export const SalesRepPermission: PermissionSet = {
export const SalesRepPermission = definePermissionSet({
name: 'sales_rep',
label: 'Sales Rep',
isProfile: true,
Expand All @@ -163,7 +163,7 @@ export const SalesRepPermission: PermissionSet = {
// <object>.<field> -> field-level security
'customer.annual_revenue': { readable: true, editable: false }, // Read-only
},
};
});
```

### Example: Workflow Automation
Expand Down
46 changes: 27 additions & 19 deletions content/docs/guides/security.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ A profile is modelled as a `PermissionSet` with `isProfile: true` (see
`PermissionSetSchema`.

```typescript
import type { PermissionSet } from '@objectstack/spec/security';
import { definePermissionSet } from '@objectstack/spec/security';

export const SalesRepProfile: PermissionSet = {
export const SalesRepProfile = definePermissionSet({
name: 'sales_rep',
label: 'Sales Representative',
isProfile: true,
Expand Down Expand Up @@ -101,7 +101,7 @@ export const SalesRepProfile: PermissionSet = {
app_admin: 'hidden', // Not visible
app_sales: 'visible', // Available
},
};
});
```

### Object Permission Levels
Expand Down Expand Up @@ -153,7 +153,9 @@ RLS (no compiler change; ADR-0055). Sharing rules still widen on top.
#### Sales Representative

```typescript
export const SalesRepProfile: PermissionSet = {
import { definePermissionSet } from '@objectstack/spec/security';

export const SalesRepProfile = definePermissionSet({
name: 'sales_rep',
isProfile: true,
objects: {
Expand All @@ -167,13 +169,15 @@ export const SalesRepProfile: PermissionSet = {
fields: {
'account.annual_revenue': { readable: true, editable: false }, // Read-only
},
};
});
```

#### Sales Manager

```typescript
export const SalesManagerProfile: PermissionSet = {
import { definePermissionSet } from '@objectstack/spec/security';

export const SalesManagerProfile = definePermissionSet({
name: 'sales_manager',
isProfile: true,
objects: {
Expand All @@ -187,13 +191,15 @@ export const SalesManagerProfile: PermissionSet = {
},
// ... full access to sales objects
},
};
});
```

#### Service Agent

```typescript
export const ServiceAgentProfile: PermissionSet = {
import { definePermissionSet } from '@objectstack/spec/security';

export const ServiceAgentProfile = definePermissionSet({
name: 'service_agent',
isProfile: true,
objects: {
Expand All @@ -206,7 +212,7 @@ export const ServiceAgentProfile: PermissionSet = {
'case.is_sla_violated': { readable: true, editable: false },
'case.resolution_time_hours': { readable: true, editable: false },
},
};
});
```

---
Expand All @@ -216,9 +222,9 @@ export const ServiceAgentProfile: PermissionSet = {
Permission sets extend profile permissions without changing the profile.

```typescript
import type { PermissionSet } from '@objectstack/spec/security';
import { definePermissionSet } from '@objectstack/spec/security';

export const AdvancedReportingPermissionSet: PermissionSet = {
export const AdvancedReportingPermissionSet = definePermissionSet({
name: 'advanced_reporting',
label: 'Advanced Reporting',

Expand All @@ -238,15 +244,15 @@ export const AdvancedReportingPermissionSet: PermissionSet = {

// System permissions are a flat array of capability strings
systemPermissions: ['run_reports', 'export_reports', 'create_dashboards'],
};
});

export const BulkDataPermissionSet: PermissionSet = {
export const BulkDataPermissionSet = definePermissionSet({
name: 'bulk_data_access',
label: 'Bulk Data Access',

objects: {},
systemPermissions: ['bulk_api', 'view_all_data'],
};
});
```

### Built-in Permission Sets
Expand Down Expand Up @@ -418,9 +424,9 @@ export const OrganizationDefaults = {
Share records based on field criteria:

```typescript
import type { SharingRule } from '@objectstack/spec/security';
import { defineSharingRule } from '@objectstack/spec/security';

export const AccountTeamSharingRule: SharingRule = {
export const AccountTeamSharingRule = defineSharingRule({
name: 'account_team_sharing',
label: 'Share Active Customers with Sales Team',
type: 'criteria',
Expand All @@ -437,7 +443,7 @@ export const AccountTeamSharingRule: SharingRule = {

// Access level granted: read | edit | full
accessLevel: 'edit',
};
});
```

#### Recipient types
Expand Down Expand Up @@ -466,7 +472,9 @@ evaluated (`afterInsert` / `afterUpdate`); `role_and_subordinates` walks the
Share based on record owner characteristics:

```typescript
export const OpportunityOwnerSharingRule: SharingRule = {
import { defineSharingRule } from '@objectstack/spec/security';

export const OpportunityOwnerSharingRule = defineSharingRule({
name: 'opportunity_owner_sharing',
label: 'Share Sales Rep Opportunities with Managers',
type: 'owner',
Expand All @@ -485,7 +493,7 @@ export const OpportunityOwnerSharingRule: SharingRule = {
},

accessLevel: 'read',
};
});
```

### Analytics and Dataset Read Scope
Expand Down
12 changes: 6 additions & 6 deletions content/docs/guides/standards.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -241,9 +241,9 @@ A profile is just a `PermissionSet` with `isProfile: true`. There is no separate
`Profile` type — both share the same `PermissionSetSchema`.

```typescript
import type { PermissionSet } from '@objectstack/spec/security';
import { definePermissionSet } from '@objectstack/spec/security';

export const MyProfile: PermissionSet = {
export const MyProfile = definePermissionSet({
name: 'profile_name',
label: 'Profile Label',
isProfile: true,
Expand Down Expand Up @@ -271,15 +271,15 @@ export const MyProfile: PermissionSet = {
app_sales: 'visible', // Visible
app_admin: 'hidden', // Hidden
},
};
});
```

### Sharing Rule Pattern

```typescript
import type { SharingRule } from '@objectstack/spec/security';
import { defineSharingRule } from '@objectstack/spec/security';

export const MySharingRule: SharingRule = {
export const MySharingRule = defineSharingRule({
name: 'rule_name',
object: 'object_name',
type: 'criteria', // 'criteria' | 'owner'
Expand All @@ -294,7 +294,7 @@ export const MySharingRule: SharingRule = {
},

accessLevel: 'edit', // 'read' | 'edit' | 'full'
};
});
```

---
Expand Down
6 changes: 3 additions & 3 deletions content/docs/protocol/objectui/record-alert.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ Common use cases:
`record:alert` is registered as a slot component in the slotted page schema. Add it to the `alerts` slot of your `*.page.ts`:

```ts
import type { Page } from '@objectstack/spec/ui';
import { definePage } from '@objectstack/spec/ui';

export const SysUserDetailPage: Page = {
export const SysUserDetailPage = definePage({
name: 'sys_user_detail',
label: 'User',
object: 'sys_user',
Expand All @@ -70,7 +70,7 @@ export const SysUserDetailPage: Page = {
],
// …other slots: header, actions, highlights, details, tabs, discussion
},
};
});
```

The `alerts` slot is rendered between the page header (`header/actions`) and the highlights strip — the standard enterprise UX placement for contextual notices.
Expand Down
Loading