business-as-code 0.2.1 → 2.0.1

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 (190) hide show
  1. package/.turbo/turbo-build.log +5 -0
  2. package/CHANGELOG.md +9 -0
  3. package/IMPLEMENTATION.md +226 -0
  4. package/README.md +1133 -193
  5. package/dist/business.d.ts +62 -0
  6. package/dist/business.d.ts.map +1 -0
  7. package/dist/business.js +109 -0
  8. package/dist/business.js.map +1 -0
  9. package/dist/dollar.d.ts +60 -0
  10. package/dist/dollar.d.ts.map +1 -0
  11. package/dist/dollar.js +107 -0
  12. package/dist/dollar.js.map +1 -0
  13. package/dist/entities/assets.d.ts +21 -0
  14. package/dist/entities/assets.d.ts.map +1 -0
  15. package/dist/entities/assets.js +323 -0
  16. package/dist/entities/assets.js.map +1 -0
  17. package/dist/entities/business.d.ts +36 -0
  18. package/dist/entities/business.d.ts.map +1 -0
  19. package/dist/entities/business.js +370 -0
  20. package/dist/entities/business.js.map +1 -0
  21. package/dist/entities/communication.d.ts +21 -0
  22. package/dist/entities/communication.d.ts.map +1 -0
  23. package/dist/entities/communication.js +255 -0
  24. package/dist/entities/communication.js.map +1 -0
  25. package/dist/entities/customers.d.ts +58 -0
  26. package/dist/entities/customers.d.ts.map +1 -0
  27. package/dist/entities/customers.js +989 -0
  28. package/dist/entities/customers.js.map +1 -0
  29. package/dist/entities/financials.d.ts +59 -0
  30. package/dist/entities/financials.d.ts.map +1 -0
  31. package/dist/entities/financials.js +932 -0
  32. package/dist/entities/financials.js.map +1 -0
  33. package/dist/entities/goals.d.ts +58 -0
  34. package/dist/entities/goals.d.ts.map +1 -0
  35. package/dist/entities/goals.js +800 -0
  36. package/dist/entities/goals.js.map +1 -0
  37. package/dist/entities/index.d.ts +299 -0
  38. package/dist/entities/index.d.ts.map +1 -0
  39. package/dist/entities/index.js +198 -0
  40. package/dist/entities/index.js.map +1 -0
  41. package/dist/entities/legal.d.ts +21 -0
  42. package/dist/entities/legal.d.ts.map +1 -0
  43. package/dist/entities/legal.js +301 -0
  44. package/dist/entities/legal.js.map +1 -0
  45. package/dist/entities/market.d.ts +21 -0
  46. package/dist/entities/market.d.ts.map +1 -0
  47. package/dist/entities/market.js +301 -0
  48. package/dist/entities/market.js.map +1 -0
  49. package/dist/entities/marketing.d.ts +67 -0
  50. package/dist/entities/marketing.d.ts.map +1 -0
  51. package/dist/entities/marketing.js +1157 -0
  52. package/dist/entities/marketing.js.map +1 -0
  53. package/dist/entities/offerings.d.ts +51 -0
  54. package/dist/entities/offerings.d.ts.map +1 -0
  55. package/dist/entities/offerings.js +727 -0
  56. package/dist/entities/offerings.js.map +1 -0
  57. package/dist/entities/operations.d.ts +58 -0
  58. package/dist/entities/operations.d.ts.map +1 -0
  59. package/dist/entities/operations.js +787 -0
  60. package/dist/entities/operations.js.map +1 -0
  61. package/dist/entities/organization.d.ts +57 -0
  62. package/dist/entities/organization.d.ts.map +1 -0
  63. package/dist/entities/organization.js +807 -0
  64. package/dist/entities/organization.js.map +1 -0
  65. package/dist/entities/partnerships.d.ts +21 -0
  66. package/dist/entities/partnerships.d.ts.map +1 -0
  67. package/dist/entities/partnerships.js +300 -0
  68. package/dist/entities/partnerships.js.map +1 -0
  69. package/dist/entities/planning.d.ts +87 -0
  70. package/dist/entities/planning.d.ts.map +1 -0
  71. package/dist/entities/planning.js +271 -0
  72. package/dist/entities/planning.js.map +1 -0
  73. package/dist/entities/projects.d.ts +25 -0
  74. package/dist/entities/projects.d.ts.map +1 -0
  75. package/dist/entities/projects.js +349 -0
  76. package/dist/entities/projects.js.map +1 -0
  77. package/dist/entities/risk.d.ts +21 -0
  78. package/dist/entities/risk.d.ts.map +1 -0
  79. package/dist/entities/risk.js +293 -0
  80. package/dist/entities/risk.js.map +1 -0
  81. package/dist/entities/sales.d.ts +72 -0
  82. package/dist/entities/sales.d.ts.map +1 -0
  83. package/dist/entities/sales.js +1248 -0
  84. package/dist/entities/sales.js.map +1 -0
  85. package/dist/financials.d.ts +130 -0
  86. package/dist/financials.d.ts.map +1 -0
  87. package/dist/financials.js +297 -0
  88. package/dist/financials.js.map +1 -0
  89. package/dist/goals.d.ts +87 -0
  90. package/dist/goals.d.ts.map +1 -0
  91. package/dist/goals.js +215 -0
  92. package/dist/goals.js.map +1 -0
  93. package/dist/index.d.ts +97 -4
  94. package/dist/index.d.ts.map +1 -0
  95. package/dist/index.js +131 -1079
  96. package/dist/index.js.map +1 -1
  97. package/dist/kpis.d.ts +118 -0
  98. package/dist/kpis.d.ts.map +1 -0
  99. package/dist/kpis.js +232 -0
  100. package/dist/kpis.js.map +1 -0
  101. package/dist/metrics.d.ts +448 -0
  102. package/dist/metrics.d.ts.map +1 -0
  103. package/dist/metrics.js +325 -0
  104. package/dist/metrics.js.map +1 -0
  105. package/dist/okrs.d.ts +123 -0
  106. package/dist/okrs.d.ts.map +1 -0
  107. package/dist/okrs.js +269 -0
  108. package/dist/okrs.js.map +1 -0
  109. package/dist/organization.d.ts +585 -0
  110. package/dist/organization.d.ts.map +1 -0
  111. package/dist/organization.js +173 -0
  112. package/dist/organization.js.map +1 -0
  113. package/dist/process.d.ts +112 -0
  114. package/dist/process.d.ts.map +1 -0
  115. package/dist/process.js +241 -0
  116. package/dist/process.js.map +1 -0
  117. package/dist/product.d.ts +85 -0
  118. package/dist/product.d.ts.map +1 -0
  119. package/dist/product.js +145 -0
  120. package/dist/product.js.map +1 -0
  121. package/dist/queries.d.ts +304 -0
  122. package/dist/queries.d.ts.map +1 -0
  123. package/dist/queries.js +415 -0
  124. package/dist/queries.js.map +1 -0
  125. package/dist/roles.d.ts +340 -0
  126. package/dist/roles.d.ts.map +1 -0
  127. package/dist/roles.js +255 -0
  128. package/dist/roles.js.map +1 -0
  129. package/dist/service.d.ts +61 -0
  130. package/dist/service.d.ts.map +1 -0
  131. package/dist/service.js +140 -0
  132. package/dist/service.js.map +1 -0
  133. package/dist/types.d.ts +459 -0
  134. package/dist/types.d.ts.map +1 -0
  135. package/dist/types.js +5 -0
  136. package/dist/types.js.map +1 -0
  137. package/dist/vision.d.ts +38 -0
  138. package/dist/vision.d.ts.map +1 -0
  139. package/dist/vision.js +68 -0
  140. package/dist/vision.js.map +1 -0
  141. package/dist/workflow.d.ts +115 -0
  142. package/dist/workflow.d.ts.map +1 -0
  143. package/dist/workflow.js +247 -0
  144. package/dist/workflow.js.map +1 -0
  145. package/examples/basic-usage.ts +307 -0
  146. package/package.json +19 -60
  147. package/src/business.ts +121 -0
  148. package/src/dollar.ts +132 -0
  149. package/src/entities/assets.ts +332 -0
  150. package/src/entities/business.ts +406 -0
  151. package/src/entities/communication.ts +264 -0
  152. package/src/entities/customers.ts +1072 -0
  153. package/src/entities/financials.ts +1011 -0
  154. package/src/entities/goals.ts +871 -0
  155. package/src/entities/index.ts +383 -0
  156. package/src/entities/legal.ts +310 -0
  157. package/src/entities/market.ts +310 -0
  158. package/src/entities/marketing.ts +1249 -0
  159. package/src/entities/offerings.ts +789 -0
  160. package/src/entities/operations.ts +861 -0
  161. package/src/entities/organization.ts +876 -0
  162. package/src/entities/partnerships.ts +309 -0
  163. package/src/entities/planning.ts +307 -0
  164. package/src/entities/projects.ts +360 -0
  165. package/src/entities/risk.ts +302 -0
  166. package/src/entities/sales.ts +1352 -0
  167. package/src/financials.ts +352 -0
  168. package/src/goals.ts +250 -0
  169. package/src/index.test.ts +336 -0
  170. package/src/index.ts +530 -0
  171. package/src/kpis.ts +275 -0
  172. package/src/metrics.ts +825 -0
  173. package/src/okrs.ts +325 -0
  174. package/src/organization.ts +909 -0
  175. package/src/process.ts +272 -0
  176. package/src/product.ts +178 -0
  177. package/src/queries.ts +767 -0
  178. package/src/roles.ts +686 -0
  179. package/src/service.ts +164 -0
  180. package/src/types.ts +493 -0
  181. package/src/vision.ts +88 -0
  182. package/src/workflow.ts +280 -0
  183. package/tsconfig.json +9 -0
  184. package/dist/loaders/index.d.ts +0 -174
  185. package/dist/loaders/index.js +0 -366
  186. package/dist/loaders/index.js.map +0 -1
  187. package/dist/schema/index.d.ts +0 -146
  188. package/dist/schema/index.js +0 -716
  189. package/dist/schema/index.js.map +0 -1
  190. package/dist/types-CJ9eGS_C.d.ts +0 -86
package/src/roles.ts ADDED
@@ -0,0 +1,686 @@
1
+ /**
2
+ * Business Roles - Bridges digital-workers and ai-database authorization
3
+ *
4
+ * Connects:
5
+ * - WorkerRole (business role: CEO, Engineer, Manager)
6
+ * - Authorization Role (FGA/RBAC: permissions, access control)
7
+ * - Task Assignment (who handles what in workflows/processes)
8
+ *
9
+ * @packageDocumentation
10
+ */
11
+
12
+ // =============================================================================
13
+ // Business Role - Bridges Worker Role and Authorization
14
+ // =============================================================================
15
+
16
+ /**
17
+ * Business role type - the function of a worker in the organization
18
+ */
19
+ export type BusinessRoleType =
20
+ // Executive
21
+ | 'ceo'
22
+ | 'cto'
23
+ | 'cfo'
24
+ | 'coo'
25
+ | 'cmo'
26
+ | 'cpo'
27
+ // Management
28
+ | 'director'
29
+ | 'manager'
30
+ | 'lead'
31
+ | 'supervisor'
32
+ // Individual Contributors
33
+ | 'engineer'
34
+ | 'designer'
35
+ | 'analyst'
36
+ | 'specialist'
37
+ | 'coordinator'
38
+ // Operations
39
+ | 'operator'
40
+ | 'agent'
41
+ | 'assistant'
42
+ // Custom
43
+ | string
44
+
45
+ /**
46
+ * Business Role - extends WorkerRole with authorization and task capabilities
47
+ *
48
+ * @example
49
+ * ```ts
50
+ * const engineeringManager: BusinessRole = {
51
+ * id: 'role_eng_manager',
52
+ * name: 'Engineering Manager',
53
+ * type: 'manager',
54
+ * department: 'Engineering',
55
+ * description: 'Leads engineering team and makes technical decisions',
56
+ *
57
+ * // Business responsibilities
58
+ * responsibilities: [
59
+ * 'Lead engineering team',
60
+ * 'Make architecture decisions',
61
+ * 'Conduct code reviews',
62
+ * ],
63
+ *
64
+ * // Authorization permissions (from FGA)
65
+ * permissions: {
66
+ * repository: ['read', 'edit', 'act:merge', 'act:deploy'],
67
+ * project: ['read', 'edit', 'manage'],
68
+ * team: ['read', 'edit'],
69
+ * },
70
+ *
71
+ * // Task capabilities
72
+ * canHandle: ['code-review', 'architecture-decision', 'deployment-approval'],
73
+ * canDelegate: ['code-review', 'testing'],
74
+ * canApprove: ['pull-request', 'deployment', 'budget-under-5k'],
75
+ *
76
+ * // Worker type preference
77
+ * workerType: 'human',
78
+ * }
79
+ * ```
80
+ */
81
+ export interface BusinessRole {
82
+ /** Unique role identifier */
83
+ id: string
84
+
85
+ /** Role display name */
86
+ name: string
87
+
88
+ /** Role type classification */
89
+ type: BusinessRoleType
90
+
91
+ /** Department or team */
92
+ department?: string
93
+
94
+ /** Human-readable description */
95
+ description?: string
96
+
97
+ /** Key responsibilities */
98
+ responsibilities?: string[]
99
+
100
+ /** Required skills */
101
+ skills?: string[]
102
+
103
+ /**
104
+ * Authorization permissions by resource type
105
+ *
106
+ * Maps resource types to allowed actions:
107
+ * - 'read', 'edit', 'delete', 'manage' (standard)
108
+ * - 'act:*' or 'act:verb' (domain-specific verbs)
109
+ *
110
+ * @example
111
+ * ```ts
112
+ * permissions: {
113
+ * document: ['read', 'edit'],
114
+ * invoice: ['read', 'act:send', 'act:void'],
115
+ * project: ['read', 'edit', 'manage'],
116
+ * }
117
+ * ```
118
+ */
119
+ permissions?: Record<string, string[]>
120
+
121
+ /** Task types this role can handle */
122
+ canHandle?: string[]
123
+
124
+ /** Task types this role can delegate to others */
125
+ canDelegate?: string[]
126
+
127
+ /** Request types this role can approve */
128
+ canApprove?: string[]
129
+
130
+ /** Escalation path - role to escalate to */
131
+ escalateTo?: string
132
+
133
+ /** Reports to - manager role */
134
+ reportsTo?: string
135
+
136
+ /** Worker type preference: 'ai' | 'human' | 'hybrid' */
137
+ workerType?: 'ai' | 'human' | 'hybrid'
138
+
139
+ /** Level in hierarchy (1 = entry, higher = more senior) */
140
+ level?: number
141
+
142
+ /** Compensation band */
143
+ compensationBand?: string
144
+
145
+ /** Additional metadata */
146
+ metadata?: Record<string, unknown>
147
+ }
148
+
149
+ // =============================================================================
150
+ // Task Assignment - Connects Workers to Tasks
151
+ // =============================================================================
152
+
153
+ /**
154
+ * Task status
155
+ */
156
+ export type TaskStatus =
157
+ | 'pending'
158
+ | 'assigned'
159
+ | 'in_progress'
160
+ | 'blocked'
161
+ | 'completed'
162
+ | 'failed'
163
+ | 'cancelled'
164
+
165
+ /**
166
+ * Task priority
167
+ */
168
+ export type TaskPriority = 'low' | 'normal' | 'high' | 'urgent' | 'critical'
169
+
170
+ /**
171
+ * Task assignment - links a worker to a task
172
+ *
173
+ * @example
174
+ * ```ts
175
+ * const assignment: TaskAssignment = {
176
+ * id: 'assign_123',
177
+ * taskId: 'task_review_pr_456',
178
+ * taskType: 'code-review',
179
+ *
180
+ * // Who is assigned
181
+ * assignee: { type: 'worker', id: 'worker_alice' },
182
+ * role: 'role_eng_manager',
183
+ *
184
+ * // From what process/workflow
185
+ * processId: 'process_code_review',
186
+ * stepId: 'step_1_review',
187
+ *
188
+ * // Status and timing
189
+ * status: 'in_progress',
190
+ * priority: 'high',
191
+ * assignedAt: new Date(),
192
+ * dueAt: new Date(Date.now() + 24 * 60 * 60 * 1000),
193
+ *
194
+ * // Context
195
+ * context: {
196
+ * pullRequestId: 'pr_789',
197
+ * repository: 'acme/webapp',
198
+ * },
199
+ * }
200
+ * ```
201
+ */
202
+ export interface TaskAssignment {
203
+ /** Unique assignment ID */
204
+ id: string
205
+
206
+ /** Task identifier */
207
+ taskId: string
208
+
209
+ /** Task type (for routing) */
210
+ taskType: string
211
+
212
+ /** Task description */
213
+ description?: string
214
+
215
+ /** Who is assigned */
216
+ assignee: AssigneeRef
217
+
218
+ /** Required role for this task */
219
+ role?: string
220
+
221
+ /** Source process ID */
222
+ processId?: string
223
+
224
+ /** Source workflow ID */
225
+ workflowId?: string
226
+
227
+ /** Step ID within process/workflow */
228
+ stepId?: string
229
+
230
+ /** Current status */
231
+ status: TaskStatus
232
+
233
+ /** Priority */
234
+ priority?: TaskPriority
235
+
236
+ /** When assigned */
237
+ assignedAt: Date
238
+
239
+ /** Who assigned it */
240
+ assignedBy?: AssigneeRef
241
+
242
+ /** Due date */
243
+ dueAt?: Date
244
+
245
+ /** Started at */
246
+ startedAt?: Date
247
+
248
+ /** Completed at */
249
+ completedAt?: Date
250
+
251
+ /** Task context/data */
252
+ context?: Record<string, unknown>
253
+
254
+ /** Task result */
255
+ result?: unknown
256
+
257
+ /** Notes */
258
+ notes?: string
259
+
260
+ /** Metadata */
261
+ metadata?: Record<string, unknown>
262
+ }
263
+
264
+ /**
265
+ * Reference to an assignee (worker, team, or role)
266
+ */
267
+ export interface AssigneeRef {
268
+ /** Type of assignee */
269
+ type: 'worker' | 'team' | 'role'
270
+ /** Assignee ID */
271
+ id: string
272
+ /** Display name */
273
+ name?: string
274
+ }
275
+
276
+ // =============================================================================
277
+ // Role-Based Task Routing
278
+ // =============================================================================
279
+
280
+ /**
281
+ * Task routing rule - determines who handles what tasks
282
+ *
283
+ * @example
284
+ * ```ts
285
+ * const routingRules: TaskRoutingRule[] = [
286
+ * {
287
+ * taskType: 'code-review',
288
+ * requiredRole: 'engineer',
289
+ * requiredLevel: 2,
290
+ * requiredSkills: ['TypeScript'],
291
+ * preferWorkerType: 'human',
292
+ * },
293
+ * {
294
+ * taskType: 'expense-approval',
295
+ * requiredRole: 'manager',
296
+ * amountThreshold: 1000,
297
+ * escalateAbove: 5000, // Escalate to director above $5k
298
+ * escalateTo: 'director',
299
+ * },
300
+ * {
301
+ * taskType: 'customer-inquiry',
302
+ * requiredRole: 'agent',
303
+ * preferWorkerType: 'ai',
304
+ * fallbackTo: 'human', // Escalate to human if AI can't handle
305
+ * },
306
+ * ]
307
+ * ```
308
+ */
309
+ export interface TaskRoutingRule {
310
+ /** Task type this rule applies to */
311
+ taskType: string
312
+
313
+ /** Required role type */
314
+ requiredRole?: BusinessRoleType
315
+
316
+ /** Minimum level required */
317
+ requiredLevel?: number
318
+
319
+ /** Required skills */
320
+ requiredSkills?: string[]
321
+
322
+ /** Required permissions */
323
+ requiredPermissions?: string[]
324
+
325
+ /** Preferred worker type */
326
+ preferWorkerType?: 'ai' | 'human' | 'hybrid'
327
+
328
+ /** Amount threshold (for approval tasks) */
329
+ amountThreshold?: number
330
+
331
+ /** Amount above which to escalate */
332
+ escalateAbove?: number
333
+
334
+ /** Role to escalate to */
335
+ escalateTo?: BusinessRoleType | string
336
+
337
+ /** Fallback worker type if preferred unavailable */
338
+ fallbackTo?: 'ai' | 'human'
339
+
340
+ /** Priority for this task type */
341
+ defaultPriority?: TaskPriority
342
+
343
+ /** SLA in minutes */
344
+ slaMinutes?: number
345
+
346
+ /** Additional conditions */
347
+ conditions?: Record<string, unknown>
348
+ }
349
+
350
+ // =============================================================================
351
+ // Workflow Role - Role within a specific workflow
352
+ // =============================================================================
353
+
354
+ /**
355
+ * Workflow role - defines a role within the context of a workflow
356
+ *
357
+ * @example
358
+ * ```ts
359
+ * const workflowRoles: WorkflowRole[] = [
360
+ * {
361
+ * name: 'Requester',
362
+ * description: 'Person who initiates the request',
363
+ * canInitiate: true,
364
+ * canView: ['all'],
365
+ * },
366
+ * {
367
+ * name: 'Approver',
368
+ * description: 'Person who approves or rejects',
369
+ * tasks: ['review', 'approve', 'reject'],
370
+ * canView: ['details', 'history'],
371
+ * requiredBusinessRole: 'manager',
372
+ * },
373
+ * {
374
+ * name: 'Processor',
375
+ * description: 'Person who processes after approval',
376
+ * tasks: ['process', 'complete'],
377
+ * requiredBusinessRole: 'operator',
378
+ * },
379
+ * ]
380
+ * ```
381
+ */
382
+ export interface WorkflowRole {
383
+ /** Role name within workflow */
384
+ name: string
385
+
386
+ /** Description */
387
+ description?: string
388
+
389
+ /** Can initiate this workflow */
390
+ canInitiate?: boolean
391
+
392
+ /** Tasks this role handles */
393
+ tasks?: string[]
394
+
395
+ /** What this role can view */
396
+ canView?: string[]
397
+
398
+ /** Required business role */
399
+ requiredBusinessRole?: BusinessRoleType | string
400
+
401
+ /** Required permissions */
402
+ requiredPermissions?: string[]
403
+
404
+ /** Minimum level */
405
+ minLevel?: number
406
+ }
407
+
408
+ // =============================================================================
409
+ // Standard Business Roles
410
+ // =============================================================================
411
+
412
+ /**
413
+ * Standard business roles with typical permissions
414
+ */
415
+ export const StandardBusinessRoles: Record<string, Partial<BusinessRole>> = {
416
+ // Executive
417
+ ceo: {
418
+ type: 'ceo',
419
+ name: 'Chief Executive Officer',
420
+ level: 10,
421
+ permissions: { '*': ['manage'] },
422
+ canApprove: ['*'],
423
+ workerType: 'human',
424
+ },
425
+ cto: {
426
+ type: 'cto',
427
+ name: 'Chief Technology Officer',
428
+ level: 10,
429
+ department: 'Technology',
430
+ permissions: {
431
+ technology: ['manage'],
432
+ repository: ['manage'],
433
+ infrastructure: ['manage'],
434
+ },
435
+ canApprove: ['technical-decision', 'architecture', 'technology-budget'],
436
+ workerType: 'human',
437
+ },
438
+ cfo: {
439
+ type: 'cfo',
440
+ name: 'Chief Financial Officer',
441
+ level: 10,
442
+ department: 'Finance',
443
+ permissions: {
444
+ finance: ['manage'],
445
+ budget: ['manage'],
446
+ expense: ['manage'],
447
+ },
448
+ canApprove: ['expense', 'budget', 'financial-decision'],
449
+ workerType: 'human',
450
+ },
451
+
452
+ // Management
453
+ director: {
454
+ type: 'director',
455
+ level: 8,
456
+ permissions: {
457
+ team: ['manage'],
458
+ project: ['manage'],
459
+ budget: ['read', 'edit'],
460
+ },
461
+ canApprove: ['hiring', 'budget-under-50k', 'project'],
462
+ workerType: 'human',
463
+ },
464
+ manager: {
465
+ type: 'manager',
466
+ level: 6,
467
+ permissions: {
468
+ team: ['read', 'edit'],
469
+ project: ['read', 'edit', 'manage'],
470
+ },
471
+ canApprove: ['expense-under-5k', 'time-off', 'code-review'],
472
+ workerType: 'human',
473
+ },
474
+ lead: {
475
+ type: 'lead',
476
+ level: 5,
477
+ permissions: {
478
+ team: ['read'],
479
+ project: ['read', 'edit'],
480
+ repository: ['read', 'edit', 'act:merge'],
481
+ },
482
+ canDelegate: ['code-review', 'testing'],
483
+ workerType: 'hybrid',
484
+ },
485
+
486
+ // Individual Contributors
487
+ engineer: {
488
+ type: 'engineer',
489
+ level: 3,
490
+ department: 'Engineering',
491
+ permissions: {
492
+ repository: ['read', 'edit'],
493
+ project: ['read'],
494
+ },
495
+ canHandle: ['coding', 'code-review', 'bug-fix', 'testing'],
496
+ workerType: 'hybrid',
497
+ },
498
+ analyst: {
499
+ type: 'analyst',
500
+ level: 3,
501
+ permissions: {
502
+ data: ['read'],
503
+ report: ['read', 'edit'],
504
+ },
505
+ canHandle: ['data-analysis', 'reporting', 'research'],
506
+ workerType: 'hybrid',
507
+ },
508
+
509
+ // Operations
510
+ agent: {
511
+ type: 'agent',
512
+ level: 2,
513
+ permissions: {
514
+ ticket: ['read', 'edit', 'act:respond', 'act:escalate'],
515
+ customer: ['read'],
516
+ },
517
+ canHandle: ['customer-inquiry', 'support-ticket', 'basic-troubleshooting'],
518
+ workerType: 'ai', // AI-first
519
+ },
520
+ assistant: {
521
+ type: 'assistant',
522
+ level: 1,
523
+ permissions: {
524
+ calendar: ['read', 'edit'],
525
+ email: ['read', 'act:draft'],
526
+ task: ['read', 'edit'],
527
+ },
528
+ canHandle: ['scheduling', 'email-draft', 'task-management', 'research'],
529
+ workerType: 'ai', // AI-first
530
+ },
531
+ }
532
+
533
+ // =============================================================================
534
+ // Helper Functions
535
+ // =============================================================================
536
+
537
+ /**
538
+ * Create a business role from a standard template
539
+ */
540
+ export function createBusinessRole(
541
+ id: string,
542
+ template: keyof typeof StandardBusinessRoles,
543
+ overrides?: Partial<BusinessRole>
544
+ ): BusinessRole {
545
+ const standard = StandardBusinessRoles[template]
546
+ if (!standard) {
547
+ throw new Error(`Unknown role template: ${template}`)
548
+ }
549
+
550
+ return {
551
+ id,
552
+ name: standard.name || template,
553
+ type: standard.type || template,
554
+ ...standard,
555
+ ...overrides,
556
+ } as BusinessRole
557
+ }
558
+
559
+ /**
560
+ * Check if a role has permission for an action on a resource type
561
+ */
562
+ export function hasPermission(
563
+ role: BusinessRole,
564
+ resourceType: string,
565
+ action: string
566
+ ): boolean {
567
+ if (!role.permissions) return false
568
+
569
+ // Check wildcard permissions
570
+ const wildcardPerms = role.permissions['*']
571
+ if (wildcardPerms) {
572
+ if (wildcardPerms.includes('manage') || wildcardPerms.includes('*')) return true
573
+ if (wildcardPerms.includes(action)) return true
574
+ }
575
+
576
+ // Check resource-specific permissions
577
+ const resourcePerms = role.permissions[resourceType]
578
+ if (!resourcePerms) return false
579
+
580
+ // Check for exact match
581
+ if (resourcePerms.includes(action)) return true
582
+
583
+ // Check for 'manage' which includes all actions
584
+ if (resourcePerms.includes('manage') || resourcePerms.includes('*')) return true
585
+
586
+ // Check for act:* pattern
587
+ if (action.startsWith('act:')) {
588
+ if (resourcePerms.includes('act:*')) return true
589
+ }
590
+
591
+ return false
592
+ }
593
+
594
+ /**
595
+ * Check if a role can handle a task type
596
+ */
597
+ export function canHandleTask(role: BusinessRole, taskType: string): boolean {
598
+ if (!role.canHandle) return false
599
+ return role.canHandle.includes(taskType) || role.canHandle.includes('*')
600
+ }
601
+
602
+ /**
603
+ * Check if a role can approve a request type
604
+ */
605
+ export function canApproveRequest(role: BusinessRole, requestType: string): boolean {
606
+ if (!role.canApprove) return false
607
+ return role.canApprove.includes(requestType) || role.canApprove.includes('*')
608
+ }
609
+
610
+ /**
611
+ * Check if a role can delegate a task type
612
+ */
613
+ export function canDelegateTask(role: BusinessRole, taskType: string): boolean {
614
+ if (!role.canDelegate) return false
615
+ return role.canDelegate.includes(taskType) || role.canDelegate.includes('*')
616
+ }
617
+
618
+ /**
619
+ * Find the best role for a task based on routing rules
620
+ */
621
+ export function findRoleForTask(
622
+ taskType: string,
623
+ rules: TaskRoutingRule[],
624
+ context?: { amount?: number; skills?: string[] }
625
+ ): TaskRoutingRule | undefined {
626
+ const matchingRules = rules.filter(rule => rule.taskType === taskType)
627
+
628
+ if (matchingRules.length === 0) return undefined
629
+
630
+ // If there's an amount and escalation rules, check those
631
+ if (context?.amount) {
632
+ for (const rule of matchingRules) {
633
+ if (rule.escalateAbove && context.amount > rule.escalateAbove) {
634
+ // Find the escalated rule
635
+ const escalatedRule = rules.find(
636
+ r => r.taskType === taskType && r.requiredRole === rule.escalateTo
637
+ )
638
+ if (escalatedRule) return escalatedRule
639
+ }
640
+ }
641
+ }
642
+
643
+ // Return the first matching rule
644
+ return matchingRules[0]
645
+ }
646
+
647
+ /**
648
+ * Create a task assignment
649
+ */
650
+ export function createTaskAssignment(
651
+ taskId: string,
652
+ taskType: string,
653
+ assignee: AssigneeRef,
654
+ options?: Partial<Omit<TaskAssignment, 'id' | 'taskId' | 'taskType' | 'assignee' | 'status' | 'assignedAt'>>
655
+ ): TaskAssignment {
656
+ return {
657
+ id: `assign_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`,
658
+ taskId,
659
+ taskType,
660
+ assignee,
661
+ status: 'assigned',
662
+ assignedAt: new Date(),
663
+ priority: 'normal',
664
+ ...options,
665
+ }
666
+ }
667
+
668
+ /**
669
+ * Transition task assignment status
670
+ */
671
+ export function transitionTaskStatus(
672
+ assignment: TaskAssignment,
673
+ newStatus: TaskStatus,
674
+ options?: { result?: unknown; notes?: string }
675
+ ): TaskAssignment {
676
+ const now = new Date()
677
+
678
+ return {
679
+ ...assignment,
680
+ status: newStatus,
681
+ ...(newStatus === 'in_progress' && !assignment.startedAt ? { startedAt: now } : {}),
682
+ ...(newStatus === 'completed' || newStatus === 'failed' ? { completedAt: now } : {}),
683
+ ...(options?.result ? { result: options.result } : {}),
684
+ ...(options?.notes ? { notes: options.notes } : {}),
685
+ }
686
+ }