@elevasis/core 0.15.1 → 0.17.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.
Files changed (72) hide show
  1. package/dist/index.d.ts +1662 -23
  2. package/dist/index.js +171 -24
  3. package/dist/knowledge/index.d.ts +1340 -0
  4. package/dist/knowledge/index.js +138 -0
  5. package/dist/organization-model/index.d.ts +1662 -23
  6. package/dist/organization-model/index.js +171 -24
  7. package/dist/test-utils/index.d.ts +711 -10
  8. package/dist/test-utils/index.js +159 -16
  9. package/package.json +7 -3
  10. package/src/__tests__/publish.test.ts +14 -13
  11. package/src/__tests__/template-core-compatibility.test.ts +4 -4
  12. package/src/_gen/__tests__/__snapshots__/contracts.md.snap +1265 -1154
  13. package/src/auth/multi-tenancy/index.ts +3 -0
  14. package/src/auth/multi-tenancy/theme-presets.ts +45 -0
  15. package/src/auth/multi-tenancy/types.ts +57 -83
  16. package/src/auth/multi-tenancy/users/api-schemas.ts +165 -194
  17. package/src/business/acquisition/activity-events.ts +1 -1
  18. package/src/business/acquisition/api-schemas.ts +1196 -1177
  19. package/src/business/acquisition/crm-state-actions.test.ts +139 -139
  20. package/src/business/acquisition/types.ts +381 -390
  21. package/src/business/crm/api-schemas.ts +40 -0
  22. package/src/business/crm/index.ts +1 -0
  23. package/src/business/deals/api-schemas.ts +79 -0
  24. package/src/business/deals/index.ts +1 -0
  25. package/src/business/projects/types.ts +124 -88
  26. package/src/execution/core/runner-types.ts +61 -80
  27. package/src/execution/engine/tools/integration/server/adapters/gmail/gmail-tools.ts +105 -104
  28. package/src/execution/engine/tools/integration/server/adapters/instantly/instantly-tools.ts +1474 -1473
  29. package/src/execution/engine/tools/integration/server/adapters/millionverifier/millionverifier-tools.ts +103 -102
  30. package/src/execution/engine/tools/integration/server/adapters/signature-api/signature-api-tools.ts +182 -179
  31. package/src/execution/engine/tools/integration/server/adapters/stripe/stripe-tools.ts +310 -309
  32. package/src/execution/engine/tools/integration/tool.ts +255 -253
  33. package/src/execution/engine/tools/lead-service-types.ts +895 -894
  34. package/src/execution/engine/tools/messages.ts +43 -0
  35. package/src/execution/engine/tools/platform/acquisition/types.ts +2 -1
  36. package/src/execution/engine/tools/platform/email/types.ts +97 -96
  37. package/src/execution/engine/tools/types.ts +234 -233
  38. package/src/execution/engine/workflow/types.ts +195 -193
  39. package/src/execution/external/api-schemas.ts +40 -0
  40. package/src/execution/external/index.ts +1 -0
  41. package/src/knowledge/README.md +32 -0
  42. package/src/knowledge/__tests__/queries.test.ts +504 -0
  43. package/src/knowledge/format.ts +99 -0
  44. package/src/knowledge/index.ts +5 -0
  45. package/src/knowledge/published.ts +5 -0
  46. package/src/knowledge/queries.ts +256 -0
  47. package/src/organization-model/__tests__/defaults.test.ts +172 -172
  48. package/src/organization-model/__tests__/foundation.test.ts +7 -7
  49. package/src/organization-model/__tests__/icons.test.ts +27 -0
  50. package/src/organization-model/__tests__/knowledge.test.ts +214 -0
  51. package/src/organization-model/contracts.ts +17 -15
  52. package/src/organization-model/defaults.ts +74 -19
  53. package/src/organization-model/domains/knowledge.ts +53 -0
  54. package/src/organization-model/domains/navigation.ts +416 -399
  55. package/src/organization-model/domains/shared.ts +6 -5
  56. package/src/organization-model/foundation.ts +10 -6
  57. package/src/organization-model/graph/build.ts +209 -182
  58. package/src/organization-model/graph/schema.ts +37 -34
  59. package/src/organization-model/graph/types.ts +47 -31
  60. package/src/organization-model/icons.ts +81 -0
  61. package/src/organization-model/index.ts +8 -3
  62. package/src/organization-model/organization-model.mdx +1 -1
  63. package/src/organization-model/published.ts +103 -86
  64. package/src/organization-model/schema.ts +90 -85
  65. package/src/organization-model/types.ts +40 -33
  66. package/src/platform/index.ts +23 -27
  67. package/src/platform/registry/index.ts +0 -4
  68. package/src/platform/registry/resource-registry.ts +0 -77
  69. package/src/platform/registry/serialized-types.ts +148 -219
  70. package/src/platform/registry/stats-types.ts +60 -60
  71. package/src/reference/_generated/contracts.md +1265 -1154
  72. package/src/platform/registry/__tests__/resource-registry.list-executable.test.ts +0 -393
@@ -1,3 +1,6 @@
1
+ // Theme preset SSOT (const tuple + derived union + Zod enum)
2
+ export * from './theme-presets'
3
+
1
4
  // Config types
2
5
  export * from './types'
3
6
 
@@ -0,0 +1,45 @@
1
+ import { z } from 'zod'
2
+
3
+ /**
4
+ * Single source of truth for all active theme preset names.
5
+ *
6
+ * This is the canonical list. To add a preset:
7
+ * 1. Add the name here.
8
+ * 2. Create `packages/ui/src/theme/presets/{name}.ts` exporting `{name}Preset: ThemePreset`.
9
+ * 3. Add to `PRESETS` record in `packages/ui/src/theme/presets/index.ts`.
10
+ * 4. Add to `PresetName` union in `packages/ui/src/theme/presets/types.ts`.
11
+ * 5. Add a card in `apps/command-center/src/features/settings/appearance/components/AppearanceSettings.tsx`.
12
+ *
13
+ * The union type (`ThemePresetName`) and Zod enum (`ThemePresetEnum`) are derived
14
+ * automatically — no other files need updating.
15
+ */
16
+ export const THEME_PRESETS = [
17
+ 'default',
18
+ 'tactical',
19
+ 'regal',
20
+ 'cyber-volt',
21
+ 'aurora',
22
+ 'rose-gold',
23
+ 'midnight',
24
+ 'titanium',
25
+ 'canopy',
26
+ 'slate',
27
+ 'cyber-strike',
28
+ 'cyber-chrome',
29
+ 'cyber-void',
30
+ 'nirvana',
31
+ 'wave',
32
+ 'synapse',
33
+ 'cortex',
34
+ 'helios',
35
+ 'graphite',
36
+ 'quarry'
37
+ ] as const satisfies readonly string[]
38
+
39
+ export type ThemePresetName = (typeof THEME_PRESETS)[number]
40
+
41
+ /**
42
+ * Zod enum derived from THEME_PRESETS.
43
+ * Use `.catch('default')` at write-path callsites to tolerate stale/unknown values.
44
+ */
45
+ export const ThemePresetEnum = z.enum(THEME_PRESETS)
@@ -1,83 +1,57 @@
1
- /**
2
- * Multi-tenancy configuration types
3
- *
4
- * Config is stored in dedicated `config` columns (NOT nested in metadata):
5
- * - organizations.config: Org-level config (no feature toggles -- all features available by default)
6
- * - org_memberships.config: Per-user-per-org feature overrides
7
- * - users.config: User-global config
8
- */
9
-
10
- /**
11
- * Per-user-per-org config (stored in org_memberships.config)
12
- * Controls which features a specific member can access within their org.
13
- * Keys are feature IDs from the organization model (e.g. crm, lead-gen, projects, seo).
14
- */
15
- export interface MembershipFeatureConfig {
16
- features?: Record<string, boolean>
17
- }
18
-
19
- /**
20
- * User-global config (stored in users.config)
21
- * Theme and onboarding are user-specific, NOT org-specific
22
- */
23
- export interface UserConfig {
24
- theme?: {
25
- preset?:
26
- | 'default'
27
- | 'tactical'
28
- | 'regal'
29
- | 'cyber-volt'
30
- | 'aurora'
31
- | 'rose-gold'
32
- | 'midnight'
33
- | 'titanium'
34
- | 'obsidian'
35
- | 'honey'
36
- | 'abyss'
37
- | 'canopy'
38
- | 'slate'
39
- | 'cyber-strike'
40
- | 'cyber-chrome'
41
- | 'cyber-void'
42
- | 'nirvana'
43
- | 'wave'
44
- | 'synapse'
45
- | 'cortex'
46
- | 'helios'
47
- | 'graphite'
48
- | 'quarry'
49
- | 'canyon'
50
- | 'nord'
51
- | 'catppuccin'
52
- | 'tokyo-night'
53
- | 'gruvbox'
54
- colorScheme?: 'light' | 'dark' | 'auto'
55
- }
56
- onboarding?: {
57
- completed?: boolean
58
- completedAt?: string // ISO date
59
- role?: string
60
- primaryUseCase?: string[]
61
- experienceLevel?: string
62
- /** Onboarding guide system state (set by checklist/tour system) */
63
- guides?: {
64
- completedIds?: string[] // e.g. ["explore-dashboard", "view-workflow"]
65
- dismissed?: boolean // user manually dismissed checklist
66
- completedAt?: string // ISO date — all guides finished
67
- }
68
- }
69
- }
70
-
71
- /**
72
- * OrgMetadata - Contains WorkOS sync data only
73
- * Note: This is kept separate from config for clarity
74
- */
75
- export interface OrgMetadata {
76
- domains?: {
77
- verified: string[]
78
- pending: string[]
79
- all: string[]
80
- }
81
- workos_created_at?: string
82
- workos_updated_at?: string
83
- }
1
+ /**
2
+ * Multi-tenancy configuration types
3
+ *
4
+ * Config is stored in dedicated `config` columns (NOT nested in metadata):
5
+ * - organizations.config: Org-level config (no feature toggles -- all features available by default)
6
+ * - org_memberships.config: Per-user-per-org feature overrides
7
+ * - users.config: User-global config
8
+ */
9
+
10
+ import type { ThemePresetName } from './theme-presets'
11
+
12
+ /**
13
+ * Per-user-per-org config (stored in org_memberships.config)
14
+ * Controls which features a specific member can access within their org.
15
+ * Keys are feature IDs from the organization model (e.g. crm, lead-gen, projects, seo).
16
+ */
17
+ export interface MembershipFeatureConfig {
18
+ features?: Record<string, boolean>
19
+ }
20
+
21
+ /**
22
+ * User-global config (stored in users.config)
23
+ * Theme and onboarding are user-specific, NOT org-specific
24
+ */
25
+ export interface UserConfig {
26
+ theme?: {
27
+ preset?: ThemePresetName
28
+ colorScheme?: 'light' | 'dark' | 'auto'
29
+ }
30
+ onboarding?: {
31
+ completed?: boolean
32
+ completedAt?: string // ISO date
33
+ role?: string
34
+ primaryUseCase?: string[]
35
+ experienceLevel?: string
36
+ /** Onboarding guide system state (set by checklist/tour system) */
37
+ guides?: {
38
+ completedIds?: string[] // e.g. ["explore-dashboard", "view-workflow"]
39
+ dismissed?: boolean // user manually dismissed checklist
40
+ completedAt?: string // ISO date — all guides finished
41
+ }
42
+ }
43
+ }
44
+
45
+ /**
46
+ * OrgMetadata - Contains WorkOS sync data only
47
+ * Note: This is kept separate from config for clarity
48
+ */
49
+ export interface OrgMetadata {
50
+ domains?: {
51
+ verified: string[]
52
+ pending: string[]
53
+ all: string[]
54
+ }
55
+ workos_created_at?: string
56
+ workos_updated_at?: string
57
+ }
@@ -1,194 +1,165 @@
1
- /**
2
- * Users Domain - Zod Validation Schemas
3
- *
4
- * Validation schemas for user management endpoints.
5
- * Includes request bodies, query params, and path params.
6
- *
7
- * Security:
8
- * - All schemas use .strict() to prevent mass assignment attacks
9
- * - UUID validation prevents invalid references
10
- * - Email validation prevents email injection attacks
11
- * - emailVerified field excluded from create/update (admin-only)
12
- * - String length limits prevent DoS
13
- */
14
-
15
- import { z } from 'zod'
16
- import { EmailSchema, createStringSchema } from '../../../platform/utils/validation'
17
-
18
- // ============================================================================
19
- // Path Parameters
20
- // ============================================================================
21
-
22
- /**
23
- * Validate user ID in URL path
24
- * Used by: GET/PUT/DELETE /users/:id
25
- */
26
- export const UserIdParamSchema = z
27
- .object({
28
- id: z.string().min(1) // WorkOS user IDs can be UUID or 'user_' prefixed strings
29
- })
30
- .strict()
31
-
32
- /**
33
- * Validate external ID in URL path
34
- * Used by: GET /users/external/:externalId
35
- */
36
- export const ExternalIdParamSchema = z
37
- .object({
38
- externalId: z.string().min(1)
39
- })
40
- .strict()
41
-
42
- // ============================================================================
43
- // Request Bodies
44
- // ============================================================================
45
-
46
- /**
47
- * Update user profile
48
- * PUT /users/:id
49
- *
50
- * Security:
51
- * - All fields optional (partial update)
52
- * - Email format validated
53
- * - emailVerified NOT accepted (managed by WorkOS only)
54
- * - Strict mode prevents unknown field injection
55
- */
56
- export const UpdateUserSchema = z
57
- .object({
58
- email: EmailSchema.optional(),
59
- firstName: createStringSchema(1, 100, 'First name').optional(),
60
- lastName: createStringSchema(1, 100, 'Last name').optional()
61
- })
62
- .strict()
63
-
64
- // ============================================================================
65
- // Self-Service Profile
66
- // ============================================================================
67
-
68
- /**
69
- * Self-service profile update (subset of admin UpdateUserSchema)
70
- * PATCH /users/me
71
- *
72
- * Security:
73
- * - All fields optional (partial update)
74
- * - Server identifies user from JWT (no user ID in body)
75
- * - Config restricted to theme and onboarding only
76
- * - Strict mode prevents unknown field injection
77
- */
78
- export const UpdateMyProfileSchema = z
79
- .object({
80
- firstName: createStringSchema(1, 100, 'First name').optional(),
81
- lastName: createStringSchema(1, 100, 'Last name').optional(),
82
- profilePictureUrl: z
83
- .string()
84
- .url()
85
- .refine((url) => url.startsWith('https://'), { message: 'Only HTTPS URLs are allowed' })
86
- .optional(),
87
- lastVisitedOrg: z.string().uuid().optional(),
88
- config: z
89
- .object({
90
- theme: z
91
- .object({
92
- // `.catch('default')` makes the write path tolerant of stale/unknown preset strings.
93
- // Any value that fails enum validation silently coerces to 'default' instead of 400ing.
94
- // This protects against preset renames (e.g. cyber-punk cyber-chrome) and drift between
95
- // the enum and legacy DB values. Paired with a read-path sync-back in main.tsx that
96
- // persists the corrected value back to DB on next profile load.
97
- preset: z
98
- .enum([
99
- 'default',
100
- 'tactical',
101
- 'regal',
102
- 'cyber-volt',
103
- 'aurora',
104
- 'rose-gold',
105
- 'midnight',
106
- 'titanium',
107
- 'obsidian',
108
- 'honey',
109
- 'abyss',
110
- 'canopy',
111
- 'slate',
112
- 'cyber-strike',
113
- 'cyber-chrome',
114
- 'cyber-void',
115
- 'nirvana',
116
- 'wave',
117
- 'synapse',
118
- 'cortex',
119
- 'helios',
120
- 'graphite',
121
- 'quarry',
122
- 'canyon',
123
- 'nord',
124
- 'catppuccin',
125
- 'tokyo-night',
126
- 'gruvbox'
127
- ])
128
- .catch('default')
129
- .optional(),
130
- colorScheme: z.enum(['light', 'dark', 'auto']).catch('auto').optional()
131
- })
132
- .strict()
133
- .optional(),
134
- onboarding: z
135
- .object({
136
- completed: z.boolean().optional(),
137
- completedAt: z.string().datetime().nullable().optional(),
138
- role: z.string().max(100).nullable().optional(),
139
- primaryUseCase: z.array(z.string().max(100)).max(10).nullable().optional(),
140
- experienceLevel: z.string().max(100).nullable().optional(),
141
- guides: z
142
- .object({
143
- completedIds: z.array(z.string().max(100)).max(20).optional(),
144
- dismissed: z.boolean().optional(),
145
- completedAt: z.string().datetime().nullable().optional()
146
- })
147
- .strict()
148
- .optional()
149
- })
150
- .strict()
151
- .optional()
152
- })
153
- .strict()
154
- .optional()
155
- })
156
- .strict()
157
-
158
- // ============================================================================
159
- // Query Parameters
160
- // ============================================================================
161
-
162
- /**
163
- * List users with filters
164
- * GET /users
165
- *
166
- * Filters:
167
- * - email: Filter by email
168
- * - organizationId: Filter by organization
169
- * - limit: Max results (pagination handled by WorkOS)
170
- *
171
- * Security:
172
- * - Email validated (prevents injection)
173
- * - organizationId validated (UUID format)
174
- */
175
- export const ListUsersQuerySchema = z
176
- .object({
177
- email: EmailSchema.optional(),
178
- organizationId: z.string().optional(), // WorkOS org IDs can be UUID or 'org_' prefixed
179
- limit: z.coerce.number().int().min(1).max(100).optional(),
180
- before: z.string().optional(), // WorkOS pagination cursor
181
- after: z.string().optional() // WorkOS pagination cursor
182
- })
183
- .strict()
184
-
185
- // ============================================================================
186
- // TypeScript Type Exports
187
- // ============================================================================
188
-
189
- // Export inferred types for use in route handlers
190
- export type UpdateUserInput = z.infer<typeof UpdateUserSchema>
191
- export type UpdateMyProfileInput = z.infer<typeof UpdateMyProfileSchema>
192
- export type ListUsersQuery = z.infer<typeof ListUsersQuerySchema>
193
- export type UserIdParam = z.infer<typeof UserIdParamSchema>
194
- export type ExternalIdParam = z.infer<typeof ExternalIdParamSchema>
1
+ /**
2
+ * Users Domain - Zod Validation Schemas
3
+ *
4
+ * Validation schemas for user management endpoints.
5
+ * Includes request bodies, query params, and path params.
6
+ *
7
+ * Security:
8
+ * - All schemas use .strict() to prevent mass assignment attacks
9
+ * - UUID validation prevents invalid references
10
+ * - Email validation prevents email injection attacks
11
+ * - emailVerified field excluded from create/update (admin-only)
12
+ * - String length limits prevent DoS
13
+ */
14
+
15
+ import { z } from 'zod'
16
+ import { EmailSchema, createStringSchema } from '../../../platform/utils/validation'
17
+ import { ThemePresetEnum } from '../theme-presets'
18
+
19
+ // ============================================================================
20
+ // Path Parameters
21
+ // ============================================================================
22
+
23
+ /**
24
+ * Validate user ID in URL path
25
+ * Used by: GET/PUT/DELETE /users/:id
26
+ */
27
+ export const UserIdParamSchema = z
28
+ .object({
29
+ id: z.string().min(1) // WorkOS user IDs can be UUID or 'user_' prefixed strings
30
+ })
31
+ .strict()
32
+
33
+ /**
34
+ * Validate external ID in URL path
35
+ * Used by: GET /users/external/:externalId
36
+ */
37
+ export const ExternalIdParamSchema = z
38
+ .object({
39
+ externalId: z.string().min(1)
40
+ })
41
+ .strict()
42
+
43
+ // ============================================================================
44
+ // Request Bodies
45
+ // ============================================================================
46
+
47
+ /**
48
+ * Update user profile
49
+ * PUT /users/:id
50
+ *
51
+ * Security:
52
+ * - All fields optional (partial update)
53
+ * - Email format validated
54
+ * - emailVerified NOT accepted (managed by WorkOS only)
55
+ * - Strict mode prevents unknown field injection
56
+ */
57
+ export const UpdateUserSchema = z
58
+ .object({
59
+ email: EmailSchema.optional(),
60
+ firstName: createStringSchema(1, 100, 'First name').optional(),
61
+ lastName: createStringSchema(1, 100, 'Last name').optional()
62
+ })
63
+ .strict()
64
+
65
+ // ============================================================================
66
+ // Self-Service Profile
67
+ // ============================================================================
68
+
69
+ /**
70
+ * Self-service profile update (subset of admin UpdateUserSchema)
71
+ * PATCH /users/me
72
+ *
73
+ * Security:
74
+ * - All fields optional (partial update)
75
+ * - Server identifies user from JWT (no user ID in body)
76
+ * - Config restricted to theme and onboarding only
77
+ * - Strict mode prevents unknown field injection
78
+ */
79
+ export const UpdateMyProfileSchema = z
80
+ .object({
81
+ firstName: createStringSchema(1, 100, 'First name').optional(),
82
+ lastName: createStringSchema(1, 100, 'Last name').optional(),
83
+ profilePictureUrl: z
84
+ .string()
85
+ .url()
86
+ .refine((url) => url.startsWith('https://'), { message: 'Only HTTPS URLs are allowed' })
87
+ .optional(),
88
+ lastVisitedOrg: z.string().uuid().optional(),
89
+ config: z
90
+ .object({
91
+ theme: z
92
+ .object({
93
+ // `.catch('default')` makes the write path tolerant of stale/unknown preset strings.
94
+ // Any value that fails enum validation silently coerces to 'default' instead of 400ing.
95
+ // This protects against preset renames (e.g. cyber-punk cyber-chrome) and drift between
96
+ // the enum and legacy DB values. Paired with a read-path sync-back in main.tsx that
97
+ // persists the corrected value back to DB on next profile load.
98
+ // ThemePresetEnum is derived from THEME_PRESETS — the single source of truth in
99
+ // packages/core/src/auth/multi-tenancy/theme-presets.ts.
100
+ preset: ThemePresetEnum.catch('default').optional(),
101
+ colorScheme: z.enum(['light', 'dark', 'auto']).catch('auto').optional()
102
+ })
103
+ .strict()
104
+ .optional(),
105
+ onboarding: z
106
+ .object({
107
+ completed: z.boolean().optional(),
108
+ completedAt: z.string().datetime().nullable().optional(),
109
+ role: z.string().max(100).nullable().optional(),
110
+ primaryUseCase: z.array(z.string().max(100)).max(10).nullable().optional(),
111
+ experienceLevel: z.string().max(100).nullable().optional(),
112
+ guides: z
113
+ .object({
114
+ completedIds: z.array(z.string().max(100)).max(20).optional(),
115
+ dismissed: z.boolean().optional(),
116
+ completedAt: z.string().datetime().nullable().optional()
117
+ })
118
+ .strict()
119
+ .optional()
120
+ })
121
+ .strict()
122
+ .optional()
123
+ })
124
+ .strict()
125
+ .optional()
126
+ })
127
+ .strict()
128
+
129
+ // ============================================================================
130
+ // Query Parameters
131
+ // ============================================================================
132
+
133
+ /**
134
+ * List users with filters
135
+ * GET /users
136
+ *
137
+ * Filters:
138
+ * - email: Filter by email
139
+ * - organizationId: Filter by organization
140
+ * - limit: Max results (pagination handled by WorkOS)
141
+ *
142
+ * Security:
143
+ * - Email validated (prevents injection)
144
+ * - organizationId validated (UUID format)
145
+ */
146
+ export const ListUsersQuerySchema = z
147
+ .object({
148
+ email: EmailSchema.optional(),
149
+ organizationId: z.string().optional(), // WorkOS org IDs can be UUID or 'org_' prefixed
150
+ limit: z.coerce.number().int().min(1).max(100).optional(),
151
+ before: z.string().optional(), // WorkOS pagination cursor
152
+ after: z.string().optional() // WorkOS pagination cursor
153
+ })
154
+ .strict()
155
+
156
+ // ============================================================================
157
+ // TypeScript Type Exports
158
+ // ============================================================================
159
+
160
+ // Export inferred types for use in route handlers
161
+ export type UpdateUserInput = z.infer<typeof UpdateUserSchema>
162
+ export type UpdateMyProfileInput = z.infer<typeof UpdateMyProfileSchema>
163
+ export type ListUsersQuery = z.infer<typeof ListUsersQuerySchema>
164
+ export type UserIdParam = z.infer<typeof UserIdParamSchema>
165
+ export type ExternalIdParam = z.infer<typeof ExternalIdParamSchema>
@@ -4,7 +4,7 @@ import { z } from 'zod'
4
4
  // Platform event member schemas (9 members — closed union, stays in @repo/core)
5
5
  //
6
6
  // Domain-specific events (reply_received, booking_nudge_sent, etc.) live in
7
- // external/elevasis/operations as CrmDomainActivityEventSchema.
7
+ // @repo/elevasis-operations as CrmDomainActivityEventSchema.
8
8
  // See Open Decision #5 in crm-action-system.mdx for rationale.
9
9
  // ---------------------------------------------------------------------------
10
10