@checkstack/catalog-common 1.2.5 → 1.2.7

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 CHANGED
@@ -1,5 +1,24 @@
1
1
  # @checkstack/catalog-common
2
2
 
3
+ ## 1.2.7
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [f676e11]
8
+ - @checkstack/common@0.6.2
9
+ - @checkstack/auth-common@0.5.5
10
+ - @checkstack/frontend-api@0.3.5
11
+
12
+ ## 1.2.6
13
+
14
+ ### Patch Changes
15
+
16
+ - e5079e1: Add contacts management to system editor
17
+
18
+ - **catalog-frontend**: New `ContactsEditor` component allows adding/removing platform users and external mailboxes as system contacts directly from the system editor dialog
19
+ - **catalog-common**: Added `instanceAccess` override to contacts RPC endpoints for correct single-resource RLAC checking
20
+ - **ui**: Fixed Tabs component to use `type="button"` to prevent form submission when used inside forms
21
+
3
22
  ## 1.2.5
4
23
 
5
24
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@checkstack/catalog-common",
3
- "version": "1.2.5",
3
+ "version": "1.2.7",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -8,15 +8,16 @@
8
8
  }
9
9
  },
10
10
  "dependencies": {
11
- "@checkstack/common": "0.6.0",
12
- "@checkstack/frontend-api": "0.3.3",
11
+ "@checkstack/common": "0.6.1",
12
+ "@checkstack/auth-common": "0.5.4",
13
+ "@checkstack/frontend-api": "0.3.4",
13
14
  "@orpc/contract": "^1.13.2",
14
15
  "zod": "^4.2.1"
15
16
  },
16
17
  "devDependencies": {
17
18
  "typescript": "^5.7.2",
18
- "@checkstack/tsconfig": "0.0.2",
19
- "@checkstack/scripts": "0.1.0"
19
+ "@checkstack/tsconfig": "0.0.3",
20
+ "@checkstack/scripts": "0.1.1"
20
21
  },
21
22
  "scripts": {
22
23
  "typecheck": "tsc --noEmit",
@@ -1,14 +1,19 @@
1
1
  import { createClientDefinition, proc } from "@checkstack/common";
2
2
  import { pluginMetadata } from "./plugin-metadata";
3
3
  import { z } from "zod";
4
- import { SystemSchema, GroupSchema, ViewSchema } from "./types";
4
+ import {
5
+ SystemSchema,
6
+ GroupSchema,
7
+ ViewSchema,
8
+ SystemContactSchema,
9
+ ContactTypeSchema,
10
+ } from "./types";
5
11
  import { catalogAccess } from "./access";
6
12
 
7
13
  // Input schemas that match the service layer expectations
8
14
  const CreateSystemInputSchema = z.object({
9
15
  name: z.string(),
10
16
  description: z.string().optional(),
11
- owner: z.string().optional(),
12
17
  metadata: z.record(z.string(), z.unknown()).optional(),
13
18
  });
14
19
 
@@ -17,7 +22,6 @@ const UpdateSystemInputSchema = z.object({
17
22
  data: z.object({
18
23
  name: z.string().optional(),
19
24
  description: z.string().nullable().optional(),
20
- owner: z.string().nullable().optional(),
21
25
  metadata: z.record(z.string(), z.unknown()).nullable().optional(),
22
26
  }),
23
27
  });
@@ -55,7 +59,7 @@ export const catalogContract = {
55
59
  z.object({
56
60
  systems: z.array(SystemSchema),
57
61
  groups: z.array(GroupSchema),
58
- })
62
+ }),
59
63
  ),
60
64
 
61
65
  getSystems: proc({
@@ -106,6 +110,44 @@ export const catalogContract = {
106
110
  .input(z.string())
107
111
  .output(z.object({ success: z.boolean() })),
108
112
 
113
+ // ==========================================================================
114
+ // SYSTEM CONTACTS MANAGEMENT
115
+ // ==========================================================================
116
+
117
+ getSystemContacts: proc({
118
+ operationType: "query",
119
+ userType: "public",
120
+ access: [catalogAccess.system.read],
121
+ instanceAccess: { idParam: "systemId" },
122
+ })
123
+ .input(z.object({ systemId: z.string() }))
124
+ .output(z.array(SystemContactSchema)),
125
+
126
+ addSystemContact: proc({
127
+ operationType: "mutation",
128
+ userType: "authenticated",
129
+ access: [catalogAccess.system.manage],
130
+ instanceAccess: { idParam: "systemId" },
131
+ })
132
+ .input(
133
+ z.object({
134
+ systemId: z.string(),
135
+ type: ContactTypeSchema,
136
+ userId: z.string().optional(),
137
+ email: z.string().email().optional(),
138
+ label: z.string().optional(),
139
+ }),
140
+ )
141
+ .output(SystemContactSchema),
142
+
143
+ removeSystemContact: proc({
144
+ operationType: "mutation",
145
+ userType: "authenticated",
146
+ access: [catalogAccess.system.manage],
147
+ })
148
+ .input(z.string())
149
+ .output(z.object({ success: z.boolean() })),
150
+
109
151
  // ==========================================================================
110
152
  // GROUP MANAGEMENT (userType: "authenticated" with manage access)
111
153
  // ==========================================================================
@@ -147,7 +189,7 @@ export const catalogContract = {
147
189
  z.object({
148
190
  groupId: z.string(),
149
191
  systemId: z.string(),
150
- })
192
+ }),
151
193
  )
152
194
  .output(z.object({ success: z.boolean() })),
153
195
 
@@ -160,7 +202,7 @@ export const catalogContract = {
160
202
  z.object({
161
203
  groupId: z.string(),
162
204
  systemId: z.string(),
163
- })
205
+ }),
164
206
  )
165
207
  .output(z.object({ success: z.boolean() })),
166
208
 
@@ -218,9 +260,9 @@ export const catalogContract = {
218
260
  .boolean()
219
261
  .optional()
220
262
  .describe(
221
- "If true, also notify subscribers of groups that contain this system"
263
+ "If true, also notify subscribers of groups that contain this system",
222
264
  ),
223
- })
265
+ }),
224
266
  )
225
267
  .output(z.object({ notifiedCount: z.number() })),
226
268
  };
@@ -232,5 +274,5 @@ export type CatalogContract = typeof catalogContract;
232
274
  // Use: const client = rpcApi.forPlugin(CatalogApi);
233
275
  export const CatalogApi = createClientDefinition(
234
276
  catalogContract,
235
- pluginMetadata
277
+ pluginMetadata,
236
278
  );
package/src/types.ts CHANGED
@@ -8,13 +8,44 @@ export const SystemSchema = z.object({
8
8
  id: z.string(),
9
9
  name: z.string(),
10
10
  description: z.string().nullable(),
11
- owner: z.string().nullable(),
12
11
  metadata: z.record(z.string(), z.unknown()).nullable(),
13
12
  createdAt: z.date(),
14
13
  updatedAt: z.date(),
15
14
  });
16
15
  export type System = z.infer<typeof SystemSchema>;
17
16
 
17
+ // Contact Types
18
+ export const ContactTypeSchema = z.enum(["user", "mailbox"]);
19
+ export type ContactType = z.infer<typeof ContactTypeSchema>;
20
+
21
+ // Base fields shared by all contacts
22
+ const SystemContactBaseSchema = z.object({
23
+ id: z.string(),
24
+ systemId: z.string(),
25
+ label: z.string().nullable(),
26
+ createdAt: z.date(),
27
+ });
28
+
29
+ // User contact: requires userId, includes resolved profile
30
+ const UserContactSchema = SystemContactBaseSchema.extend({
31
+ type: z.literal("user"),
32
+ userId: z.string(),
33
+ userName: z.string().optional(),
34
+ userEmail: z.string().optional(),
35
+ });
36
+
37
+ // Mailbox contact: requires email
38
+ const MailboxContactSchema = SystemContactBaseSchema.extend({
39
+ type: z.literal("mailbox"),
40
+ email: z.string(),
41
+ });
42
+
43
+ export const SystemContactSchema = z.discriminatedUnion("type", [
44
+ UserContactSchema,
45
+ MailboxContactSchema,
46
+ ]);
47
+ export type SystemContact = z.infer<typeof SystemContactSchema>;
48
+
18
49
  export const GroupSchema = z.object({
19
50
  id: z.string(),
20
51
  name: z.string(),