@checkstack/catalog-common 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +75 -0
- package/package.json +1 -1
- package/src/access.ts +69 -0
- package/src/index.ts +1 -1
- package/src/rpc-contract.ts +19 -28
- package/src/permissions.ts +0 -17
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,80 @@
|
|
|
1
1
|
# @checkstack/catalog-common
|
|
2
2
|
|
|
3
|
+
## 1.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 9faec1f: # Unified AccessRule Terminology Refactoring
|
|
8
|
+
|
|
9
|
+
This release completes a comprehensive terminology refactoring from "permission" to "accessRule" across the entire codebase, establishing a consistent and modern access control vocabulary.
|
|
10
|
+
|
|
11
|
+
## Changes
|
|
12
|
+
|
|
13
|
+
### Core Infrastructure (`@checkstack/common`)
|
|
14
|
+
|
|
15
|
+
- Introduced `AccessRule` interface as the primary access control type
|
|
16
|
+
- Added `accessPair()` helper for creating read/manage access rule pairs
|
|
17
|
+
- Added `access()` builder for individual access rules
|
|
18
|
+
- Replaced `Permission` type with `AccessRule` throughout
|
|
19
|
+
|
|
20
|
+
### API Changes
|
|
21
|
+
|
|
22
|
+
- `env.registerPermissions()` → `env.registerAccessRules()`
|
|
23
|
+
- `meta.permissions` → `meta.access` in RPC contracts
|
|
24
|
+
- `usePermission()` → `useAccess()` in frontend hooks
|
|
25
|
+
- Route `permission:` field → `accessRule:` field
|
|
26
|
+
|
|
27
|
+
### UI Changes
|
|
28
|
+
|
|
29
|
+
- "Roles & Permissions" tab → "Roles & Access Rules"
|
|
30
|
+
- "You don't have permission..." → "You don't have access..."
|
|
31
|
+
- All permission-related UI text updated
|
|
32
|
+
|
|
33
|
+
### Documentation & Templates
|
|
34
|
+
|
|
35
|
+
- Updated 18 documentation files with AccessRule terminology
|
|
36
|
+
- Updated 7 scaffolding templates with `accessPair()` pattern
|
|
37
|
+
- All code examples use new AccessRule API
|
|
38
|
+
|
|
39
|
+
## Migration Guide
|
|
40
|
+
|
|
41
|
+
### Backend Plugins
|
|
42
|
+
|
|
43
|
+
```diff
|
|
44
|
+
- import { permissionList } from "./permissions";
|
|
45
|
+
- env.registerPermissions(permissionList);
|
|
46
|
+
+ import { accessRules } from "./access";
|
|
47
|
+
+ env.registerAccessRules(accessRules);
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### RPC Contracts
|
|
51
|
+
|
|
52
|
+
```diff
|
|
53
|
+
- .meta({ userType: "user", permissions: [permissions.read.id] })
|
|
54
|
+
+ .meta({ userType: "user", access: [access.read] })
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Frontend Hooks
|
|
58
|
+
|
|
59
|
+
```diff
|
|
60
|
+
- const canRead = accessApi.usePermission(permissions.read.id);
|
|
61
|
+
+ const canRead = accessApi.useAccess(access.read);
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Routes
|
|
65
|
+
|
|
66
|
+
```diff
|
|
67
|
+
- permission: permissions.entityRead.id,
|
|
68
|
+
+ accessRule: access.read,
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Patch Changes
|
|
72
|
+
|
|
73
|
+
- Updated dependencies [9faec1f]
|
|
74
|
+
- Updated dependencies [f533141]
|
|
75
|
+
- @checkstack/common@0.2.0
|
|
76
|
+
- @checkstack/frontend-api@0.1.0
|
|
77
|
+
|
|
3
78
|
## 1.0.0
|
|
4
79
|
|
|
5
80
|
### Major Changes
|
package/package.json
CHANGED
package/src/access.ts
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { accessPair } from "@checkstack/common";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Access rules for the Catalog plugin.
|
|
5
|
+
*
|
|
6
|
+
* Systems have instance-level access control (team-based filtering).
|
|
7
|
+
* Groups and views are global (no team-based filtering).
|
|
8
|
+
*/
|
|
9
|
+
export const catalogAccess = {
|
|
10
|
+
/**
|
|
11
|
+
* System access with team-based filtering.
|
|
12
|
+
* - Read: View systems (filtered by team grants if no global access)
|
|
13
|
+
* - Manage: Create, update, delete systems
|
|
14
|
+
*/
|
|
15
|
+
system: accessPair(
|
|
16
|
+
"system",
|
|
17
|
+
{
|
|
18
|
+
read: "View systems in catalog",
|
|
19
|
+
manage: "Create, update, and delete systems",
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
idParam: "systemId",
|
|
23
|
+
listKey: "systems",
|
|
24
|
+
readIsDefault: true,
|
|
25
|
+
readIsPublic: true,
|
|
26
|
+
}
|
|
27
|
+
),
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Group access (global, no team-based filtering).
|
|
31
|
+
*/
|
|
32
|
+
group: accessPair(
|
|
33
|
+
"group",
|
|
34
|
+
{
|
|
35
|
+
read: "View groups",
|
|
36
|
+
manage: "Create, update, and delete groups",
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
readIsDefault: true,
|
|
40
|
+
readIsPublic: true,
|
|
41
|
+
}
|
|
42
|
+
),
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* View access (global, user-only).
|
|
46
|
+
*/
|
|
47
|
+
view: accessPair(
|
|
48
|
+
"view",
|
|
49
|
+
{
|
|
50
|
+
read: "View saved views",
|
|
51
|
+
manage: "Manage saved views",
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
readIsDefault: true,
|
|
55
|
+
}
|
|
56
|
+
),
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* All access rules for registration with the plugin system.
|
|
61
|
+
*/
|
|
62
|
+
export const catalogAccessRules = [
|
|
63
|
+
catalogAccess.system.read,
|
|
64
|
+
catalogAccess.system.manage,
|
|
65
|
+
catalogAccess.group.read,
|
|
66
|
+
catalogAccess.group.manage,
|
|
67
|
+
catalogAccess.view.read,
|
|
68
|
+
catalogAccess.view.manage,
|
|
69
|
+
];
|
package/src/index.ts
CHANGED
package/src/rpc-contract.ts
CHANGED
|
@@ -1,22 +1,16 @@
|
|
|
1
1
|
import { oc } from "@orpc/contract";
|
|
2
2
|
import {
|
|
3
3
|
createClientDefinition,
|
|
4
|
-
createResourceAccess,
|
|
5
|
-
createResourceAccessList,
|
|
6
4
|
type ProcedureMetadata,
|
|
7
5
|
} from "@checkstack/common";
|
|
8
6
|
import { pluginMetadata } from "./plugin-metadata";
|
|
9
7
|
import { z } from "zod";
|
|
10
8
|
import { SystemSchema, GroupSchema, ViewSchema } from "./types";
|
|
11
|
-
import {
|
|
9
|
+
import { catalogAccess } from "./access";
|
|
12
10
|
|
|
13
11
|
// Base builder with full metadata support
|
|
14
12
|
const _base = oc.$meta<ProcedureMetadata>({});
|
|
15
13
|
|
|
16
|
-
// Resource access configurations for team-based access control
|
|
17
|
-
const systemAccess = createResourceAccess("system", "systemId");
|
|
18
|
-
const systemListAccess = createResourceAccessList("system", "systems");
|
|
19
|
-
|
|
20
14
|
// Input schemas that match the service layer expectations
|
|
21
15
|
const CreateSystemInputSchema = z.object({
|
|
22
16
|
name: z.string(),
|
|
@@ -57,14 +51,13 @@ const CreateViewInputSchema = z.object({
|
|
|
57
51
|
// Catalog RPC Contract using oRPC's contract-first pattern
|
|
58
52
|
export const catalogContract = {
|
|
59
53
|
// ==========================================================================
|
|
60
|
-
// ENTITY READ ENDPOINTS (userType: "public" - accessible by anyone with
|
|
54
|
+
// ENTITY READ ENDPOINTS (userType: "public" - accessible by anyone with access)
|
|
61
55
|
// ==========================================================================
|
|
62
56
|
|
|
63
57
|
getEntities: _base
|
|
64
58
|
.meta({
|
|
65
59
|
userType: "public",
|
|
66
|
-
|
|
67
|
-
resourceAccess: [systemListAccess],
|
|
60
|
+
access: [catalogAccess.system.read],
|
|
68
61
|
})
|
|
69
62
|
.output(
|
|
70
63
|
z.object({
|
|
@@ -76,32 +69,30 @@ export const catalogContract = {
|
|
|
76
69
|
getSystems: _base
|
|
77
70
|
.meta({
|
|
78
71
|
userType: "public",
|
|
79
|
-
|
|
80
|
-
resourceAccess: [systemListAccess],
|
|
72
|
+
access: [catalogAccess.system.read],
|
|
81
73
|
})
|
|
82
74
|
.output(z.object({ systems: z.array(SystemSchema) })),
|
|
83
75
|
|
|
84
76
|
getSystem: _base
|
|
85
77
|
.meta({
|
|
86
78
|
userType: "public",
|
|
87
|
-
|
|
88
|
-
resourceAccess: [systemAccess],
|
|
79
|
+
access: [catalogAccess.system.read],
|
|
89
80
|
})
|
|
90
81
|
.input(z.object({ systemId: z.string() }))
|
|
91
82
|
.output(SystemSchema.nullable()),
|
|
92
83
|
|
|
93
84
|
getGroups: _base
|
|
94
|
-
.meta({ userType: "public",
|
|
85
|
+
.meta({ userType: "public", access: [catalogAccess.group.read] })
|
|
95
86
|
.output(z.array(GroupSchema)),
|
|
96
87
|
|
|
97
88
|
// ==========================================================================
|
|
98
|
-
// SYSTEM MANAGEMENT (userType: "authenticated" with manage
|
|
89
|
+
// SYSTEM MANAGEMENT (userType: "authenticated" with manage access)
|
|
99
90
|
// ==========================================================================
|
|
100
91
|
|
|
101
92
|
createSystem: _base
|
|
102
93
|
.meta({
|
|
103
94
|
userType: "authenticated",
|
|
104
|
-
|
|
95
|
+
access: [catalogAccess.system.manage],
|
|
105
96
|
})
|
|
106
97
|
.input(CreateSystemInputSchema)
|
|
107
98
|
.output(SystemSchema),
|
|
@@ -109,7 +100,7 @@ export const catalogContract = {
|
|
|
109
100
|
updateSystem: _base
|
|
110
101
|
.meta({
|
|
111
102
|
userType: "authenticated",
|
|
112
|
-
|
|
103
|
+
access: [catalogAccess.system.manage],
|
|
113
104
|
})
|
|
114
105
|
.input(UpdateSystemInputSchema)
|
|
115
106
|
.output(SystemSchema),
|
|
@@ -117,19 +108,19 @@ export const catalogContract = {
|
|
|
117
108
|
deleteSystem: _base
|
|
118
109
|
.meta({
|
|
119
110
|
userType: "authenticated",
|
|
120
|
-
|
|
111
|
+
access: [catalogAccess.system.manage],
|
|
121
112
|
})
|
|
122
113
|
.input(z.string())
|
|
123
114
|
.output(z.object({ success: z.boolean() })),
|
|
124
115
|
|
|
125
116
|
// ==========================================================================
|
|
126
|
-
// GROUP MANAGEMENT (userType: "authenticated" with manage
|
|
117
|
+
// GROUP MANAGEMENT (userType: "authenticated" with manage access)
|
|
127
118
|
// ==========================================================================
|
|
128
119
|
|
|
129
120
|
createGroup: _base
|
|
130
121
|
.meta({
|
|
131
122
|
userType: "authenticated",
|
|
132
|
-
|
|
123
|
+
access: [catalogAccess.group.manage],
|
|
133
124
|
})
|
|
134
125
|
.input(CreateGroupInputSchema)
|
|
135
126
|
.output(GroupSchema),
|
|
@@ -137,7 +128,7 @@ export const catalogContract = {
|
|
|
137
128
|
updateGroup: _base
|
|
138
129
|
.meta({
|
|
139
130
|
userType: "authenticated",
|
|
140
|
-
|
|
131
|
+
access: [catalogAccess.group.manage],
|
|
141
132
|
})
|
|
142
133
|
.input(UpdateGroupInputSchema)
|
|
143
134
|
.output(GroupSchema),
|
|
@@ -145,19 +136,19 @@ export const catalogContract = {
|
|
|
145
136
|
deleteGroup: _base
|
|
146
137
|
.meta({
|
|
147
138
|
userType: "authenticated",
|
|
148
|
-
|
|
139
|
+
access: [catalogAccess.group.manage],
|
|
149
140
|
})
|
|
150
141
|
.input(z.string())
|
|
151
142
|
.output(z.object({ success: z.boolean() })),
|
|
152
143
|
|
|
153
144
|
// ==========================================================================
|
|
154
|
-
// SYSTEM-GROUP RELATIONSHIPS (userType: "authenticated" with manage
|
|
145
|
+
// SYSTEM-GROUP RELATIONSHIPS (userType: "authenticated" with manage access)
|
|
155
146
|
// ==========================================================================
|
|
156
147
|
|
|
157
148
|
addSystemToGroup: _base
|
|
158
149
|
.meta({
|
|
159
150
|
userType: "authenticated",
|
|
160
|
-
|
|
151
|
+
access: [catalogAccess.system.manage],
|
|
161
152
|
})
|
|
162
153
|
.input(
|
|
163
154
|
z.object({
|
|
@@ -170,7 +161,7 @@ export const catalogContract = {
|
|
|
170
161
|
removeSystemFromGroup: _base
|
|
171
162
|
.meta({
|
|
172
163
|
userType: "authenticated",
|
|
173
|
-
|
|
164
|
+
access: [catalogAccess.system.manage],
|
|
174
165
|
})
|
|
175
166
|
.input(
|
|
176
167
|
z.object({
|
|
@@ -185,11 +176,11 @@ export const catalogContract = {
|
|
|
185
176
|
// ==========================================================================
|
|
186
177
|
|
|
187
178
|
getViews: _base
|
|
188
|
-
.meta({ userType: "user",
|
|
179
|
+
.meta({ userType: "user", access: [catalogAccess.view.read] })
|
|
189
180
|
.output(z.array(ViewSchema)),
|
|
190
181
|
|
|
191
182
|
createView: _base
|
|
192
|
-
.meta({ userType: "user",
|
|
183
|
+
.meta({ userType: "user", access: [catalogAccess.view.manage] })
|
|
193
184
|
.input(CreateViewInputSchema)
|
|
194
185
|
.output(ViewSchema),
|
|
195
186
|
|
package/src/permissions.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { createPermission } from "@checkstack/common";
|
|
2
|
-
|
|
3
|
-
export const permissions = {
|
|
4
|
-
catalogRead: createPermission(
|
|
5
|
-
"catalog",
|
|
6
|
-
"read",
|
|
7
|
-
"Read Catalog (Systems and Groups)",
|
|
8
|
-
{ isAuthenticatedDefault: true, isPublicDefault: true }
|
|
9
|
-
),
|
|
10
|
-
catalogManage: createPermission(
|
|
11
|
-
"catalog",
|
|
12
|
-
"manage",
|
|
13
|
-
"Full management of Catalog (Systems and Groups)"
|
|
14
|
-
),
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
export const permissionList = Object.values(permissions);
|