business-as-code 2.1.3 → 2.4.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 (235) hide show
  1. package/.turbo/turbo-build.log +4 -5
  2. package/CHANGELOG.md +53 -0
  3. package/README.md +2 -0
  4. package/dist/dollar.d.ts.map +1 -1
  5. package/dist/dollar.js +2 -2
  6. package/dist/dollar.js.map +1 -1
  7. package/dist/entities/organization.d.ts +4 -0
  8. package/dist/entities/organization.d.ts.map +1 -1
  9. package/dist/entities/organization.js +27 -18
  10. package/dist/entities/organization.js.map +1 -1
  11. package/dist/entities/planning.d.ts +87 -0
  12. package/dist/finance/account.d.ts +44 -0
  13. package/dist/finance/account.d.ts.map +1 -0
  14. package/dist/finance/account.js +6 -0
  15. package/dist/finance/account.js.map +1 -0
  16. package/dist/finance/authority.d.ts +78 -0
  17. package/dist/finance/authority.d.ts.map +1 -0
  18. package/dist/finance/authority.js +27 -0
  19. package/dist/finance/authority.js.map +1 -0
  20. package/dist/finance/card.d.ts +36 -0
  21. package/dist/finance/card.d.ts.map +1 -0
  22. package/dist/finance/card.js +6 -0
  23. package/dist/finance/card.js.map +1 -0
  24. package/dist/finance/identity.d.ts +30 -0
  25. package/dist/finance/identity.d.ts.map +1 -0
  26. package/dist/finance/identity.js +8 -0
  27. package/dist/finance/identity.js.map +1 -0
  28. package/dist/finance/index.d.ts +36 -0
  29. package/dist/finance/index.d.ts.map +1 -0
  30. package/dist/finance/index.js +22 -0
  31. package/dist/finance/index.js.map +1 -0
  32. package/dist/finance/ledger.d.ts +24 -0
  33. package/dist/finance/ledger.d.ts.map +1 -0
  34. package/dist/finance/ledger.js +8 -0
  35. package/dist/finance/ledger.js.map +1 -0
  36. package/dist/finance/merchant.d.ts +129 -0
  37. package/dist/finance/merchant.d.ts.map +1 -0
  38. package/dist/finance/merchant.js +21 -0
  39. package/dist/finance/merchant.js.map +1 -0
  40. package/dist/finance/outcome-contract.d.ts +139 -0
  41. package/dist/finance/outcome-contract.d.ts.map +1 -0
  42. package/dist/finance/outcome-contract.js +27 -0
  43. package/dist/finance/outcome-contract.js.map +1 -0
  44. package/dist/finance/port.d.ts +121 -0
  45. package/dist/finance/port.d.ts.map +1 -0
  46. package/dist/finance/port.js +10 -0
  47. package/dist/finance/port.js.map +1 -0
  48. package/dist/finance/pricing.d.ts +154 -0
  49. package/dist/finance/pricing.d.ts.map +1 -0
  50. package/dist/finance/pricing.js +79 -0
  51. package/dist/finance/pricing.js.map +1 -0
  52. package/dist/finance/proof-predicate.d.ts +92 -0
  53. package/dist/finance/proof-predicate.d.ts.map +1 -0
  54. package/dist/finance/proof-predicate.js +80 -0
  55. package/dist/finance/proof-predicate.js.map +1 -0
  56. package/dist/finance/refund.d.ts +44 -0
  57. package/dist/finance/refund.d.ts.map +1 -0
  58. package/dist/finance/refund.js +41 -0
  59. package/dist/finance/refund.js.map +1 -0
  60. package/dist/finance/sla.d.ts +25 -0
  61. package/dist/finance/sla.d.ts.map +1 -0
  62. package/dist/finance/sla.js +7 -0
  63. package/dist/finance/sla.js.map +1 -0
  64. package/dist/finance/types.d.ts +79 -0
  65. package/dist/finance/types.d.ts.map +1 -0
  66. package/dist/finance/types.js +8 -0
  67. package/dist/{canvas → finance}/types.js.map +1 -1
  68. package/dist/goals.d.ts +19 -0
  69. package/dist/goals.d.ts.map +1 -1
  70. package/dist/goals.js +81 -12
  71. package/dist/goals.js.map +1 -1
  72. package/dist/index.d.ts +12 -8
  73. package/dist/index.d.ts.map +1 -1
  74. package/dist/index.js +19 -7
  75. package/dist/index.js.map +1 -1
  76. package/dist/kpis.d.ts +19 -0
  77. package/dist/kpis.d.ts.map +1 -1
  78. package/dist/kpis.js +71 -6
  79. package/dist/kpis.js.map +1 -1
  80. package/dist/metrics.d.ts.map +1 -1
  81. package/dist/metrics.js +29 -24
  82. package/dist/metrics.js.map +1 -1
  83. package/dist/okrs.d.ts +34 -0
  84. package/dist/okrs.d.ts.map +1 -1
  85. package/dist/okrs.js +135 -13
  86. package/dist/okrs.js.map +1 -1
  87. package/dist/organization.d.ts.map +1 -1
  88. package/dist/organization.js +11 -11
  89. package/dist/organization.js.map +1 -1
  90. package/dist/process.d.ts.map +1 -1
  91. package/dist/process.js +13 -12
  92. package/dist/process.js.map +1 -1
  93. package/dist/product.d.ts.map +1 -1
  94. package/dist/product.js +9 -9
  95. package/dist/product.js.map +1 -1
  96. package/dist/queries.d.ts.map +1 -1
  97. package/dist/queries.js +194 -32
  98. package/dist/queries.js.map +1 -1
  99. package/dist/roles.d.ts +25 -31
  100. package/dist/roles.d.ts.map +1 -1
  101. package/dist/roles.js +37 -10
  102. package/dist/roles.js.map +1 -1
  103. package/dist/workflow.d.ts.map +1 -1
  104. package/dist/workflow.js +13 -12
  105. package/dist/workflow.js.map +1 -1
  106. package/package.json +20 -13
  107. package/src/dollar.ts +5 -2
  108. package/src/entities/organization.ts +31 -18
  109. package/src/finance/account.ts +48 -0
  110. package/src/finance/authority.ts +42 -0
  111. package/src/finance/card.ts +38 -0
  112. package/src/finance/identity.ts +31 -0
  113. package/src/finance/index.ts +117 -0
  114. package/src/finance/ledger.ts +26 -0
  115. package/src/finance/merchant.ts +127 -0
  116. package/src/finance/outcome-contract.ts +157 -0
  117. package/src/finance/port.ts +144 -0
  118. package/src/finance/pricing.ts +197 -0
  119. package/src/finance/proof-predicate.ts +106 -0
  120. package/src/finance/refund.ts +52 -0
  121. package/src/finance/sla.ts +33 -0
  122. package/src/finance/types.ts +75 -0
  123. package/src/goals.ts +78 -12
  124. package/src/index.ts +48 -18
  125. package/src/kpis.ts +62 -8
  126. package/src/metrics.ts +92 -79
  127. package/src/okrs.ts +120 -20
  128. package/src/organization.ts +12 -15
  129. package/src/process.ts +11 -12
  130. package/src/product.ts +8 -9
  131. package/src/queries.ts +238 -75
  132. package/src/roles.ts +62 -61
  133. package/src/workflow.ts +22 -15
  134. package/test/business.test.ts +282 -0
  135. package/test/dollar.test.ts +270 -0
  136. package/test/entities.test.ts +628 -0
  137. package/test/financials.test.ts +539 -0
  138. package/test/goals.test.ts +451 -0
  139. package/{src → test}/index.test.ts +1 -1
  140. package/test/kpis.test.ts +440 -0
  141. package/test/metrics.test.ts +744 -0
  142. package/test/okrs.test.ts +741 -0
  143. package/test/organization.test.ts +548 -0
  144. package/test/process.test.ts +503 -0
  145. package/test/product.test.ts +430 -0
  146. package/test/queries.test.ts +556 -0
  147. package/test/roles.test.ts +546 -0
  148. package/test/service.test.ts +450 -0
  149. package/test/types.test.ts +1141 -0
  150. package/test/vision.test.ts +214 -0
  151. package/test/workflow.test.ts +501 -0
  152. package/vitest.config.ts +47 -0
  153. package/LICENSE +0 -21
  154. package/dist/canvas/activities.d.ts +0 -19
  155. package/dist/canvas/activities.d.ts.map +0 -1
  156. package/dist/canvas/activities.js +0 -20
  157. package/dist/canvas/activities.js.map +0 -1
  158. package/dist/canvas/channels.d.ts +0 -20
  159. package/dist/canvas/channels.d.ts.map +0 -1
  160. package/dist/canvas/channels.js +0 -21
  161. package/dist/canvas/channels.js.map +0 -1
  162. package/dist/canvas/relationships.d.ts +0 -20
  163. package/dist/canvas/relationships.d.ts.map +0 -1
  164. package/dist/canvas/relationships.js +0 -21
  165. package/dist/canvas/relationships.js.map +0 -1
  166. package/dist/canvas/resources.d.ts +0 -20
  167. package/dist/canvas/resources.d.ts.map +0 -1
  168. package/dist/canvas/resources.js +0 -30
  169. package/dist/canvas/resources.js.map +0 -1
  170. package/dist/canvas/revenue.d.ts +0 -22
  171. package/dist/canvas/revenue.d.ts.map +0 -1
  172. package/dist/canvas/revenue.js +0 -30
  173. package/dist/canvas/revenue.js.map +0 -1
  174. package/dist/canvas/segments.d.ts +0 -20
  175. package/dist/canvas/segments.d.ts.map +0 -1
  176. package/dist/canvas/segments.js +0 -28
  177. package/dist/canvas/segments.js.map +0 -1
  178. package/dist/canvas/types.d.ts +0 -232
  179. package/dist/canvas/types.d.ts.map +0 -1
  180. package/dist/canvas/types.js +0 -8
  181. package/dist/canvas/value.d.ts +0 -20
  182. package/dist/canvas/value.d.ts.map +0 -1
  183. package/dist/canvas/value.js +0 -21
  184. package/dist/canvas/value.js.map +0 -1
  185. package/src/business.js +0 -108
  186. package/src/canvas/activities.ts +0 -32
  187. package/src/canvas/canvas.ts +0 -482
  188. package/src/canvas/channels.ts +0 -34
  189. package/src/canvas/costs.ts +0 -43
  190. package/src/canvas/economics.ts +0 -99
  191. package/src/canvas/index.ts +0 -206
  192. package/src/canvas/partnerships.ts +0 -34
  193. package/src/canvas/projections.ts +0 -141
  194. package/src/canvas/relationships.ts +0 -34
  195. package/src/canvas/resources.ts +0 -43
  196. package/src/canvas/revenue.ts +0 -56
  197. package/src/canvas/segments.ts +0 -42
  198. package/src/canvas/types.ts +0 -363
  199. package/src/canvas/value.ts +0 -34
  200. package/src/dollar.js +0 -106
  201. package/src/entities/assets.js +0 -322
  202. package/src/entities/business.js +0 -369
  203. package/src/entities/communication.js +0 -254
  204. package/src/entities/customers.js +0 -988
  205. package/src/entities/financials.js +0 -931
  206. package/src/entities/goals.js +0 -799
  207. package/src/entities/index.js +0 -197
  208. package/src/entities/legal.js +0 -300
  209. package/src/entities/market.js +0 -300
  210. package/src/entities/marketing.js +0 -1156
  211. package/src/entities/offerings.js +0 -726
  212. package/src/entities/operations.js +0 -786
  213. package/src/entities/organization.js +0 -806
  214. package/src/entities/partnerships.js +0 -299
  215. package/src/entities/planning.js +0 -270
  216. package/src/entities/projects.js +0 -348
  217. package/src/entities/risk.js +0 -292
  218. package/src/entities/sales.js +0 -1247
  219. package/src/financials.js +0 -296
  220. package/src/goals.js +0 -214
  221. package/src/index.js +0 -131
  222. package/src/index.test.js +0 -274
  223. package/src/kpis.js +0 -231
  224. package/src/metrics.js +0 -324
  225. package/src/okrs.js +0 -268
  226. package/src/organization.js +0 -172
  227. package/src/process.js +0 -240
  228. package/src/product.js +0 -144
  229. package/src/queries.js +0 -414
  230. package/src/roles.js +0 -254
  231. package/src/service.js +0 -139
  232. package/src/types.js +0 -4
  233. package/src/vision.js +0 -67
  234. package/src/workflow.js +0 -246
  235. 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
- }