@automate.ax/api-contract 0.33.1 → 0.35.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/dist/api-key.js CHANGED
@@ -19,7 +19,7 @@ export const apiKeyContract = {
19
19
  path: "/organizations/{organizationId}/api-keys",
20
20
  operationId: "createOrganizationApiKey",
21
21
  summary: "Create organization API key",
22
- description: "Creates an API key owned by the organization. The secret is returned once.",
22
+ description: "Creates an API key owned by the organization. Requires apiKey:create; the secret is returned once.",
23
23
  successStatus: 201,
24
24
  successDescription: "API key created.",
25
25
  tags: ["API Keys"],
@@ -35,7 +35,7 @@ export const apiKeyContract = {
35
35
  path: "/organizations/{organizationId}/api-keys/{keyId}",
36
36
  operationId: "deleteOrganizationApiKey",
37
37
  summary: "Delete organization API key",
38
- description: "Permanently revokes an organization API key.",
38
+ description: "Permanently revokes an organization API key. Requires apiKey:delete.",
39
39
  successStatus: 204,
40
40
  tags: ["API Keys"],
41
41
  })
@@ -50,7 +50,7 @@ export const apiKeyContract = {
50
50
  path: "/organizations/{organizationId}/api-keys",
51
51
  operationId: "listOrganizationApiKeys",
52
52
  summary: "List organization API keys",
53
- description: "Lists API keys owned by an organization.",
53
+ description: "Lists API keys owned by an organization. Requires apiKey:read.",
54
54
  tags: ["API Keys"],
55
55
  })
56
56
  .input(z.object({ organizationId: z.string() }))
@@ -61,7 +61,7 @@ export const apiKeyContract = {
61
61
  path: "/organizations/{organizationId}/api-keys/{keyId}",
62
62
  operationId: "updateOrganizationApiKey",
63
63
  summary: "Update organization API key",
64
- description: "Updates an organization API key's display name.",
64
+ description: "Updates an organization API key's display name. Requires apiKey:update.",
65
65
  tags: ["API Keys"],
66
66
  })
67
67
  .input(z.object({
package/dist/index.d.ts CHANGED
@@ -8,6 +8,7 @@ export { activeSubscriptionOutputSchema, createdInvitationOutputSchema, organiza
8
8
  export { projectOutputSchema } from "./project.js";
9
9
  export { reasonableNameSchema } from "./schemas.js";
10
10
  export { userOutputSchema } from "./auth.js";
11
+ export { managementPermissionStatement, managementRolePermissions, organizationApiKeyPermissions, type ManagementPermission, } from "./permissions.js";
11
12
  /** Procedures exposed by the public Node client and OpenAPI document. */
12
13
  export declare const publicContract: {
13
14
  apiKey: {
@@ -89,9 +90,15 @@ export declare const publicContract: {
89
90
  enterprise: "enterprise";
90
91
  }>;
91
92
  limits: import("zod").ZodObject<{
93
+ aiGenerations: import("zod").ZodNumber;
94
+ emailRecipients: import("zod").ZodNumber;
92
95
  projects: import("zod").ZodNumber;
93
96
  seats: import("zod").ZodNumber;
94
97
  }, import("zod/v4/core").$strip>;
98
+ usage: import("zod").ZodObject<{
99
+ aiGenerations: import("zod").ZodNumber;
100
+ emailRecipients: import("zod").ZodNumber;
101
+ }, import("zod/v4/core").$strip>;
95
102
  members: import("zod").ZodArray<import("zod").ZodObject<{
96
103
  id: import("zod").ZodString;
97
104
  userId: import("zod").ZodString;
@@ -173,9 +180,15 @@ export declare const publicContract: {
173
180
  enterprise: "enterprise";
174
181
  }>;
175
182
  limits: import("zod").ZodObject<{
183
+ aiGenerations: import("zod").ZodNumber;
184
+ emailRecipients: import("zod").ZodNumber;
176
185
  projects: import("zod").ZodNumber;
177
186
  seats: import("zod").ZodNumber;
178
187
  }, import("zod/v4/core").$strip>;
188
+ usage: import("zod").ZodObject<{
189
+ aiGenerations: import("zod").ZodNumber;
190
+ emailRecipients: import("zod").ZodNumber;
191
+ }, import("zod/v4/core").$strip>;
179
192
  }, import("zod/v4/core").$strip>>, Record<never, never>, Record<never, never>>;
180
193
  remove: import("@orpc/contract").ContractProcedureBuilderWithInputOutput<import("zod").ZodObject<{
181
194
  organizationId: import("zod").ZodString;
@@ -606,9 +619,15 @@ export declare const firstPartyContract: {
606
619
  enterprise: "enterprise";
607
620
  }>;
608
621
  limits: import("zod").ZodObject<{
622
+ aiGenerations: import("zod").ZodNumber;
623
+ emailRecipients: import("zod").ZodNumber;
609
624
  projects: import("zod").ZodNumber;
610
625
  seats: import("zod").ZodNumber;
611
626
  }, import("zod/v4/core").$strip>;
627
+ usage: import("zod").ZodObject<{
628
+ aiGenerations: import("zod").ZodNumber;
629
+ emailRecipients: import("zod").ZodNumber;
630
+ }, import("zod/v4/core").$strip>;
612
631
  members: import("zod").ZodArray<import("zod").ZodObject<{
613
632
  id: import("zod").ZodString;
614
633
  userId: import("zod").ZodString;
@@ -690,9 +709,15 @@ export declare const firstPartyContract: {
690
709
  enterprise: "enterprise";
691
710
  }>;
692
711
  limits: import("zod").ZodObject<{
712
+ aiGenerations: import("zod").ZodNumber;
713
+ emailRecipients: import("zod").ZodNumber;
693
714
  projects: import("zod").ZodNumber;
694
715
  seats: import("zod").ZodNumber;
695
716
  }, import("zod/v4/core").$strip>;
717
+ usage: import("zod").ZodObject<{
718
+ aiGenerations: import("zod").ZodNumber;
719
+ emailRecipients: import("zod").ZodNumber;
720
+ }, import("zod/v4/core").$strip>;
696
721
  }, import("zod/v4/core").$strip>>, Record<never, never>, Record<never, never>>;
697
722
  remove: import("@orpc/contract").ContractProcedureBuilderWithInputOutput<import("zod").ZodObject<{
698
723
  organizationId: import("zod").ZodString;
@@ -1455,9 +1480,15 @@ export declare const contract: {
1455
1480
  enterprise: "enterprise";
1456
1481
  }>;
1457
1482
  limits: import("zod").ZodObject<{
1483
+ aiGenerations: import("zod").ZodNumber;
1484
+ emailRecipients: import("zod").ZodNumber;
1458
1485
  projects: import("zod").ZodNumber;
1459
1486
  seats: import("zod").ZodNumber;
1460
1487
  }, import("zod/v4/core").$strip>;
1488
+ usage: import("zod").ZodObject<{
1489
+ aiGenerations: import("zod").ZodNumber;
1490
+ emailRecipients: import("zod").ZodNumber;
1491
+ }, import("zod/v4/core").$strip>;
1461
1492
  members: import("zod").ZodArray<import("zod").ZodObject<{
1462
1493
  id: import("zod").ZodString;
1463
1494
  userId: import("zod").ZodString;
@@ -1539,9 +1570,15 @@ export declare const contract: {
1539
1570
  enterprise: "enterprise";
1540
1571
  }>;
1541
1572
  limits: import("zod").ZodObject<{
1573
+ aiGenerations: import("zod").ZodNumber;
1574
+ emailRecipients: import("zod").ZodNumber;
1542
1575
  projects: import("zod").ZodNumber;
1543
1576
  seats: import("zod").ZodNumber;
1544
1577
  }, import("zod/v4/core").$strip>;
1578
+ usage: import("zod").ZodObject<{
1579
+ aiGenerations: import("zod").ZodNumber;
1580
+ emailRecipients: import("zod").ZodNumber;
1581
+ }, import("zod/v4/core").$strip>;
1545
1582
  }, import("zod/v4/core").$strip>>, Record<never, never>, Record<never, never>>;
1546
1583
  remove: import("@orpc/contract").ContractProcedureBuilderWithInputOutput<import("zod").ZodObject<{
1547
1584
  organizationId: import("zod").ZodString;
package/dist/index.js CHANGED
@@ -16,6 +16,7 @@ export { activeSubscriptionOutputSchema, createdInvitationOutputSchema, organiza
16
16
  export { projectOutputSchema } from "./project.js";
17
17
  export { reasonableNameSchema } from "./schemas.js";
18
18
  export { userOutputSchema } from "./auth.js";
19
+ export { managementPermissionStatement, managementRolePermissions, organizationApiKeyPermissions, } from "./permissions.js";
19
20
  /** Procedures exposed by the public Node client and OpenAPI document. */
20
21
  export const publicContract = {
21
22
  apiKey: apiKeyContract,
package/dist/org.d.ts CHANGED
@@ -42,9 +42,15 @@ export declare const organizationSummaryOutputSchema: z.ZodObject<{
42
42
  enterprise: "enterprise";
43
43
  }>;
44
44
  limits: z.ZodObject<{
45
+ aiGenerations: z.ZodNumber;
46
+ emailRecipients: z.ZodNumber;
45
47
  projects: z.ZodNumber;
46
48
  seats: z.ZodNumber;
47
49
  }, z.core.$strip>;
50
+ usage: z.ZodObject<{
51
+ aiGenerations: z.ZodNumber;
52
+ emailRecipients: z.ZodNumber;
53
+ }, z.core.$strip>;
48
54
  }, z.core.$strip>;
49
55
  export declare const organizationMemberOutputSchema: z.ZodObject<{
50
56
  id: z.ZodString;
@@ -103,9 +109,15 @@ export declare const organizationDetailsOutputSchema: z.ZodObject<{
103
109
  enterprise: "enterprise";
104
110
  }>;
105
111
  limits: z.ZodObject<{
112
+ aiGenerations: z.ZodNumber;
113
+ emailRecipients: z.ZodNumber;
106
114
  projects: z.ZodNumber;
107
115
  seats: z.ZodNumber;
108
116
  }, z.core.$strip>;
117
+ usage: z.ZodObject<{
118
+ aiGenerations: z.ZodNumber;
119
+ emailRecipients: z.ZodNumber;
120
+ }, z.core.$strip>;
109
121
  members: z.ZodArray<z.ZodObject<{
110
122
  id: z.ZodString;
111
123
  userId: z.ZodString;
@@ -199,9 +211,15 @@ export declare const orgContract: {
199
211
  enterprise: "enterprise";
200
212
  }>;
201
213
  limits: z.ZodObject<{
214
+ aiGenerations: z.ZodNumber;
215
+ emailRecipients: z.ZodNumber;
202
216
  projects: z.ZodNumber;
203
217
  seats: z.ZodNumber;
204
218
  }, z.core.$strip>;
219
+ usage: z.ZodObject<{
220
+ aiGenerations: z.ZodNumber;
221
+ emailRecipients: z.ZodNumber;
222
+ }, z.core.$strip>;
205
223
  members: z.ZodArray<z.ZodObject<{
206
224
  id: z.ZodString;
207
225
  userId: z.ZodString;
@@ -283,9 +301,15 @@ export declare const orgContract: {
283
301
  enterprise: "enterprise";
284
302
  }>;
285
303
  limits: z.ZodObject<{
304
+ aiGenerations: z.ZodNumber;
305
+ emailRecipients: z.ZodNumber;
286
306
  projects: z.ZodNumber;
287
307
  seats: z.ZodNumber;
288
308
  }, z.core.$strip>;
309
+ usage: z.ZodObject<{
310
+ aiGenerations: z.ZodNumber;
311
+ emailRecipients: z.ZodNumber;
312
+ }, z.core.$strip>;
289
313
  }, z.core.$strip>>, Record<never, never>, Record<never, never>>;
290
314
  remove: import("@orpc/contract").ContractProcedureBuilderWithInputOutput<z.ZodObject<{
291
315
  organizationId: z.ZodString;
package/dist/org.js CHANGED
@@ -26,9 +26,15 @@ export const organizationSummaryOutputSchema = z.object({
26
26
  activeSubscription: activeSubscriptionOutputSchema.nullable(),
27
27
  plan: z.enum(["free", "pro", "enterprise"]),
28
28
  limits: z.object({
29
+ aiGenerations: z.number(),
30
+ emailRecipients: z.number(),
29
31
  projects: z.number(),
30
32
  seats: z.number(),
31
33
  }),
34
+ usage: z.object({
35
+ aiGenerations: z.number(),
36
+ emailRecipients: z.number(),
37
+ }),
32
38
  });
33
39
  export const organizationMemberOutputSchema = z.object({
34
40
  id: z.string(),
@@ -92,7 +98,7 @@ export const orgContract = {
92
98
  path: "/organizations/{organizationId}",
93
99
  operationId: "deleteOrganization",
94
100
  summary: "Delete organization",
95
- description: "Deletes an organization and cancels its billing. Caller must be the organization owner.",
101
+ description: "Deletes an organization and cancels its billing. Requires organization:delete.",
96
102
  tags: ["Organizations"],
97
103
  successStatus: 204,
98
104
  })
@@ -115,7 +121,7 @@ export const orgContract = {
115
121
  path: "/organizations/{organizationId}/invitations",
116
122
  operationId: "createOrganizationInvitation",
117
123
  summary: "Invite organization member",
118
- description: "Creates a pending invitation for an email address. Caller must be an organization admin or owner.",
124
+ description: "Creates a pending invitation for an email address. Requires invitation:create.",
119
125
  successStatus: 201,
120
126
  successDescription: "Invitation created.",
121
127
  tags: ["Organizations"],
@@ -0,0 +1,61 @@
1
+ /** Management permissions understood by organization roles and API keys. */
2
+ export declare const managementPermissionStatement: {
3
+ readonly ac: readonly ["create", "read", "update", "delete"];
4
+ readonly account: readonly ["create", "read", "delete"];
5
+ readonly apiKey: readonly ["create", "read", "update", "delete"];
6
+ readonly authorization: readonly ["create", "read", "update"];
7
+ readonly billing: readonly ["read", "update"];
8
+ readonly deployment: readonly ["create", "read", "cancel"];
9
+ readonly invitation: readonly ["create", "read", "cancel"];
10
+ readonly member: readonly ["create", "read", "update", "delete", "leave"];
11
+ readonly organization: readonly ["read", "update", "delete"];
12
+ readonly project: readonly ["create", "read", "update", "delete"];
13
+ readonly team: readonly ["create", "update", "delete"];
14
+ };
15
+ export type ManagementPermission = {
16
+ [Resource in keyof typeof managementPermissionStatement]?: (typeof managementPermissionStatement)[Resource][number][];
17
+ };
18
+ /** Static organization roles are permission bundles, not authorization checks. */
19
+ export declare const managementRolePermissions: {
20
+ readonly admin: {
21
+ readonly ac: ["create", "read", "update", "delete"];
22
+ readonly account: ["create", "read", "delete"];
23
+ readonly apiKey: ["create", "read", "update", "delete"];
24
+ readonly authorization: ["create", "read", "update"];
25
+ readonly deployment: ["create", "read", "cancel"];
26
+ readonly invitation: ["create", "read", "cancel"];
27
+ readonly member: ["create", "read", "update", "delete", "leave"];
28
+ readonly organization: ["read", "update"];
29
+ readonly project: ["create", "read", "update", "delete"];
30
+ readonly team: ["create", "update", "delete"];
31
+ };
32
+ readonly member: {
33
+ readonly ac: ["read"];
34
+ readonly authorization: ["create", "read", "update"];
35
+ readonly deployment: ["create", "read", "cancel"];
36
+ readonly invitation: ["read"];
37
+ readonly member: ["read", "leave"];
38
+ readonly organization: ["read"];
39
+ readonly project: ["create", "read"];
40
+ };
41
+ readonly owner: {
42
+ readonly ac: ["create", "read", "update", "delete"];
43
+ readonly account: ["create", "read", "delete"];
44
+ readonly apiKey: ["create", "read", "update", "delete"];
45
+ readonly authorization: ["create", "read", "update"];
46
+ readonly billing: ["read", "update"];
47
+ readonly deployment: ["create", "read", "cancel"];
48
+ readonly invitation: ["create", "read", "cancel"];
49
+ readonly member: ["create", "read", "update", "delete"];
50
+ readonly organization: ["read", "update", "delete"];
51
+ readonly project: ["create", "read", "update", "delete"];
52
+ readonly team: ["create", "update", "delete"];
53
+ };
54
+ };
55
+ /** Explicit capabilities granted to newly issued organization API keys. */
56
+ export declare const organizationApiKeyPermissions: {
57
+ readonly account: ["create", "read", "delete"];
58
+ readonly authorization: ["create", "read", "update"];
59
+ readonly deployment: ["create", "read", "cancel"];
60
+ readonly project: ["create", "read", "update", "delete"];
61
+ };
@@ -0,0 +1,58 @@
1
+ /** Management permissions understood by organization roles and API keys. */
2
+ export const managementPermissionStatement = {
3
+ ac: ["create", "read", "update", "delete"],
4
+ account: ["create", "read", "delete"],
5
+ apiKey: ["create", "read", "update", "delete"],
6
+ authorization: ["create", "read", "update"],
7
+ billing: ["read", "update"],
8
+ deployment: ["create", "read", "cancel"],
9
+ invitation: ["create", "read", "cancel"],
10
+ member: ["create", "read", "update", "delete", "leave"],
11
+ organization: ["read", "update", "delete"],
12
+ project: ["create", "read", "update", "delete"],
13
+ team: ["create", "update", "delete"],
14
+ };
15
+ /** Static organization roles are permission bundles, not authorization checks. */
16
+ export const managementRolePermissions = {
17
+ admin: {
18
+ ac: ["create", "read", "update", "delete"],
19
+ account: ["create", "read", "delete"],
20
+ apiKey: ["create", "read", "update", "delete"],
21
+ authorization: ["create", "read", "update"],
22
+ deployment: ["create", "read", "cancel"],
23
+ invitation: ["create", "read", "cancel"],
24
+ member: ["create", "read", "update", "delete", "leave"],
25
+ organization: ["read", "update"],
26
+ project: ["create", "read", "update", "delete"],
27
+ team: ["create", "update", "delete"],
28
+ },
29
+ member: {
30
+ ac: ["read"],
31
+ authorization: ["create", "read", "update"],
32
+ deployment: ["create", "read", "cancel"],
33
+ invitation: ["read"],
34
+ member: ["read", "leave"],
35
+ organization: ["read"],
36
+ project: ["create", "read"],
37
+ },
38
+ owner: {
39
+ ac: ["create", "read", "update", "delete"],
40
+ account: ["create", "read", "delete"],
41
+ apiKey: ["create", "read", "update", "delete"],
42
+ authorization: ["create", "read", "update"],
43
+ billing: ["read", "update"],
44
+ deployment: ["create", "read", "cancel"],
45
+ invitation: ["create", "read", "cancel"],
46
+ member: ["create", "read", "update", "delete"],
47
+ organization: ["read", "update", "delete"],
48
+ project: ["create", "read", "update", "delete"],
49
+ team: ["create", "update", "delete"],
50
+ },
51
+ };
52
+ /** Explicit capabilities granted to newly issued organization API keys. */
53
+ export const organizationApiKeyPermissions = {
54
+ account: ["create", "read", "delete"],
55
+ authorization: ["create", "read", "update"],
56
+ deployment: ["create", "read", "cancel"],
57
+ project: ["create", "read", "update", "delete"],
58
+ };
package/dist/project.js CHANGED
@@ -28,7 +28,7 @@ export const projectContract = {
28
28
  path: "/organizations/{organizationId}/projects",
29
29
  operationId: "createProject",
30
30
  summary: "Create project",
31
- description: "Creates a project inside an organization the user belongs to.",
31
+ description: "Creates a project inside an organization. Requires project:create.",
32
32
  successStatus: 201,
33
33
  successDescription: "Project created.",
34
34
  tags: ["Projects"],
@@ -71,7 +71,7 @@ export const projectContract = {
71
71
  path: "/projects/{projectId}",
72
72
  operationId: "updateProject",
73
73
  summary: "Update project",
74
- description: "Updates project fields. Caller must be an organization admin or owner.",
74
+ description: "Updates project fields. Requires project:update.",
75
75
  successStatus: 204,
76
76
  tags: ["Projects"],
77
77
  })
@@ -86,7 +86,7 @@ export const projectContract = {
86
86
  path: "/projects/{projectId}",
87
87
  operationId: "deleteProject",
88
88
  summary: "Delete project",
89
- description: "Deletes a project. Caller must be an organization admin or owner.",
89
+ description: "Deletes a project. Requires project:delete.",
90
90
  tags: ["Projects"],
91
91
  successStatus: 204,
92
92
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automate.ax/api-contract",
3
- "version": "0.33.1",
3
+ "version": "0.35.0",
4
4
  "description": "Public oRPC contract for the Automate.ax API.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -27,7 +27,7 @@
27
27
  },
28
28
  "dependencies": {
29
29
  "@ai-sdk/gateway": "^4.0.46",
30
- "@automate.ax/codec": "0.33.1",
30
+ "@automate.ax/codec": "0.35.0",
31
31
  "@orpc/contract": "1.13.14",
32
32
  "zod": "^4.3.6"
33
33
  },
package/src/api-key.ts CHANGED
@@ -24,7 +24,7 @@ export const apiKeyContract = {
24
24
  operationId: "createOrganizationApiKey",
25
25
  summary: "Create organization API key",
26
26
  description:
27
- "Creates an API key owned by the organization. The secret is returned once.",
27
+ "Creates an API key owned by the organization. Requires apiKey:create; the secret is returned once.",
28
28
  successStatus: 201,
29
29
  successDescription: "API key created.",
30
30
  tags: ["API Keys"],
@@ -42,7 +42,8 @@ export const apiKeyContract = {
42
42
  path: "/organizations/{organizationId}/api-keys/{keyId}",
43
43
  operationId: "deleteOrganizationApiKey",
44
44
  summary: "Delete organization API key",
45
- description: "Permanently revokes an organization API key.",
45
+ description:
46
+ "Permanently revokes an organization API key. Requires apiKey:delete.",
46
47
  successStatus: 204,
47
48
  tags: ["API Keys"],
48
49
  })
@@ -59,7 +60,8 @@ export const apiKeyContract = {
59
60
  path: "/organizations/{organizationId}/api-keys",
60
61
  operationId: "listOrganizationApiKeys",
61
62
  summary: "List organization API keys",
62
- description: "Lists API keys owned by an organization.",
63
+ description:
64
+ "Lists API keys owned by an organization. Requires apiKey:read.",
63
65
  tags: ["API Keys"],
64
66
  })
65
67
  .input(z.object({ organizationId: z.string() }))
@@ -70,7 +72,8 @@ export const apiKeyContract = {
70
72
  path: "/organizations/{organizationId}/api-keys/{keyId}",
71
73
  operationId: "updateOrganizationApiKey",
72
74
  summary: "Update organization API key",
73
- description: "Updates an organization API key's display name.",
75
+ description:
76
+ "Updates an organization API key's display name. Requires apiKey:update.",
74
77
  tags: ["API Keys"],
75
78
  })
76
79
  .input(
package/src/index.ts CHANGED
@@ -48,6 +48,12 @@ export {
48
48
  export { projectOutputSchema } from "./project"
49
49
  export { reasonableNameSchema } from "./schemas"
50
50
  export { userOutputSchema } from "./auth"
51
+ export {
52
+ managementPermissionStatement,
53
+ managementRolePermissions,
54
+ organizationApiKeyPermissions,
55
+ type ManagementPermission,
56
+ } from "./permissions"
51
57
 
52
58
  /** Procedures exposed by the public Node client and OpenAPI document. */
53
59
  export const publicContract = {
package/src/org.ts CHANGED
@@ -30,9 +30,15 @@ export const organizationSummaryOutputSchema = z.object({
30
30
  activeSubscription: activeSubscriptionOutputSchema.nullable(),
31
31
  plan: z.enum(["free", "pro", "enterprise"]),
32
32
  limits: z.object({
33
+ aiGenerations: z.number(),
34
+ emailRecipients: z.number(),
33
35
  projects: z.number(),
34
36
  seats: z.number(),
35
37
  }),
38
+ usage: z.object({
39
+ aiGenerations: z.number(),
40
+ emailRecipients: z.number(),
41
+ }),
36
42
  })
37
43
 
38
44
  export const organizationMemberOutputSchema = z.object({
@@ -104,7 +110,7 @@ export const orgContract = {
104
110
  operationId: "deleteOrganization",
105
111
  summary: "Delete organization",
106
112
  description:
107
- "Deletes an organization and cancels its billing. Caller must be the organization owner.",
113
+ "Deletes an organization and cancels its billing. Requires organization:delete.",
108
114
  tags: ["Organizations"],
109
115
  successStatus: 204,
110
116
  })
@@ -129,7 +135,7 @@ export const orgContract = {
129
135
  operationId: "createOrganizationInvitation",
130
136
  summary: "Invite organization member",
131
137
  description:
132
- "Creates a pending invitation for an email address. Caller must be an organization admin or owner.",
138
+ "Creates a pending invitation for an email address. Requires invitation:create.",
133
139
  successStatus: 201,
134
140
  successDescription: "Invitation created.",
135
141
  tags: ["Organizations"],
@@ -0,0 +1,64 @@
1
+ /** Management permissions understood by organization roles and API keys. */
2
+ export const managementPermissionStatement = {
3
+ ac: ["create", "read", "update", "delete"],
4
+ account: ["create", "read", "delete"],
5
+ apiKey: ["create", "read", "update", "delete"],
6
+ authorization: ["create", "read", "update"],
7
+ billing: ["read", "update"],
8
+ deployment: ["create", "read", "cancel"],
9
+ invitation: ["create", "read", "cancel"],
10
+ member: ["create", "read", "update", "delete", "leave"],
11
+ organization: ["read", "update", "delete"],
12
+ project: ["create", "read", "update", "delete"],
13
+ team: ["create", "update", "delete"],
14
+ } as const
15
+
16
+ export type ManagementPermission = {
17
+ [Resource in keyof typeof managementPermissionStatement]?: (typeof managementPermissionStatement)[Resource][number][]
18
+ }
19
+
20
+ /** Static organization roles are permission bundles, not authorization checks. */
21
+ export const managementRolePermissions = {
22
+ admin: {
23
+ ac: ["create", "read", "update", "delete"],
24
+ account: ["create", "read", "delete"],
25
+ apiKey: ["create", "read", "update", "delete"],
26
+ authorization: ["create", "read", "update"],
27
+ deployment: ["create", "read", "cancel"],
28
+ invitation: ["create", "read", "cancel"],
29
+ member: ["create", "read", "update", "delete", "leave"],
30
+ organization: ["read", "update"],
31
+ project: ["create", "read", "update", "delete"],
32
+ team: ["create", "update", "delete"],
33
+ },
34
+ member: {
35
+ ac: ["read"],
36
+ authorization: ["create", "read", "update"],
37
+ deployment: ["create", "read", "cancel"],
38
+ invitation: ["read"],
39
+ member: ["read", "leave"],
40
+ organization: ["read"],
41
+ project: ["create", "read"],
42
+ },
43
+ owner: {
44
+ ac: ["create", "read", "update", "delete"],
45
+ account: ["create", "read", "delete"],
46
+ apiKey: ["create", "read", "update", "delete"],
47
+ authorization: ["create", "read", "update"],
48
+ billing: ["read", "update"],
49
+ deployment: ["create", "read", "cancel"],
50
+ invitation: ["create", "read", "cancel"],
51
+ member: ["create", "read", "update", "delete"],
52
+ organization: ["read", "update", "delete"],
53
+ project: ["create", "read", "update", "delete"],
54
+ team: ["create", "update", "delete"],
55
+ },
56
+ } as const satisfies Record<string, ManagementPermission>
57
+
58
+ /** Explicit capabilities granted to newly issued organization API keys. */
59
+ export const organizationApiKeyPermissions = {
60
+ account: ["create", "read", "delete"],
61
+ authorization: ["create", "read", "update"],
62
+ deployment: ["create", "read", "cancel"],
63
+ project: ["create", "read", "update", "delete"],
64
+ } as const satisfies ManagementPermission
package/src/project.ts CHANGED
@@ -31,7 +31,7 @@ export const projectContract = {
31
31
  operationId: "createProject",
32
32
  summary: "Create project",
33
33
  description:
34
- "Creates a project inside an organization the user belongs to.",
34
+ "Creates a project inside an organization. Requires project:create.",
35
35
  successStatus: 201,
36
36
  successDescription: "Project created.",
37
37
  tags: ["Projects"],
@@ -80,8 +80,7 @@ export const projectContract = {
80
80
  path: "/projects/{projectId}",
81
81
  operationId: "updateProject",
82
82
  summary: "Update project",
83
- description:
84
- "Updates project fields. Caller must be an organization admin or owner.",
83
+ description: "Updates project fields. Requires project:update.",
85
84
  successStatus: 204,
86
85
  tags: ["Projects"],
87
86
  })
@@ -98,8 +97,7 @@ export const projectContract = {
98
97
  path: "/projects/{projectId}",
99
98
  operationId: "deleteProject",
100
99
  summary: "Delete project",
101
- description:
102
- "Deletes a project. Caller must be an organization admin or owner.",
100
+ description: "Deletes a project. Requires project:delete.",
103
101
  tags: ["Projects"],
104
102
  successStatus: 204,
105
103
  })