@elevasis/core 0.32.0 → 0.33.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.
@@ -123,6 +123,7 @@ declare const PERMISSIONS: {
123
123
  readonly SECRETS_MANAGE: "secrets.manage";
124
124
  readonly OPERATIONS_READ: "operations.read";
125
125
  readonly OPERATIONS_MANAGE: "operations.manage";
126
+ readonly SALES_LEAD_GEN_MANAGE: "sales.lead-gen.manage";
126
127
  readonly ACQUISITION_MANAGE: "acquisition.manage";
127
128
  readonly PROJECTS_MANAGE: "projects.manage";
128
129
  readonly CLIENTS_MANAGE: "clients.manage";
@@ -5262,6 +5263,10 @@ declare const AccessKeys: {
5262
5263
  readonly systemPath: "permission.operations";
5263
5264
  readonly action: "manage";
5264
5265
  };
5266
+ readonly leadGenManage: {
5267
+ readonly systemPath: "sales.lead-gen";
5268
+ readonly action: "manage";
5269
+ };
5265
5270
  readonly acquisitionManage: {
5266
5271
  readonly systemPath: "permission.acquisition";
5267
5272
  readonly action: "manage";
@@ -35,6 +35,7 @@ var PERMISSIONS = {
35
35
  SECRETS_MANAGE: "secrets.manage",
36
36
  OPERATIONS_READ: "operations.read",
37
37
  OPERATIONS_MANAGE: "operations.manage",
38
+ SALES_LEAD_GEN_MANAGE: "sales.lead-gen.manage",
38
39
  ACQUISITION_MANAGE: "acquisition.manage",
39
40
  PROJECTS_MANAGE: "projects.manage",
40
41
  CLIENTS_MANAGE: "clients.manage"
@@ -80,6 +81,11 @@ var PERMISSION_CATALOG = [
80
81
  description: "Run and modify executions, sessions, schedules, queue",
81
82
  isOrgGrantable: true
82
83
  },
84
+ {
85
+ key: "sales.lead-gen.manage",
86
+ description: "Operate Lead Gen lists and list-builder workflows",
87
+ isOrgGrantable: true
88
+ },
83
89
  {
84
90
  key: "acquisition.manage",
85
91
  description: "Create, update, and delete acquisition records (acq_companies, acq_contacts, acq_deals, acq_lists*, acq_content*, acquisition storage files)",
@@ -421,6 +427,7 @@ var AccessKeys = {
421
427
  secretsManage: { systemPath: "permission.secrets", action: "manage" },
422
428
  operationsRead: { systemPath: "permission.operations", action: DEFAULT_ACCESS_ACTION },
423
429
  operationsManage: { systemPath: "permission.operations", action: "manage" },
430
+ leadGenManage: { systemPath: "sales.lead-gen", action: "manage" },
424
431
  acquisitionManage: { systemPath: "permission.acquisition", action: "manage" },
425
432
  projectsManage: { systemPath: "permission.projects", action: "manage" },
426
433
  clientsManage: { systemPath: "permission.clients", action: "manage" },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elevasis/core",
3
- "version": "0.32.0",
3
+ "version": "0.33.0",
4
4
  "license": "MIT",
5
5
  "description": "Minimal shared constants across Elevasis monorepo",
6
6
  "sideEffects": false,
@@ -23,6 +23,12 @@ const model = {
23
23
  label: 'CRM',
24
24
  lifecycle: 'active',
25
25
  order: 10
26
+ },
27
+ 'lead-gen': {
28
+ id: 'lead-gen',
29
+ label: 'Lead Gen',
30
+ lifecycle: 'active',
31
+ order: 20
26
32
  }
27
33
  }
28
34
  },
@@ -53,6 +59,7 @@ describe('access keys', () => {
53
59
  expect(keys).toContainEqual({ systemPath: 'sales', action: 'view' })
54
60
  expect(keys).toContainEqual({ systemPath: 'sales.crm', action: 'view' })
55
61
  expect(keys).toContainEqual({ systemPath: 'sales.crm', action: 'manage' })
62
+ expect(keys).toContainEqual(AccessKeys.leadGenManage)
56
63
  expect(keys).toContainEqual({ systemPath: 'operations', action: 'manage' })
57
64
  })
58
65
 
@@ -78,4 +85,13 @@ describe('access keys', () => {
78
85
  rolePermission: 'members.manage'
79
86
  })
80
87
  })
88
+
89
+ it('maps the Lead Gen manage AccessKey to the OM System permission', () => {
90
+ const catalog = deriveAccessKeyCatalog(model)
91
+
92
+ expect(findAccessCatalogEntry(catalog, AccessKeys.leadGenManage)).toMatchObject({
93
+ source: 'om-system',
94
+ rolePermission: 'sales.lead-gen.manage'
95
+ })
96
+ })
81
97
  })
@@ -17,6 +17,12 @@ const organizationModel = {
17
17
  label: 'CRM',
18
18
  lifecycle: 'active',
19
19
  order: 10
20
+ },
21
+ 'lead-gen': {
22
+ id: 'lead-gen',
23
+ label: 'Lead Gen',
24
+ lifecycle: 'active',
25
+ order: 20
20
26
  }
21
27
  }
22
28
  },
@@ -179,6 +185,31 @@ describe('checkAccess', () => {
179
185
  })
180
186
  })
181
187
 
188
+ it('allows Lead Gen manage only with the explicit OM System permission', () => {
189
+ expect(
190
+ checkAccess(
191
+ AccessKeys.leadGenManage,
192
+ context({
193
+ membership: {
194
+ id: 'membership-1',
195
+ organizationId: 'org-1',
196
+ effectivePermissions: ['sales.lead-gen.manage']
197
+ }
198
+ })
199
+ )
200
+ ).toEqual({
201
+ allowed: true,
202
+ restrictedBy: null,
203
+ reason: 'allowed'
204
+ })
205
+
206
+ expect(checkAccess(AccessKeys.leadGenManage, context())).toEqual({
207
+ allowed: false,
208
+ restrictedBy: 'role-permission',
209
+ reason: 'role-permission-denied'
210
+ })
211
+ })
212
+
182
213
  it('requires explicit role permissions for permission-only access keys', () => {
183
214
  expect(
184
215
  checkAccess(
@@ -54,6 +54,7 @@ export const AccessKeys = {
54
54
  secretsManage: { systemPath: 'permission.secrets', action: 'manage' },
55
55
  operationsRead: { systemPath: 'permission.operations', action: DEFAULT_ACCESS_ACTION },
56
56
  operationsManage: { systemPath: 'permission.operations', action: 'manage' },
57
+ leadGenManage: { systemPath: 'sales.lead-gen', action: 'manage' },
57
58
  acquisitionManage: { systemPath: 'permission.acquisition', action: 'manage' },
58
59
  projectsManage: { systemPath: 'permission.projects', action: 'manage' },
59
60
  clientsManage: { systemPath: 'permission.clients', action: 'manage' },
@@ -32,12 +32,13 @@ export const PERMISSIONS = {
32
32
  MEMBERS_MANAGE: 'members.manage',
33
33
  ROLES_MANAGE: 'roles.manage',
34
34
  SECRETS_MANAGE: 'secrets.manage',
35
- OPERATIONS_READ: 'operations.read',
36
- OPERATIONS_MANAGE: 'operations.manage',
37
- ACQUISITION_MANAGE: 'acquisition.manage',
38
- PROJECTS_MANAGE: 'projects.manage',
39
- CLIENTS_MANAGE: 'clients.manage'
40
- } as const
35
+ OPERATIONS_READ: 'operations.read',
36
+ OPERATIONS_MANAGE: 'operations.manage',
37
+ SALES_LEAD_GEN_MANAGE: 'sales.lead-gen.manage',
38
+ ACQUISITION_MANAGE: 'acquisition.manage',
39
+ PROJECTS_MANAGE: 'projects.manage',
40
+ CLIENTS_MANAGE: 'clients.manage'
41
+ } as const
41
42
 
42
43
  export type PermissionKey = (typeof PERMISSIONS)[keyof typeof PERMISSIONS]
43
44
 
@@ -89,13 +90,18 @@ export const PERMISSION_CATALOG: readonly PermissionDescriptor[] = [
89
90
  description: 'View executions, sessions, schedules, and command queue',
90
91
  isOrgGrantable: true
91
92
  },
92
- {
93
- key: 'operations.manage',
94
- description: 'Run and modify executions, sessions, schedules, queue',
95
- isOrgGrantable: true
96
- },
97
- {
98
- key: 'acquisition.manage',
93
+ {
94
+ key: 'operations.manage',
95
+ description: 'Run and modify executions, sessions, schedules, queue',
96
+ isOrgGrantable: true
97
+ },
98
+ {
99
+ key: 'sales.lead-gen.manage',
100
+ description: 'Operate Lead Gen lists and list-builder workflows',
101
+ isOrgGrantable: true
102
+ },
103
+ {
104
+ key: 'acquisition.manage',
99
105
  description:
100
106
  'Create, update, and delete acquisition records (acq_companies, acq_contacts, acq_deals, acq_lists*, acq_content*, acquisition storage files)',
101
107
  isOrgGrantable: false
@@ -216,45 +216,42 @@ describe.each([
216
216
  idField: 'id' as const,
217
217
  invalidOverride: { kind: 'invalid-kind' }
218
218
  }
219
- ])(
220
- 'define$domain$domain',
221
- ({ domain: _domain, defineSingle, defineMultiple, valid, schema, idField, invalidOverride }) => {
222
- it('defineX — validates and returns a parsed entry', () => {
223
- const result = defineSingle(valid as never)
224
- expect(result).toHaveProperty(idField)
225
- expect((result as Record<string, unknown>)[idField]).toBe((valid as Record<string, unknown>)[idField])
226
- })
219
+ ])('define$domain — $domain', ({ domain: _domain, defineSingle, defineMultiple, valid, idField, invalidOverride }) => {
220
+ it('defineXvalidates and returns a parsed entry', () => {
221
+ const result = defineSingle(valid as never)
222
+ expect(result).toHaveProperty(idField)
223
+ expect((result as Record<string, unknown>)[idField]).toBe((valid as Record<string, unknown>)[idField])
224
+ })
227
225
 
228
- it('defineX — throws ZodError on invalid input', () => {
229
- const bad = { ...valid, ...invalidOverride } as never
230
- expect(() => defineSingle(bad)).toThrow(z.ZodError)
231
- })
226
+ it('defineX — throws ZodError on invalid input', () => {
227
+ const bad = { ...valid, ...invalidOverride } as never
228
+ expect(() => defineSingle(bad)).toThrow(z.ZodError)
229
+ })
232
230
 
233
- it('defineXs — produces an id-keyed map', () => {
234
- const result = defineMultiple([valid] as never[])
235
- const id = (valid as Record<string, unknown>)[idField] as string
236
- expect(result).toHaveProperty(id)
237
- expect((result[id] as Record<string, unknown>)[idField]).toBe(id)
238
- })
231
+ it('defineXs — produces an id-keyed map', () => {
232
+ const result = defineMultiple([valid] as never[])
233
+ const id = (valid as Record<string, unknown>)[idField] as string
234
+ expect(result).toHaveProperty(id)
235
+ expect((result[id] as Record<string, unknown>)[idField]).toBe(id)
236
+ })
239
237
 
240
- it('defineXs — throws ZodError on invalid input', () => {
241
- const bad = { ...valid, ...invalidOverride } as never
242
- expect(() => defineMultiple([bad] as never[])).toThrow(z.ZodError)
243
- })
238
+ it('defineXs — throws ZodError on invalid input', () => {
239
+ const bad = { ...valid, ...invalidOverride } as never
240
+ expect(() => defineMultiple([bad] as never[])).toThrow(z.ZodError)
241
+ })
244
242
 
245
- it('defineXs — returns empty map for empty array', () => {
246
- const result = defineMultiple([] as never[])
247
- expect(result).toEqual({})
248
- })
243
+ it('defineXs — returns empty map for empty array', () => {
244
+ const result = defineMultiple([] as never[])
245
+ expect(result).toEqual({})
246
+ })
249
247
 
250
- it('defineXs — validates through schema (no bypass)', () => {
251
- // Confirm that defineMultiple uses schema.parse, not a pass-through.
252
- // Missing required fields should throw even if the object looks similar.
253
- const missingRequired = { [idField]: (valid as Record<string, unknown>)[idField] } as never
254
- expect(() => defineMultiple([missingRequired] as never[])).toThrow(z.ZodError)
255
- })
256
- }
257
- )
248
+ it('defineXs — validates through schema (no bypass)', () => {
249
+ // Confirm that defineMultiple uses schema.parse, not a pass-through.
250
+ // Missing required fields should throw even if the object looks similar.
251
+ const missingRequired = { [idField]: (valid as Record<string, unknown>)[idField] } as never
252
+ expect(() => defineMultiple([missingRequired] as never[])).toThrow(z.ZodError)
253
+ })
254
+ })
258
255
 
259
256
  // ---------------------------------------------------------------------------
260
257
  // Topology — existing helpers (defineTopology, defineTopologyRelationship)