business-as-code 2.1.3 → 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 (260) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/README.md +2 -0
  3. package/package.json +16 -13
  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/LICENSE +0 -21
  38. package/dist/business.d.ts +0 -62
  39. package/dist/business.d.ts.map +0 -1
  40. package/dist/business.js +0 -109
  41. package/dist/business.js.map +0 -1
  42. package/dist/canvas/activities.d.ts +0 -19
  43. package/dist/canvas/activities.d.ts.map +0 -1
  44. package/dist/canvas/activities.js +0 -20
  45. package/dist/canvas/activities.js.map +0 -1
  46. package/dist/canvas/channels.d.ts +0 -20
  47. package/dist/canvas/channels.d.ts.map +0 -1
  48. package/dist/canvas/channels.js +0 -21
  49. package/dist/canvas/channels.js.map +0 -1
  50. package/dist/canvas/relationships.d.ts +0 -20
  51. package/dist/canvas/relationships.d.ts.map +0 -1
  52. package/dist/canvas/relationships.js +0 -21
  53. package/dist/canvas/relationships.js.map +0 -1
  54. package/dist/canvas/resources.d.ts +0 -20
  55. package/dist/canvas/resources.d.ts.map +0 -1
  56. package/dist/canvas/resources.js +0 -30
  57. package/dist/canvas/resources.js.map +0 -1
  58. package/dist/canvas/revenue.d.ts +0 -22
  59. package/dist/canvas/revenue.d.ts.map +0 -1
  60. package/dist/canvas/revenue.js +0 -30
  61. package/dist/canvas/revenue.js.map +0 -1
  62. package/dist/canvas/segments.d.ts +0 -20
  63. package/dist/canvas/segments.d.ts.map +0 -1
  64. package/dist/canvas/segments.js +0 -28
  65. package/dist/canvas/segments.js.map +0 -1
  66. package/dist/canvas/types.d.ts +0 -232
  67. package/dist/canvas/types.d.ts.map +0 -1
  68. package/dist/canvas/types.js +0 -8
  69. package/dist/canvas/types.js.map +0 -1
  70. package/dist/canvas/value.d.ts +0 -20
  71. package/dist/canvas/value.d.ts.map +0 -1
  72. package/dist/canvas/value.js +0 -21
  73. package/dist/canvas/value.js.map +0 -1
  74. package/dist/dollar.d.ts +0 -60
  75. package/dist/dollar.d.ts.map +0 -1
  76. package/dist/dollar.js +0 -107
  77. package/dist/dollar.js.map +0 -1
  78. package/dist/entities/assets.d.ts +0 -21
  79. package/dist/entities/assets.d.ts.map +0 -1
  80. package/dist/entities/assets.js +0 -323
  81. package/dist/entities/assets.js.map +0 -1
  82. package/dist/entities/business.d.ts +0 -36
  83. package/dist/entities/business.d.ts.map +0 -1
  84. package/dist/entities/business.js +0 -370
  85. package/dist/entities/business.js.map +0 -1
  86. package/dist/entities/communication.d.ts +0 -21
  87. package/dist/entities/communication.d.ts.map +0 -1
  88. package/dist/entities/communication.js +0 -255
  89. package/dist/entities/communication.js.map +0 -1
  90. package/dist/entities/customers.d.ts +0 -58
  91. package/dist/entities/customers.d.ts.map +0 -1
  92. package/dist/entities/customers.js +0 -989
  93. package/dist/entities/customers.js.map +0 -1
  94. package/dist/entities/financials.d.ts +0 -59
  95. package/dist/entities/financials.d.ts.map +0 -1
  96. package/dist/entities/financials.js +0 -932
  97. package/dist/entities/financials.js.map +0 -1
  98. package/dist/entities/goals.d.ts +0 -58
  99. package/dist/entities/goals.d.ts.map +0 -1
  100. package/dist/entities/goals.js +0 -800
  101. package/dist/entities/goals.js.map +0 -1
  102. package/dist/entities/index.d.ts +0 -299
  103. package/dist/entities/index.d.ts.map +0 -1
  104. package/dist/entities/index.js +0 -198
  105. package/dist/entities/index.js.map +0 -1
  106. package/dist/entities/legal.d.ts +0 -21
  107. package/dist/entities/legal.d.ts.map +0 -1
  108. package/dist/entities/legal.js +0 -301
  109. package/dist/entities/legal.js.map +0 -1
  110. package/dist/entities/market.d.ts +0 -21
  111. package/dist/entities/market.d.ts.map +0 -1
  112. package/dist/entities/market.js +0 -301
  113. package/dist/entities/market.js.map +0 -1
  114. package/dist/entities/marketing.d.ts +0 -67
  115. package/dist/entities/marketing.d.ts.map +0 -1
  116. package/dist/entities/marketing.js +0 -1157
  117. package/dist/entities/marketing.js.map +0 -1
  118. package/dist/entities/offerings.d.ts +0 -51
  119. package/dist/entities/offerings.d.ts.map +0 -1
  120. package/dist/entities/offerings.js +0 -727
  121. package/dist/entities/offerings.js.map +0 -1
  122. package/dist/entities/operations.d.ts +0 -58
  123. package/dist/entities/operations.d.ts.map +0 -1
  124. package/dist/entities/operations.js +0 -787
  125. package/dist/entities/operations.js.map +0 -1
  126. package/dist/entities/organization.d.ts +0 -57
  127. package/dist/entities/organization.d.ts.map +0 -1
  128. package/dist/entities/organization.js +0 -807
  129. package/dist/entities/organization.js.map +0 -1
  130. package/dist/entities/partnerships.d.ts +0 -21
  131. package/dist/entities/partnerships.d.ts.map +0 -1
  132. package/dist/entities/partnerships.js +0 -300
  133. package/dist/entities/partnerships.js.map +0 -1
  134. package/dist/entities/planning.d.ts +0 -0
  135. package/dist/entities/planning.d.ts.map +0 -1
  136. package/dist/entities/planning.js +0 -271
  137. package/dist/entities/planning.js.map +0 -1
  138. package/dist/entities/projects.d.ts +0 -25
  139. package/dist/entities/projects.d.ts.map +0 -1
  140. package/dist/entities/projects.js +0 -349
  141. package/dist/entities/projects.js.map +0 -1
  142. package/dist/entities/risk.d.ts +0 -21
  143. package/dist/entities/risk.d.ts.map +0 -1
  144. package/dist/entities/risk.js +0 -293
  145. package/dist/entities/risk.js.map +0 -1
  146. package/dist/entities/sales.d.ts +0 -72
  147. package/dist/entities/sales.d.ts.map +0 -1
  148. package/dist/entities/sales.js +0 -1248
  149. package/dist/entities/sales.js.map +0 -1
  150. package/dist/financials.d.ts +0 -130
  151. package/dist/financials.d.ts.map +0 -1
  152. package/dist/financials.js +0 -297
  153. package/dist/financials.js.map +0 -1
  154. package/dist/goals.d.ts +0 -87
  155. package/dist/goals.d.ts.map +0 -1
  156. package/dist/goals.js +0 -215
  157. package/dist/goals.js.map +0 -1
  158. package/dist/index.d.ts +0 -97
  159. package/dist/index.d.ts.map +0 -1
  160. package/dist/index.js +0 -132
  161. package/dist/index.js.map +0 -1
  162. package/dist/kpis.d.ts +0 -118
  163. package/dist/kpis.d.ts.map +0 -1
  164. package/dist/kpis.js +0 -232
  165. package/dist/kpis.js.map +0 -1
  166. package/dist/metrics.d.ts +0 -448
  167. package/dist/metrics.d.ts.map +0 -1
  168. package/dist/metrics.js +0 -325
  169. package/dist/metrics.js.map +0 -1
  170. package/dist/okrs.d.ts +0 -123
  171. package/dist/okrs.d.ts.map +0 -1
  172. package/dist/okrs.js +0 -269
  173. package/dist/okrs.js.map +0 -1
  174. package/dist/organization.d.ts +0 -585
  175. package/dist/organization.d.ts.map +0 -1
  176. package/dist/organization.js +0 -173
  177. package/dist/organization.js.map +0 -1
  178. package/dist/process.d.ts +0 -112
  179. package/dist/process.d.ts.map +0 -1
  180. package/dist/process.js +0 -241
  181. package/dist/process.js.map +0 -1
  182. package/dist/product.d.ts +0 -85
  183. package/dist/product.d.ts.map +0 -1
  184. package/dist/product.js +0 -145
  185. package/dist/product.js.map +0 -1
  186. package/dist/queries.d.ts +0 -304
  187. package/dist/queries.d.ts.map +0 -1
  188. package/dist/queries.js +0 -415
  189. package/dist/queries.js.map +0 -1
  190. package/dist/roles.d.ts +0 -340
  191. package/dist/roles.d.ts.map +0 -1
  192. package/dist/roles.js +0 -255
  193. package/dist/roles.js.map +0 -1
  194. package/dist/service.d.ts +0 -61
  195. package/dist/service.d.ts.map +0 -1
  196. package/dist/service.js +0 -140
  197. package/dist/service.js.map +0 -1
  198. package/dist/types.d.ts +0 -459
  199. package/dist/types.d.ts.map +0 -1
  200. package/dist/types.js +0 -5
  201. package/dist/types.js.map +0 -1
  202. package/dist/vision.d.ts +0 -38
  203. package/dist/vision.d.ts.map +0 -1
  204. package/dist/vision.js +0 -68
  205. package/dist/vision.js.map +0 -1
  206. package/dist/workflow.d.ts +0 -115
  207. package/dist/workflow.d.ts.map +0 -1
  208. package/dist/workflow.js +0 -247
  209. package/dist/workflow.js.map +0 -1
  210. package/src/business.js +0 -108
  211. package/src/canvas/activities.ts +0 -32
  212. package/src/canvas/canvas.ts +0 -482
  213. package/src/canvas/channels.ts +0 -34
  214. package/src/canvas/costs.ts +0 -43
  215. package/src/canvas/economics.ts +0 -99
  216. package/src/canvas/index.ts +0 -206
  217. package/src/canvas/partnerships.ts +0 -34
  218. package/src/canvas/projections.ts +0 -141
  219. package/src/canvas/relationships.ts +0 -34
  220. package/src/canvas/resources.ts +0 -43
  221. package/src/canvas/revenue.ts +0 -56
  222. package/src/canvas/segments.ts +0 -42
  223. package/src/canvas/types.ts +0 -363
  224. package/src/canvas/value.ts +0 -34
  225. package/src/dollar.js +0 -106
  226. package/src/entities/assets.js +0 -322
  227. package/src/entities/business.js +0 -369
  228. package/src/entities/communication.js +0 -254
  229. package/src/entities/customers.js +0 -988
  230. package/src/entities/financials.js +0 -931
  231. package/src/entities/goals.js +0 -799
  232. package/src/entities/index.js +0 -197
  233. package/src/entities/legal.js +0 -300
  234. package/src/entities/market.js +0 -300
  235. package/src/entities/marketing.js +0 -1156
  236. package/src/entities/offerings.js +0 -726
  237. package/src/entities/operations.js +0 -786
  238. package/src/entities/organization.js +0 -806
  239. package/src/entities/partnerships.js +0 -299
  240. package/src/entities/planning.js +0 -270
  241. package/src/entities/projects.js +0 -348
  242. package/src/entities/risk.js +0 -292
  243. package/src/entities/sales.js +0 -1247
  244. package/src/financials.js +0 -296
  245. package/src/goals.js +0 -214
  246. package/src/index.js +0 -131
  247. package/src/index.test.js +0 -274
  248. package/src/kpis.js +0 -231
  249. package/src/metrics.js +0 -324
  250. package/src/okrs.js +0 -268
  251. package/src/organization.js +0 -172
  252. package/src/process.js +0 -240
  253. package/src/product.js +0 -144
  254. package/src/queries.js +0 -414
  255. package/src/roles.js +0 -254
  256. package/src/service.js +0 -139
  257. package/src/types.js +0 -4
  258. package/src/vision.js +0 -67
  259. package/src/workflow.js +0 -246
  260. package/tests/canvas.test.ts +0 -842
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
- }