business-as-code 2.1.1 → 2.3.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 (212) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +2 -0
  3. package/package.json +7 -4
  4. package/src/dollar.ts +5 -2
  5. package/src/entities/organization.ts +31 -18
  6. package/src/goals.ts +78 -12
  7. package/src/index.ts +48 -18
  8. package/src/kpis.ts +62 -8
  9. package/src/metrics.ts +92 -79
  10. package/src/okrs.ts +120 -20
  11. package/src/organization.ts +12 -15
  12. package/src/process.ts +11 -12
  13. package/src/product.ts +8 -9
  14. package/src/queries.ts +238 -75
  15. package/src/roles.ts +62 -61
  16. package/src/workflow.ts +22 -15
  17. package/test/business.test.ts +282 -0
  18. package/test/dollar.test.ts +270 -0
  19. package/test/entities.test.ts +628 -0
  20. package/test/financials.test.ts +539 -0
  21. package/test/goals.test.ts +451 -0
  22. package/{src → test}/index.test.ts +1 -1
  23. package/test/kpis.test.ts +440 -0
  24. package/test/metrics.test.ts +744 -0
  25. package/test/okrs.test.ts +741 -0
  26. package/test/organization.test.ts +548 -0
  27. package/test/process.test.ts +503 -0
  28. package/test/product.test.ts +430 -0
  29. package/test/queries.test.ts +556 -0
  30. package/test/roles.test.ts +546 -0
  31. package/test/service.test.ts +450 -0
  32. package/test/types.test.ts +1141 -0
  33. package/test/vision.test.ts +214 -0
  34. package/test/workflow.test.ts +501 -0
  35. package/vitest.config.ts +47 -0
  36. package/.turbo/turbo-build.log +0 -5
  37. package/dist/business.d.ts +0 -62
  38. package/dist/business.d.ts.map +0 -1
  39. package/dist/business.js +0 -109
  40. package/dist/business.js.map +0 -1
  41. package/dist/dollar.d.ts +0 -60
  42. package/dist/dollar.d.ts.map +0 -1
  43. package/dist/dollar.js +0 -107
  44. package/dist/dollar.js.map +0 -1
  45. package/dist/entities/assets.d.ts +0 -21
  46. package/dist/entities/assets.d.ts.map +0 -1
  47. package/dist/entities/assets.js +0 -323
  48. package/dist/entities/assets.js.map +0 -1
  49. package/dist/entities/business.d.ts +0 -36
  50. package/dist/entities/business.d.ts.map +0 -1
  51. package/dist/entities/business.js +0 -370
  52. package/dist/entities/business.js.map +0 -1
  53. package/dist/entities/communication.d.ts +0 -21
  54. package/dist/entities/communication.d.ts.map +0 -1
  55. package/dist/entities/communication.js +0 -255
  56. package/dist/entities/communication.js.map +0 -1
  57. package/dist/entities/customers.d.ts +0 -58
  58. package/dist/entities/customers.d.ts.map +0 -1
  59. package/dist/entities/customers.js +0 -989
  60. package/dist/entities/customers.js.map +0 -1
  61. package/dist/entities/financials.d.ts +0 -59
  62. package/dist/entities/financials.d.ts.map +0 -1
  63. package/dist/entities/financials.js +0 -932
  64. package/dist/entities/financials.js.map +0 -1
  65. package/dist/entities/goals.d.ts +0 -58
  66. package/dist/entities/goals.d.ts.map +0 -1
  67. package/dist/entities/goals.js +0 -800
  68. package/dist/entities/goals.js.map +0 -1
  69. package/dist/entities/index.d.ts +0 -299
  70. package/dist/entities/index.d.ts.map +0 -1
  71. package/dist/entities/index.js +0 -198
  72. package/dist/entities/index.js.map +0 -1
  73. package/dist/entities/legal.d.ts +0 -21
  74. package/dist/entities/legal.d.ts.map +0 -1
  75. package/dist/entities/legal.js +0 -301
  76. package/dist/entities/legal.js.map +0 -1
  77. package/dist/entities/market.d.ts +0 -21
  78. package/dist/entities/market.d.ts.map +0 -1
  79. package/dist/entities/market.js +0 -301
  80. package/dist/entities/market.js.map +0 -1
  81. package/dist/entities/marketing.d.ts +0 -67
  82. package/dist/entities/marketing.d.ts.map +0 -1
  83. package/dist/entities/marketing.js +0 -1157
  84. package/dist/entities/marketing.js.map +0 -1
  85. package/dist/entities/offerings.d.ts +0 -51
  86. package/dist/entities/offerings.d.ts.map +0 -1
  87. package/dist/entities/offerings.js +0 -727
  88. package/dist/entities/offerings.js.map +0 -1
  89. package/dist/entities/operations.d.ts +0 -58
  90. package/dist/entities/operations.d.ts.map +0 -1
  91. package/dist/entities/operations.js +0 -787
  92. package/dist/entities/operations.js.map +0 -1
  93. package/dist/entities/organization.d.ts +0 -57
  94. package/dist/entities/organization.d.ts.map +0 -1
  95. package/dist/entities/organization.js +0 -807
  96. package/dist/entities/organization.js.map +0 -1
  97. package/dist/entities/partnerships.d.ts +0 -21
  98. package/dist/entities/partnerships.d.ts.map +0 -1
  99. package/dist/entities/partnerships.js +0 -300
  100. package/dist/entities/partnerships.js.map +0 -1
  101. package/dist/entities/planning.d.ts +0 -87
  102. package/dist/entities/planning.d.ts.map +0 -1
  103. package/dist/entities/planning.js +0 -271
  104. package/dist/entities/planning.js.map +0 -1
  105. package/dist/entities/projects.d.ts +0 -25
  106. package/dist/entities/projects.d.ts.map +0 -1
  107. package/dist/entities/projects.js +0 -349
  108. package/dist/entities/projects.js.map +0 -1
  109. package/dist/entities/risk.d.ts +0 -21
  110. package/dist/entities/risk.d.ts.map +0 -1
  111. package/dist/entities/risk.js +0 -293
  112. package/dist/entities/risk.js.map +0 -1
  113. package/dist/entities/sales.d.ts +0 -72
  114. package/dist/entities/sales.d.ts.map +0 -1
  115. package/dist/entities/sales.js +0 -1248
  116. package/dist/entities/sales.js.map +0 -1
  117. package/dist/financials.d.ts +0 -130
  118. package/dist/financials.d.ts.map +0 -1
  119. package/dist/financials.js +0 -297
  120. package/dist/financials.js.map +0 -1
  121. package/dist/goals.d.ts +0 -87
  122. package/dist/goals.d.ts.map +0 -1
  123. package/dist/goals.js +0 -215
  124. package/dist/goals.js.map +0 -1
  125. package/dist/index.d.ts +0 -97
  126. package/dist/index.d.ts.map +0 -1
  127. package/dist/index.js +0 -132
  128. package/dist/index.js.map +0 -1
  129. package/dist/kpis.d.ts +0 -118
  130. package/dist/kpis.d.ts.map +0 -1
  131. package/dist/kpis.js +0 -232
  132. package/dist/kpis.js.map +0 -1
  133. package/dist/metrics.d.ts +0 -448
  134. package/dist/metrics.d.ts.map +0 -1
  135. package/dist/metrics.js +0 -325
  136. package/dist/metrics.js.map +0 -1
  137. package/dist/okrs.d.ts +0 -123
  138. package/dist/okrs.d.ts.map +0 -1
  139. package/dist/okrs.js +0 -269
  140. package/dist/okrs.js.map +0 -1
  141. package/dist/organization.d.ts +0 -585
  142. package/dist/organization.d.ts.map +0 -1
  143. package/dist/organization.js +0 -173
  144. package/dist/organization.js.map +0 -1
  145. package/dist/process.d.ts +0 -112
  146. package/dist/process.d.ts.map +0 -1
  147. package/dist/process.js +0 -241
  148. package/dist/process.js.map +0 -1
  149. package/dist/product.d.ts +0 -85
  150. package/dist/product.d.ts.map +0 -1
  151. package/dist/product.js +0 -145
  152. package/dist/product.js.map +0 -1
  153. package/dist/queries.d.ts +0 -304
  154. package/dist/queries.d.ts.map +0 -1
  155. package/dist/queries.js +0 -415
  156. package/dist/queries.js.map +0 -1
  157. package/dist/roles.d.ts +0 -340
  158. package/dist/roles.d.ts.map +0 -1
  159. package/dist/roles.js +0 -255
  160. package/dist/roles.js.map +0 -1
  161. package/dist/service.d.ts +0 -61
  162. package/dist/service.d.ts.map +0 -1
  163. package/dist/service.js +0 -140
  164. package/dist/service.js.map +0 -1
  165. package/dist/types.d.ts +0 -459
  166. package/dist/types.d.ts.map +0 -1
  167. package/dist/types.js +0 -5
  168. package/dist/types.js.map +0 -1
  169. package/dist/vision.d.ts +0 -38
  170. package/dist/vision.d.ts.map +0 -1
  171. package/dist/vision.js +0 -68
  172. package/dist/vision.js.map +0 -1
  173. package/dist/workflow.d.ts +0 -115
  174. package/dist/workflow.d.ts.map +0 -1
  175. package/dist/workflow.js +0 -247
  176. package/dist/workflow.js.map +0 -1
  177. package/src/business.js +0 -108
  178. package/src/dollar.js +0 -106
  179. package/src/entities/assets.js +0 -322
  180. package/src/entities/business.js +0 -369
  181. package/src/entities/communication.js +0 -254
  182. package/src/entities/customers.js +0 -988
  183. package/src/entities/financials.js +0 -931
  184. package/src/entities/goals.js +0 -799
  185. package/src/entities/index.js +0 -197
  186. package/src/entities/legal.js +0 -300
  187. package/src/entities/market.js +0 -300
  188. package/src/entities/marketing.js +0 -1156
  189. package/src/entities/offerings.js +0 -726
  190. package/src/entities/operations.js +0 -786
  191. package/src/entities/organization.js +0 -806
  192. package/src/entities/partnerships.js +0 -299
  193. package/src/entities/planning.js +0 -270
  194. package/src/entities/projects.js +0 -348
  195. package/src/entities/risk.js +0 -292
  196. package/src/entities/sales.js +0 -1247
  197. package/src/financials.js +0 -296
  198. package/src/goals.js +0 -214
  199. package/src/index.js +0 -131
  200. package/src/index.test.js +0 -274
  201. package/src/kpis.js +0 -231
  202. package/src/metrics.js +0 -324
  203. package/src/okrs.js +0 -268
  204. package/src/organization.js +0 -172
  205. package/src/process.js +0 -240
  206. package/src/product.js +0 -144
  207. package/src/queries.js +0 -414
  208. package/src/roles.js +0 -254
  209. package/src/service.js +0 -139
  210. package/src/types.js +0 -4
  211. package/src/vision.js +0 -67
  212. package/src/workflow.js +0 -246
package/src/queries.js DELETED
@@ -1,414 +0,0 @@
1
- /**
2
- * Live Queries & Views
3
- *
4
- * Query definitions for real-time analytics against ai-database (ClickHouse-backed).
5
- * These are NOT batch reports - they're live, composable queries that execute
6
- * in real-time against a performant OLAP database.
7
- *
8
- * @packageDocumentation
9
- */
10
- // =============================================================================
11
- // Metric Definitions (Standard SaaS Metrics as Queries)
12
- // =============================================================================
13
- /**
14
- * Standard SaaS metric dimensions
15
- */
16
- export const StandardDimensions = {
17
- // Time
18
- date: { name: 'date', field: 'date', type: 'date', description: 'Event date' },
19
- month: { name: 'month', field: 'date', type: 'date', granularity: 'month', description: 'Month' },
20
- quarter: { name: 'quarter', field: 'date', type: 'date', granularity: 'quarter', description: 'Quarter' },
21
- year: { name: 'year', field: 'date', type: 'date', granularity: 'year', description: 'Year' },
22
- // Customer
23
- customerId: { name: 'customerId', field: 'customer_id', type: 'string', description: 'Customer ID' },
24
- customerSegment: { name: 'customerSegment', field: 'customer_segment', type: 'string', description: 'Customer segment' },
25
- plan: { name: 'plan', field: 'plan', type: 'string', description: 'Subscription plan' },
26
- cohort: { name: 'cohort', field: 'cohort', type: 'string', description: 'Customer cohort' },
27
- // Product
28
- productId: { name: 'productId', field: 'product_id', type: 'string', description: 'Product ID' },
29
- productName: { name: 'productName', field: 'product_name', type: 'string', description: 'Product name' },
30
- feature: { name: 'feature', field: 'feature', type: 'string', description: 'Feature name' },
31
- // Geography
32
- country: { name: 'country', field: 'country', type: 'string', description: 'Country' },
33
- region: { name: 'region', field: 'region', type: 'string', description: 'Region' },
34
- // Channel
35
- channel: { name: 'channel', field: 'channel', type: 'string', description: 'Acquisition channel' },
36
- source: { name: 'source', field: 'source', type: 'string', description: 'Traffic source' },
37
- campaign: { name: 'campaign', field: 'campaign', type: 'string', description: 'Marketing campaign' },
38
- };
39
- /**
40
- * Standard SaaS metric measures
41
- */
42
- export const StandardMeasures = {
43
- // Revenue
44
- revenue: { name: 'revenue', field: 'revenue', aggregate: 'sum', type: 'currency', description: 'Total revenue' },
45
- mrr: { name: 'mrr', field: 'mrr', aggregate: 'sum', type: 'currency', description: 'Monthly recurring revenue' },
46
- newMrr: { name: 'newMrr', field: 'new_mrr', aggregate: 'sum', type: 'currency', description: 'New MRR' },
47
- expansionMrr: { name: 'expansionMrr', field: 'expansion_mrr', aggregate: 'sum', type: 'currency', description: 'Expansion MRR' },
48
- contractionMrr: { name: 'contractionMrr', field: 'contraction_mrr', aggregate: 'sum', type: 'currency', description: 'Contraction MRR' },
49
- churnedMrr: { name: 'churnedMrr', field: 'churned_mrr', aggregate: 'sum', type: 'currency', description: 'Churned MRR' },
50
- // Customers
51
- customers: { name: 'customers', field: 'customer_id', aggregate: 'countDistinct', type: 'number', description: 'Unique customers' },
52
- newCustomers: { name: 'newCustomers', field: 'new_customer_id', aggregate: 'countDistinct', type: 'number', description: 'New customers' },
53
- churnedCustomers: { name: 'churnedCustomers', field: 'churned_customer_id', aggregate: 'countDistinct', type: 'number', description: 'Churned customers' },
54
- // Usage
55
- events: { name: 'events', field: 'event_id', aggregate: 'count', type: 'number', description: 'Event count' },
56
- sessions: { name: 'sessions', field: 'session_id', aggregate: 'countDistinct', type: 'number', description: 'Unique sessions' },
57
- activeUsers: { name: 'activeUsers', field: 'user_id', aggregate: 'countDistinct', type: 'number', description: 'Active users' },
58
- // Costs
59
- cogs: { name: 'cogs', field: 'cogs', aggregate: 'sum', type: 'currency', description: 'Cost of goods sold' },
60
- salesSpend: { name: 'salesSpend', field: 'sales_spend', aggregate: 'sum', type: 'currency', description: 'Sales spend' },
61
- marketingSpend: { name: 'marketingSpend', field: 'marketing_spend', aggregate: 'sum', type: 'currency', description: 'Marketing spend' },
62
- };
63
- /**
64
- * Calculated SaaS metrics
65
- */
66
- export const CalculatedMetrics = {
67
- // Revenue metrics
68
- arr: {
69
- name: 'arr',
70
- expression: 'mrr * 12',
71
- measures: ['mrr'],
72
- type: 'currency',
73
- description: 'Annual recurring revenue',
74
- },
75
- netNewMrr: {
76
- name: 'netNewMrr',
77
- expression: 'newMrr + expansionMrr - contractionMrr - churnedMrr',
78
- measures: ['newMrr', 'expansionMrr', 'contractionMrr', 'churnedMrr'],
79
- type: 'currency',
80
- description: 'Net new MRR',
81
- },
82
- arpu: {
83
- name: 'arpu',
84
- expression: 'mrr / customers',
85
- measures: ['mrr', 'customers'],
86
- type: 'currency',
87
- description: 'Average revenue per user',
88
- },
89
- // Margin metrics
90
- grossProfit: {
91
- name: 'grossProfit',
92
- expression: 'revenue - cogs',
93
- measures: ['revenue', 'cogs'],
94
- type: 'currency',
95
- description: 'Gross profit',
96
- },
97
- grossMargin: {
98
- name: 'grossMargin',
99
- expression: '(revenue - cogs) / revenue * 100',
100
- measures: ['revenue', 'cogs'],
101
- type: 'percent',
102
- description: 'Gross margin percentage',
103
- },
104
- // Efficiency metrics
105
- cac: {
106
- name: 'cac',
107
- expression: '(salesSpend + marketingSpend) / newCustomers',
108
- measures: ['salesSpend', 'marketingSpend', 'newCustomers'],
109
- type: 'currency',
110
- description: 'Customer acquisition cost',
111
- },
112
- ltv: {
113
- name: 'ltv',
114
- expression: 'arpu * grossMargin / 100 / churnRate',
115
- measures: ['arpu', 'grossMargin'],
116
- type: 'currency',
117
- description: 'Customer lifetime value',
118
- },
119
- ltvCacRatio: {
120
- name: 'ltvCacRatio',
121
- expression: 'ltv / cac',
122
- measures: ['ltv', 'cac'],
123
- type: 'number',
124
- description: 'LTV:CAC ratio',
125
- },
126
- // Churn metrics
127
- customerChurnRate: {
128
- name: 'customerChurnRate',
129
- expression: 'churnedCustomers / customers * 100',
130
- measures: ['churnedCustomers', 'customers'],
131
- type: 'percent',
132
- description: 'Customer churn rate',
133
- },
134
- revenueChurnRate: {
135
- name: 'revenueChurnRate',
136
- expression: 'churnedMrr / mrr * 100',
137
- measures: ['churnedMrr', 'mrr'],
138
- type: 'percent',
139
- description: 'Revenue churn rate',
140
- },
141
- nrr: {
142
- name: 'nrr',
143
- expression: '(mrr + expansionMrr - contractionMrr - churnedMrr) / mrr * 100',
144
- measures: ['mrr', 'expansionMrr', 'contractionMrr', 'churnedMrr'],
145
- type: 'percent',
146
- description: 'Net revenue retention',
147
- },
148
- // Growth metrics
149
- quickRatio: {
150
- name: 'quickRatio',
151
- expression: '(newMrr + expansionMrr) / (contractionMrr + churnedMrr)',
152
- measures: ['newMrr', 'expansionMrr', 'contractionMrr', 'churnedMrr'],
153
- type: 'number',
154
- description: 'SaaS Quick Ratio',
155
- },
156
- magicNumber: {
157
- name: 'magicNumber',
158
- expression: 'netNewMrr * 12 / (salesSpend + marketingSpend)',
159
- measures: ['netNewMrr', 'salesSpend', 'marketingSpend'],
160
- type: 'number',
161
- description: 'Magic Number',
162
- },
163
- };
164
- // =============================================================================
165
- // Query Builder Functions
166
- // =============================================================================
167
- /**
168
- * Create a query
169
- */
170
- export function query(name, source) {
171
- return new QueryBuilder(name, source);
172
- }
173
- /**
174
- * Fluent query builder
175
- */
176
- export class QueryBuilder {
177
- _query;
178
- constructor(name, source) {
179
- this._query = { name, source };
180
- }
181
- describe(description) {
182
- this._query.description = description;
183
- return this;
184
- }
185
- dimensions(...dims) {
186
- this._query.dimensions = dims;
187
- return this;
188
- }
189
- measures(...measures) {
190
- this._query.measures = measures;
191
- return this;
192
- }
193
- filter(field, operator, value) {
194
- if (!this._query.filters)
195
- this._query.filters = [];
196
- this._query.filters.push({ field, operator, value });
197
- return this;
198
- }
199
- where(filters) {
200
- this._query.filters = filters;
201
- return this;
202
- }
203
- timeRange(field, start, end, granularity) {
204
- this._query.timeRange = { field, start, end, granularity };
205
- return this;
206
- }
207
- last(duration, field = 'date') {
208
- this._query.timeRange = { field, start: `-${duration}` };
209
- return this;
210
- }
211
- sort(field, direction = 'desc') {
212
- if (!this._query.sort)
213
- this._query.sort = [];
214
- this._query.sort.push({ field, direction });
215
- return this;
216
- }
217
- limit(n) {
218
- this._query.limit = n;
219
- return this;
220
- }
221
- offset(n) {
222
- this._query.offset = n;
223
- return this;
224
- }
225
- tags(...tags) {
226
- this._query.tags = tags;
227
- return this;
228
- }
229
- owner(owner) {
230
- this._query.owner = owner;
231
- return this;
232
- }
233
- build() {
234
- return { ...this._query };
235
- }
236
- }
237
- // =============================================================================
238
- // Pre-built SaaS Metric Queries
239
- // =============================================================================
240
- /**
241
- * MRR Overview query
242
- */
243
- export const MrrOverview = query('mrr_overview', 'revenue_events')
244
- .describe('Monthly recurring revenue breakdown')
245
- .dimensions('month')
246
- .measures('mrr', 'newMrr', 'expansionMrr', 'contractionMrr', 'churnedMrr', 'netNewMrr')
247
- .last('12m')
248
- .sort('month', 'asc')
249
- .build();
250
- /**
251
- * ARR by segment query
252
- */
253
- export const ArrBySegment = query('arr_by_segment', 'revenue_events')
254
- .describe('Annual recurring revenue by customer segment')
255
- .dimensions('customerSegment')
256
- .measures('arr', 'customers', 'arpu')
257
- .last('1m')
258
- .sort('arr', 'desc')
259
- .build();
260
- /**
261
- * Customer cohort retention query
262
- */
263
- export const CohortRetention = query('cohort_retention', 'customer_events')
264
- .describe('Customer retention by signup cohort')
265
- .dimensions('cohort', 'month')
266
- .measures('customers', 'mrr')
267
- .last('12m')
268
- .sort('cohort', 'asc')
269
- .build();
270
- /**
271
- * Unit economics query
272
- */
273
- export const UnitEconomics = query('unit_economics', 'financial_events')
274
- .describe('Key unit economics metrics')
275
- .dimensions('month')
276
- .measures('cac', 'ltv', 'ltvCacRatio', 'arpu', 'customerChurnRate')
277
- .last('12m')
278
- .sort('month', 'asc')
279
- .build();
280
- /**
281
- * Revenue by channel query
282
- */
283
- export const RevenueByChannel = query('revenue_by_channel', 'revenue_events')
284
- .describe('Revenue breakdown by acquisition channel')
285
- .dimensions('channel')
286
- .measures('mrr', 'newCustomers', 'cac')
287
- .last('3m')
288
- .sort('mrr', 'desc')
289
- .build();
290
- /**
291
- * Growth metrics query
292
- */
293
- export const GrowthMetrics = query('growth_metrics', 'financial_events')
294
- .describe('Key growth and efficiency metrics')
295
- .dimensions('month')
296
- .measures('mrr', 'netNewMrr', 'quickRatio', 'nrr', 'magicNumber')
297
- .last('12m')
298
- .sort('month', 'asc')
299
- .build();
300
- // =============================================================================
301
- // View Builder
302
- // =============================================================================
303
- /**
304
- * Create a view from a query
305
- */
306
- export function view(name, queryDef) {
307
- return new ViewBuilder(name, queryDef);
308
- }
309
- /**
310
- * Fluent view builder
311
- */
312
- export class ViewBuilder {
313
- _view;
314
- constructor(name, queryDef) {
315
- this._view = { name, query: queryDef };
316
- }
317
- describe(description) {
318
- this._view.description = description;
319
- return this;
320
- }
321
- materialize(refreshInterval, retention) {
322
- this._view.materialized = true;
323
- this._view.refreshInterval = refreshInterval;
324
- this._view.retention = retention;
325
- return this;
326
- }
327
- public() {
328
- this._view.public = true;
329
- return this;
330
- }
331
- owner(owner) {
332
- this._view.owner = owner;
333
- return this;
334
- }
335
- tags(...tags) {
336
- this._view.tags = tags;
337
- return this;
338
- }
339
- build() {
340
- return { ...this._view };
341
- }
342
- }
343
- // =============================================================================
344
- // Dashboard Builder
345
- // =============================================================================
346
- /**
347
- * Create a dashboard
348
- */
349
- export function dashboard(name) {
350
- return new DashboardBuilder(name);
351
- }
352
- /**
353
- * Fluent dashboard builder
354
- */
355
- export class DashboardBuilder {
356
- _dashboard;
357
- constructor(name) {
358
- this._dashboard = { name, views: [] };
359
- }
360
- describe(description) {
361
- this._dashboard.description = description;
362
- return this;
363
- }
364
- add(viewDef, options) {
365
- this._dashboard.views.push(viewDef);
366
- if (options && this._dashboard.layout) {
367
- this._dashboard.layout.items.push({
368
- viewName: viewDef.name,
369
- x: options.x || 0,
370
- y: options.y || 0,
371
- width: options.width || 1,
372
- height: options.height || 1,
373
- visualization: options.visualization,
374
- });
375
- }
376
- return this;
377
- }
378
- layout(columns, rows) {
379
- this._dashboard.layout = { columns, rows, items: [] };
380
- return this;
381
- }
382
- refresh(interval) {
383
- this._dashboard.refreshInterval = interval;
384
- return this;
385
- }
386
- owner(owner) {
387
- this._dashboard.owner = owner;
388
- return this;
389
- }
390
- tags(...tags) {
391
- this._dashboard.tags = tags;
392
- return this;
393
- }
394
- build() {
395
- return { ...this._dashboard };
396
- }
397
- }
398
- // =============================================================================
399
- // Pre-built Dashboards
400
- // =============================================================================
401
- /**
402
- * Executive SaaS Dashboard
403
- */
404
- export const ExecutiveDashboard = dashboard('executive')
405
- .describe('Executive overview of key SaaS metrics')
406
- .layout(4, 3)
407
- .add(view('mrr', MrrOverview).build(), { x: 0, y: 0, width: 2, height: 1, visualization: 'trend' })
408
- .add(view('arr_segments', ArrBySegment).build(), { x: 2, y: 0, width: 2, height: 1, visualization: 'bar' })
409
- .add(view('unit_econ', UnitEconomics).build(), { x: 0, y: 1, width: 2, height: 1, visualization: 'table' })
410
- .add(view('growth', GrowthMetrics).build(), { x: 2, y: 1, width: 2, height: 1, visualization: 'line' })
411
- .add(view('cohorts', CohortRetention).build(), { x: 0, y: 2, width: 4, height: 1, visualization: 'cohort' })
412
- .refresh('5m')
413
- .tags('executive', 'saas', 'metrics')
414
- .build();
package/src/roles.js DELETED
@@ -1,254 +0,0 @@
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
- // Standard Business Roles
13
- // =============================================================================
14
- /**
15
- * Standard business roles with typical permissions
16
- */
17
- export const StandardBusinessRoles = {
18
- // Executive
19
- ceo: {
20
- type: 'ceo',
21
- name: 'Chief Executive Officer',
22
- level: 10,
23
- permissions: { '*': ['manage'] },
24
- canApprove: ['*'],
25
- workerType: 'human',
26
- },
27
- cto: {
28
- type: 'cto',
29
- name: 'Chief Technology Officer',
30
- level: 10,
31
- department: 'Technology',
32
- permissions: {
33
- technology: ['manage'],
34
- repository: ['manage'],
35
- infrastructure: ['manage'],
36
- },
37
- canApprove: ['technical-decision', 'architecture', 'technology-budget'],
38
- workerType: 'human',
39
- },
40
- cfo: {
41
- type: 'cfo',
42
- name: 'Chief Financial Officer',
43
- level: 10,
44
- department: 'Finance',
45
- permissions: {
46
- finance: ['manage'],
47
- budget: ['manage'],
48
- expense: ['manage'],
49
- },
50
- canApprove: ['expense', 'budget', 'financial-decision'],
51
- workerType: 'human',
52
- },
53
- // Management
54
- director: {
55
- type: 'director',
56
- level: 8,
57
- permissions: {
58
- team: ['manage'],
59
- project: ['manage'],
60
- budget: ['read', 'edit'],
61
- },
62
- canApprove: ['hiring', 'budget-under-50k', 'project'],
63
- workerType: 'human',
64
- },
65
- manager: {
66
- type: 'manager',
67
- level: 6,
68
- permissions: {
69
- team: ['read', 'edit'],
70
- project: ['read', 'edit', 'manage'],
71
- },
72
- canApprove: ['expense-under-5k', 'time-off', 'code-review'],
73
- workerType: 'human',
74
- },
75
- lead: {
76
- type: 'lead',
77
- level: 5,
78
- permissions: {
79
- team: ['read'],
80
- project: ['read', 'edit'],
81
- repository: ['read', 'edit', 'act:merge'],
82
- },
83
- canDelegate: ['code-review', 'testing'],
84
- workerType: 'hybrid',
85
- },
86
- // Individual Contributors
87
- engineer: {
88
- type: 'engineer',
89
- level: 3,
90
- department: 'Engineering',
91
- permissions: {
92
- repository: ['read', 'edit'],
93
- project: ['read'],
94
- },
95
- canHandle: ['coding', 'code-review', 'bug-fix', 'testing'],
96
- workerType: 'hybrid',
97
- },
98
- analyst: {
99
- type: 'analyst',
100
- level: 3,
101
- permissions: {
102
- data: ['read'],
103
- report: ['read', 'edit'],
104
- },
105
- canHandle: ['data-analysis', 'reporting', 'research'],
106
- workerType: 'hybrid',
107
- },
108
- // Operations
109
- agent: {
110
- type: 'agent',
111
- level: 2,
112
- permissions: {
113
- ticket: ['read', 'edit', 'act:respond', 'act:escalate'],
114
- customer: ['read'],
115
- },
116
- canHandle: ['customer-inquiry', 'support-ticket', 'basic-troubleshooting'],
117
- workerType: 'ai', // AI-first
118
- },
119
- assistant: {
120
- type: 'assistant',
121
- level: 1,
122
- permissions: {
123
- calendar: ['read', 'edit'],
124
- email: ['read', 'act:draft'],
125
- task: ['read', 'edit'],
126
- },
127
- canHandle: ['scheduling', 'email-draft', 'task-management', 'research'],
128
- workerType: 'ai', // AI-first
129
- },
130
- };
131
- // =============================================================================
132
- // Helper Functions
133
- // =============================================================================
134
- /**
135
- * Create a business role from a standard template
136
- */
137
- export function createBusinessRole(id, template, overrides) {
138
- const standard = StandardBusinessRoles[template];
139
- if (!standard) {
140
- throw new Error(`Unknown role template: ${template}`);
141
- }
142
- return {
143
- id,
144
- name: standard.name || template,
145
- type: standard.type || template,
146
- ...standard,
147
- ...overrides,
148
- };
149
- }
150
- /**
151
- * Check if a role has permission for an action on a resource type
152
- */
153
- export function hasPermission(role, resourceType, action) {
154
- if (!role.permissions)
155
- return false;
156
- // Check wildcard permissions
157
- const wildcardPerms = role.permissions['*'];
158
- if (wildcardPerms) {
159
- if (wildcardPerms.includes('manage') || wildcardPerms.includes('*'))
160
- return true;
161
- if (wildcardPerms.includes(action))
162
- return true;
163
- }
164
- // Check resource-specific permissions
165
- const resourcePerms = role.permissions[resourceType];
166
- if (!resourcePerms)
167
- return false;
168
- // Check for exact match
169
- if (resourcePerms.includes(action))
170
- return true;
171
- // Check for 'manage' which includes all actions
172
- if (resourcePerms.includes('manage') || resourcePerms.includes('*'))
173
- return true;
174
- // Check for act:* pattern
175
- if (action.startsWith('act:')) {
176
- if (resourcePerms.includes('act:*'))
177
- return true;
178
- }
179
- return false;
180
- }
181
- /**
182
- * Check if a role can handle a task type
183
- */
184
- export function canHandleTask(role, taskType) {
185
- if (!role.canHandle)
186
- return false;
187
- return role.canHandle.includes(taskType) || role.canHandle.includes('*');
188
- }
189
- /**
190
- * Check if a role can approve a request type
191
- */
192
- export function canApproveRequest(role, requestType) {
193
- if (!role.canApprove)
194
- return false;
195
- return role.canApprove.includes(requestType) || role.canApprove.includes('*');
196
- }
197
- /**
198
- * Check if a role can delegate a task type
199
- */
200
- export function canDelegateTask(role, taskType) {
201
- if (!role.canDelegate)
202
- return false;
203
- return role.canDelegate.includes(taskType) || role.canDelegate.includes('*');
204
- }
205
- /**
206
- * Find the best role for a task based on routing rules
207
- */
208
- export function findRoleForTask(taskType, rules, context) {
209
- const matchingRules = rules.filter(rule => rule.taskType === taskType);
210
- if (matchingRules.length === 0)
211
- return undefined;
212
- // If there's an amount and escalation rules, check those
213
- if (context?.amount) {
214
- for (const rule of matchingRules) {
215
- if (rule.escalateAbove && context.amount > rule.escalateAbove) {
216
- // Find the escalated rule
217
- const escalatedRule = rules.find(r => r.taskType === taskType && r.requiredRole === rule.escalateTo);
218
- if (escalatedRule)
219
- return escalatedRule;
220
- }
221
- }
222
- }
223
- // Return the first matching rule
224
- return matchingRules[0];
225
- }
226
- /**
227
- * Create a task assignment
228
- */
229
- export function createTaskAssignment(taskId, taskType, assignee, options) {
230
- return {
231
- id: `assign_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`,
232
- taskId,
233
- taskType,
234
- assignee,
235
- status: 'assigned',
236
- assignedAt: new Date(),
237
- priority: 'normal',
238
- ...options,
239
- };
240
- }
241
- /**
242
- * Transition task assignment status
243
- */
244
- export function transitionTaskStatus(assignment, newStatus, options) {
245
- const now = new Date();
246
- return {
247
- ...assignment,
248
- status: newStatus,
249
- ...(newStatus === 'in_progress' && !assignment.startedAt ? { startedAt: now } : {}),
250
- ...(newStatus === 'completed' || newStatus === 'failed' ? { completedAt: now } : {}),
251
- ...(options?.result ? { result: options.result } : {}),
252
- ...(options?.notes ? { notes: options.notes } : {}),
253
- };
254
- }