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.
- package/.turbo/turbo-build.log +4 -5
- package/CHANGELOG.md +53 -0
- package/README.md +2 -0
- package/dist/dollar.d.ts.map +1 -1
- package/dist/dollar.js +2 -2
- package/dist/dollar.js.map +1 -1
- package/dist/entities/organization.d.ts +4 -0
- package/dist/entities/organization.d.ts.map +1 -1
- package/dist/entities/organization.js +27 -18
- package/dist/entities/organization.js.map +1 -1
- package/dist/entities/planning.d.ts +87 -0
- package/dist/finance/account.d.ts +44 -0
- package/dist/finance/account.d.ts.map +1 -0
- package/dist/finance/account.js +6 -0
- package/dist/finance/account.js.map +1 -0
- package/dist/finance/authority.d.ts +78 -0
- package/dist/finance/authority.d.ts.map +1 -0
- package/dist/finance/authority.js +27 -0
- package/dist/finance/authority.js.map +1 -0
- package/dist/finance/card.d.ts +36 -0
- package/dist/finance/card.d.ts.map +1 -0
- package/dist/finance/card.js +6 -0
- package/dist/finance/card.js.map +1 -0
- package/dist/finance/identity.d.ts +30 -0
- package/dist/finance/identity.d.ts.map +1 -0
- package/dist/finance/identity.js +8 -0
- package/dist/finance/identity.js.map +1 -0
- package/dist/finance/index.d.ts +36 -0
- package/dist/finance/index.d.ts.map +1 -0
- package/dist/finance/index.js +22 -0
- package/dist/finance/index.js.map +1 -0
- package/dist/finance/ledger.d.ts +24 -0
- package/dist/finance/ledger.d.ts.map +1 -0
- package/dist/finance/ledger.js +8 -0
- package/dist/finance/ledger.js.map +1 -0
- package/dist/finance/merchant.d.ts +129 -0
- package/dist/finance/merchant.d.ts.map +1 -0
- package/dist/finance/merchant.js +21 -0
- package/dist/finance/merchant.js.map +1 -0
- package/dist/finance/outcome-contract.d.ts +139 -0
- package/dist/finance/outcome-contract.d.ts.map +1 -0
- package/dist/finance/outcome-contract.js +27 -0
- package/dist/finance/outcome-contract.js.map +1 -0
- package/dist/finance/port.d.ts +121 -0
- package/dist/finance/port.d.ts.map +1 -0
- package/dist/finance/port.js +10 -0
- package/dist/finance/port.js.map +1 -0
- package/dist/finance/pricing.d.ts +154 -0
- package/dist/finance/pricing.d.ts.map +1 -0
- package/dist/finance/pricing.js +79 -0
- package/dist/finance/pricing.js.map +1 -0
- package/dist/finance/proof-predicate.d.ts +92 -0
- package/dist/finance/proof-predicate.d.ts.map +1 -0
- package/dist/finance/proof-predicate.js +80 -0
- package/dist/finance/proof-predicate.js.map +1 -0
- package/dist/finance/refund.d.ts +44 -0
- package/dist/finance/refund.d.ts.map +1 -0
- package/dist/finance/refund.js +41 -0
- package/dist/finance/refund.js.map +1 -0
- package/dist/finance/sla.d.ts +25 -0
- package/dist/finance/sla.d.ts.map +1 -0
- package/dist/finance/sla.js +7 -0
- package/dist/finance/sla.js.map +1 -0
- package/dist/finance/types.d.ts +79 -0
- package/dist/finance/types.d.ts.map +1 -0
- package/dist/finance/types.js +8 -0
- package/dist/{canvas → finance}/types.js.map +1 -1
- package/dist/goals.d.ts +19 -0
- package/dist/goals.d.ts.map +1 -1
- package/dist/goals.js +81 -12
- package/dist/goals.js.map +1 -1
- package/dist/index.d.ts +12 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -7
- package/dist/index.js.map +1 -1
- package/dist/kpis.d.ts +19 -0
- package/dist/kpis.d.ts.map +1 -1
- package/dist/kpis.js +71 -6
- package/dist/kpis.js.map +1 -1
- package/dist/metrics.d.ts.map +1 -1
- package/dist/metrics.js +29 -24
- package/dist/metrics.js.map +1 -1
- package/dist/okrs.d.ts +34 -0
- package/dist/okrs.d.ts.map +1 -1
- package/dist/okrs.js +135 -13
- package/dist/okrs.js.map +1 -1
- package/dist/organization.d.ts.map +1 -1
- package/dist/organization.js +11 -11
- package/dist/organization.js.map +1 -1
- package/dist/process.d.ts.map +1 -1
- package/dist/process.js +13 -12
- package/dist/process.js.map +1 -1
- package/dist/product.d.ts.map +1 -1
- package/dist/product.js +9 -9
- package/dist/product.js.map +1 -1
- package/dist/queries.d.ts.map +1 -1
- package/dist/queries.js +194 -32
- package/dist/queries.js.map +1 -1
- package/dist/roles.d.ts +25 -31
- package/dist/roles.d.ts.map +1 -1
- package/dist/roles.js +37 -10
- package/dist/roles.js.map +1 -1
- package/dist/workflow.d.ts.map +1 -1
- package/dist/workflow.js +13 -12
- package/dist/workflow.js.map +1 -1
- package/package.json +20 -13
- package/src/dollar.ts +5 -2
- package/src/entities/organization.ts +31 -18
- package/src/finance/account.ts +48 -0
- package/src/finance/authority.ts +42 -0
- package/src/finance/card.ts +38 -0
- package/src/finance/identity.ts +31 -0
- package/src/finance/index.ts +117 -0
- package/src/finance/ledger.ts +26 -0
- package/src/finance/merchant.ts +127 -0
- package/src/finance/outcome-contract.ts +157 -0
- package/src/finance/port.ts +144 -0
- package/src/finance/pricing.ts +197 -0
- package/src/finance/proof-predicate.ts +106 -0
- package/src/finance/refund.ts +52 -0
- package/src/finance/sla.ts +33 -0
- package/src/finance/types.ts +75 -0
- package/src/goals.ts +78 -12
- package/src/index.ts +48 -18
- package/src/kpis.ts +62 -8
- package/src/metrics.ts +92 -79
- package/src/okrs.ts +120 -20
- package/src/organization.ts +12 -15
- package/src/process.ts +11 -12
- package/src/product.ts +8 -9
- package/src/queries.ts +238 -75
- package/src/roles.ts +62 -61
- package/src/workflow.ts +22 -15
- package/test/business.test.ts +282 -0
- package/test/dollar.test.ts +270 -0
- package/test/entities.test.ts +628 -0
- package/test/financials.test.ts +539 -0
- package/test/goals.test.ts +451 -0
- package/{src → test}/index.test.ts +1 -1
- package/test/kpis.test.ts +440 -0
- package/test/metrics.test.ts +744 -0
- package/test/okrs.test.ts +741 -0
- package/test/organization.test.ts +548 -0
- package/test/process.test.ts +503 -0
- package/test/product.test.ts +430 -0
- package/test/queries.test.ts +556 -0
- package/test/roles.test.ts +546 -0
- package/test/service.test.ts +450 -0
- package/test/types.test.ts +1141 -0
- package/test/vision.test.ts +214 -0
- package/test/workflow.test.ts +501 -0
- package/vitest.config.ts +47 -0
- package/LICENSE +0 -21
- package/dist/canvas/activities.d.ts +0 -19
- package/dist/canvas/activities.d.ts.map +0 -1
- package/dist/canvas/activities.js +0 -20
- package/dist/canvas/activities.js.map +0 -1
- package/dist/canvas/channels.d.ts +0 -20
- package/dist/canvas/channels.d.ts.map +0 -1
- package/dist/canvas/channels.js +0 -21
- package/dist/canvas/channels.js.map +0 -1
- package/dist/canvas/relationships.d.ts +0 -20
- package/dist/canvas/relationships.d.ts.map +0 -1
- package/dist/canvas/relationships.js +0 -21
- package/dist/canvas/relationships.js.map +0 -1
- package/dist/canvas/resources.d.ts +0 -20
- package/dist/canvas/resources.d.ts.map +0 -1
- package/dist/canvas/resources.js +0 -30
- package/dist/canvas/resources.js.map +0 -1
- package/dist/canvas/revenue.d.ts +0 -22
- package/dist/canvas/revenue.d.ts.map +0 -1
- package/dist/canvas/revenue.js +0 -30
- package/dist/canvas/revenue.js.map +0 -1
- package/dist/canvas/segments.d.ts +0 -20
- package/dist/canvas/segments.d.ts.map +0 -1
- package/dist/canvas/segments.js +0 -28
- package/dist/canvas/segments.js.map +0 -1
- package/dist/canvas/types.d.ts +0 -232
- package/dist/canvas/types.d.ts.map +0 -1
- package/dist/canvas/types.js +0 -8
- package/dist/canvas/value.d.ts +0 -20
- package/dist/canvas/value.d.ts.map +0 -1
- package/dist/canvas/value.js +0 -21
- package/dist/canvas/value.js.map +0 -1
- package/src/business.js +0 -108
- package/src/canvas/activities.ts +0 -32
- package/src/canvas/canvas.ts +0 -482
- package/src/canvas/channels.ts +0 -34
- package/src/canvas/costs.ts +0 -43
- package/src/canvas/economics.ts +0 -99
- package/src/canvas/index.ts +0 -206
- package/src/canvas/partnerships.ts +0 -34
- package/src/canvas/projections.ts +0 -141
- package/src/canvas/relationships.ts +0 -34
- package/src/canvas/resources.ts +0 -43
- package/src/canvas/revenue.ts +0 -56
- package/src/canvas/segments.ts +0 -42
- package/src/canvas/types.ts +0 -363
- package/src/canvas/value.ts +0 -34
- package/src/dollar.js +0 -106
- package/src/entities/assets.js +0 -322
- package/src/entities/business.js +0 -369
- package/src/entities/communication.js +0 -254
- package/src/entities/customers.js +0 -988
- package/src/entities/financials.js +0 -931
- package/src/entities/goals.js +0 -799
- package/src/entities/index.js +0 -197
- package/src/entities/legal.js +0 -300
- package/src/entities/market.js +0 -300
- package/src/entities/marketing.js +0 -1156
- package/src/entities/offerings.js +0 -726
- package/src/entities/operations.js +0 -786
- package/src/entities/organization.js +0 -806
- package/src/entities/partnerships.js +0 -299
- package/src/entities/planning.js +0 -270
- package/src/entities/projects.js +0 -348
- package/src/entities/risk.js +0 -292
- package/src/entities/sales.js +0 -1247
- package/src/financials.js +0 -296
- package/src/goals.js +0 -214
- package/src/index.js +0 -131
- package/src/index.test.js +0 -274
- package/src/kpis.js +0 -231
- package/src/metrics.js +0 -324
- package/src/okrs.js +0 -268
- package/src/organization.js +0 -172
- package/src/process.js +0 -240
- package/src/product.js +0 -144
- package/src/queries.js +0 -414
- package/src/roles.js +0 -254
- package/src/service.js +0 -139
- package/src/types.js +0 -4
- package/src/vision.js +0 -67
- package/src/workflow.js +0 -246
- package/tests/canvas.test.ts +0 -842
package/src/okrs.ts
CHANGED
|
@@ -1,8 +1,106 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Objectives and Key Results (OKRs) management
|
|
3
|
+
*
|
|
4
|
+
* Uses org.ai OKR types for standardized OKR definitions across the ecosystem.
|
|
3
5
|
*/
|
|
4
6
|
|
|
5
7
|
import type { OKRDefinition, KeyResult } from './types.js'
|
|
8
|
+
import type { OKR as OrgOKR, KeyResult as OrgKeyResult, OKRStatus, KeyResultStatus } from 'org.ai'
|
|
9
|
+
|
|
10
|
+
// Re-export org.ai OKR types for convenience
|
|
11
|
+
export type { OrgOKR, OrgKeyResult, OKRStatus, KeyResultStatus }
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Convert a business-as-code KeyResult to an org.ai KeyResult
|
|
15
|
+
*
|
|
16
|
+
* @param kr - Business key result
|
|
17
|
+
* @param id - Optional identifier
|
|
18
|
+
* @returns org.ai KeyResult object
|
|
19
|
+
*/
|
|
20
|
+
export function toOrgKeyResult(kr: KeyResult, id?: string): OrgKeyResult {
|
|
21
|
+
const result: OrgKeyResult = {
|
|
22
|
+
description: kr.description,
|
|
23
|
+
}
|
|
24
|
+
if (id !== undefined) result.id = id
|
|
25
|
+
if (kr.description) result.name = kr.description
|
|
26
|
+
if (kr.metric !== undefined) result.metric = kr.metric
|
|
27
|
+
if (kr.startValue !== undefined) result.startValue = kr.startValue
|
|
28
|
+
if (kr.targetValue !== undefined) {
|
|
29
|
+
result.targetValue = kr.targetValue
|
|
30
|
+
result.target = kr.targetValue
|
|
31
|
+
}
|
|
32
|
+
if (kr.currentValue !== undefined) {
|
|
33
|
+
result.currentValue = kr.currentValue
|
|
34
|
+
result.current = kr.currentValue
|
|
35
|
+
}
|
|
36
|
+
if (kr.unit !== undefined) result.unit = kr.unit
|
|
37
|
+
if (kr.progress !== undefined) result.progress = kr.progress
|
|
38
|
+
return result
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Convert an org.ai KeyResult to a business-as-code KeyResult
|
|
43
|
+
*
|
|
44
|
+
* @param kr - org.ai KeyResult object
|
|
45
|
+
* @returns Business key result
|
|
46
|
+
*/
|
|
47
|
+
export function fromOrgKeyResult(kr: OrgKeyResult): KeyResult {
|
|
48
|
+
const result: KeyResult = {
|
|
49
|
+
description: kr.description || kr.name || '',
|
|
50
|
+
metric: kr.metric || '',
|
|
51
|
+
targetValue: kr.targetValue ?? kr.target ?? 0,
|
|
52
|
+
}
|
|
53
|
+
if (kr.startValue !== undefined) result.startValue = kr.startValue
|
|
54
|
+
if (kr.currentValue !== undefined) result.currentValue = kr.currentValue
|
|
55
|
+
else if (kr.current !== undefined) result.currentValue = kr.current
|
|
56
|
+
if (kr.unit !== undefined) result.unit = kr.unit
|
|
57
|
+
if (kr.progress !== undefined) result.progress = kr.progress
|
|
58
|
+
return result
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Convert a business-as-code OKRDefinition to an org.ai OKR
|
|
63
|
+
*
|
|
64
|
+
* @param definition - Business OKR definition
|
|
65
|
+
* @param id - Optional unique identifier
|
|
66
|
+
* @returns org.ai OKR object
|
|
67
|
+
*/
|
|
68
|
+
export function toOrgOKR(definition: OKRDefinition, id?: string): OrgOKR {
|
|
69
|
+
const result: OrgOKR = {
|
|
70
|
+
objective: definition.objective,
|
|
71
|
+
keyResults: definition.keyResults?.map((kr, i) => toOrgKeyResult(kr, `${id}_kr_${i}`)) || [],
|
|
72
|
+
}
|
|
73
|
+
if (id !== undefined) result.id = id
|
|
74
|
+
if (definition.description !== undefined) result.description = definition.description
|
|
75
|
+
if (definition.owner !== undefined) result.owner = definition.owner
|
|
76
|
+
if (definition.period !== undefined) result.period = definition.period
|
|
77
|
+
if (definition.status !== undefined) result.status = definition.status as OKRStatus
|
|
78
|
+
result.progress = calculateOKRProgress(definition)
|
|
79
|
+
if (definition.confidence !== undefined) result.confidence = definition.confidence
|
|
80
|
+
if (definition.metadata !== undefined) result.metadata = definition.metadata
|
|
81
|
+
return result
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Convert an org.ai OKR to a business-as-code OKRDefinition
|
|
86
|
+
*
|
|
87
|
+
* @param okr - org.ai OKR object
|
|
88
|
+
* @returns Business OKR definition
|
|
89
|
+
*/
|
|
90
|
+
export function fromOrgOKR(okr: OrgOKR): OKRDefinition {
|
|
91
|
+
const result: OKRDefinition = {
|
|
92
|
+
objective: okr.objective,
|
|
93
|
+
keyResults: okr.keyResults.map(fromOrgKeyResult),
|
|
94
|
+
}
|
|
95
|
+
if (okr.description !== undefined) result.description = okr.description
|
|
96
|
+
if (okr.owner !== undefined) result.owner = okr.owner
|
|
97
|
+
if (okr.period !== undefined) result.period = okr.period
|
|
98
|
+
const st = okr.status
|
|
99
|
+
if (st !== undefined) result.status = st as NonNullable<OKRDefinition['status']>
|
|
100
|
+
if (okr.confidence !== undefined) result.confidence = okr.confidence
|
|
101
|
+
if (okr.metadata !== undefined) result.metadata = okr.metadata
|
|
102
|
+
return result
|
|
103
|
+
}
|
|
6
104
|
|
|
7
105
|
/**
|
|
8
106
|
* Define Objectives and Key Results for goal tracking
|
|
@@ -51,7 +149,7 @@ import type { OKRDefinition, KeyResult } from './types.js'
|
|
|
51
149
|
* ```
|
|
52
150
|
*/
|
|
53
151
|
export function okrs(definitions: OKRDefinition[]): OKRDefinition[] {
|
|
54
|
-
return definitions.map(okr => validateAndNormalizeOKR(okr))
|
|
152
|
+
return definitions.map((okr) => validateAndNormalizeOKR(okr))
|
|
55
153
|
}
|
|
56
154
|
|
|
57
155
|
/**
|
|
@@ -70,18 +168,19 @@ function validateAndNormalizeOKR(okr: OKRDefinition): OKRDefinition {
|
|
|
70
168
|
}
|
|
71
169
|
|
|
72
170
|
// Calculate progress for key results if not set
|
|
73
|
-
const keyResults = okr.keyResults?.map(kr => ({
|
|
171
|
+
const keyResults = okr.keyResults?.map((kr) => ({
|
|
74
172
|
...kr,
|
|
75
173
|
progress: kr.progress ?? calculateKeyResultProgress(kr),
|
|
76
174
|
}))
|
|
77
175
|
|
|
78
|
-
|
|
176
|
+
const result: OKRDefinition = {
|
|
79
177
|
...okr,
|
|
80
|
-
keyResults,
|
|
81
178
|
status: okr.status || 'not-started',
|
|
82
179
|
confidence: okr.confidence ?? calculateConfidence(keyResults || []),
|
|
83
180
|
metadata: okr.metadata || {},
|
|
84
181
|
}
|
|
182
|
+
if (keyResults !== undefined) result.keyResults = keyResults
|
|
183
|
+
return result
|
|
85
184
|
}
|
|
86
185
|
|
|
87
186
|
/**
|
|
@@ -136,7 +235,7 @@ export function updateKeyResult(
|
|
|
136
235
|
krDescription: string,
|
|
137
236
|
currentValue: number
|
|
138
237
|
): OKRDefinition {
|
|
139
|
-
const keyResults = okr.keyResults?.map(kr => {
|
|
238
|
+
const keyResults = okr.keyResults?.map((kr) => {
|
|
140
239
|
if (kr.description === krDescription) {
|
|
141
240
|
const updatedKR = { ...kr, currentValue }
|
|
142
241
|
return {
|
|
@@ -148,24 +247,24 @@ export function updateKeyResult(
|
|
|
148
247
|
})
|
|
149
248
|
|
|
150
249
|
// Recalculate overall status and confidence
|
|
151
|
-
const
|
|
250
|
+
const okrWithKeyResults: OKRDefinition = { ...okr }
|
|
251
|
+
if (keyResults !== undefined) okrWithKeyResults.keyResults = keyResults
|
|
252
|
+
const progress = calculateOKRProgress(okrWithKeyResults)
|
|
152
253
|
const status = determineOKRStatus(progress, okr.confidence || 0)
|
|
153
254
|
|
|
154
|
-
|
|
255
|
+
const result: OKRDefinition = {
|
|
155
256
|
...okr,
|
|
156
|
-
keyResults,
|
|
157
|
-
status,
|
|
158
257
|
confidence: calculateConfidence(keyResults || []),
|
|
159
258
|
}
|
|
259
|
+
if (keyResults !== undefined) result.keyResults = keyResults
|
|
260
|
+
if (status !== undefined) result.status = status
|
|
261
|
+
return result
|
|
160
262
|
}
|
|
161
263
|
|
|
162
264
|
/**
|
|
163
265
|
* Determine OKR status based on progress and confidence
|
|
164
266
|
*/
|
|
165
|
-
function determineOKRStatus(
|
|
166
|
-
progress: number,
|
|
167
|
-
confidence: number
|
|
168
|
-
): OKRDefinition['status'] {
|
|
267
|
+
function determineOKRStatus(progress: number, confidence: number): OKRDefinition['status'] {
|
|
169
268
|
if (progress === 0) return 'not-started'
|
|
170
269
|
if (progress === 100) return 'completed'
|
|
171
270
|
if (confidence < 50 || progress < 30) return 'at-risk'
|
|
@@ -199,21 +298,21 @@ export function getKeyResultsOnTrack(okr: OKRDefinition): KeyResult[] {
|
|
|
199
298
|
* Get key results that are at risk
|
|
200
299
|
*/
|
|
201
300
|
export function getKeyResultsAtRisk(okr: OKRDefinition): KeyResult[] {
|
|
202
|
-
return okr.keyResults?.filter(kr => !isKeyResultOnTrack(kr)) || []
|
|
301
|
+
return okr.keyResults?.filter((kr) => !isKeyResultOnTrack(kr)) || []
|
|
203
302
|
}
|
|
204
303
|
|
|
205
304
|
/**
|
|
206
305
|
* Get OKRs by owner
|
|
207
306
|
*/
|
|
208
307
|
export function getOKRsByOwner(okrs: OKRDefinition[], owner: string): OKRDefinition[] {
|
|
209
|
-
return okrs.filter(okr => okr.owner === owner)
|
|
308
|
+
return okrs.filter((okr) => okr.owner === owner)
|
|
210
309
|
}
|
|
211
310
|
|
|
212
311
|
/**
|
|
213
312
|
* Get OKRs by period
|
|
214
313
|
*/
|
|
215
314
|
export function getOKRsByPeriod(okrs: OKRDefinition[], period: string): OKRDefinition[] {
|
|
216
|
-
return okrs.filter(okr => okr.period === period)
|
|
315
|
+
return okrs.filter((okr) => okr.period === period)
|
|
217
316
|
}
|
|
218
317
|
|
|
219
318
|
/**
|
|
@@ -223,7 +322,7 @@ export function getOKRsByStatus(
|
|
|
223
322
|
okrs: OKRDefinition[],
|
|
224
323
|
status: OKRDefinition['status']
|
|
225
324
|
): OKRDefinition[] {
|
|
226
|
-
return okrs.filter(okr => okr.status === status)
|
|
325
|
+
return okrs.filter((okr) => okr.status === status)
|
|
227
326
|
}
|
|
228
327
|
|
|
229
328
|
/**
|
|
@@ -232,9 +331,10 @@ export function getOKRsByStatus(
|
|
|
232
331
|
export function calculateSuccessRate(okrs: OKRDefinition[]): number {
|
|
233
332
|
if (okrs.length === 0) return 0
|
|
234
333
|
|
|
235
|
-
const avgProgress =
|
|
236
|
-
|
|
237
|
-
|
|
334
|
+
const avgProgress =
|
|
335
|
+
okrs.reduce((sum, okr) => {
|
|
336
|
+
return sum + calculateOKRProgress(okr)
|
|
337
|
+
}, 0) / okrs.length
|
|
238
338
|
|
|
239
339
|
return avgProgress
|
|
240
340
|
}
|
package/src/organization.ts
CHANGED
|
@@ -741,7 +741,7 @@ export function resolvePermissions(
|
|
|
741
741
|
// Search through hierarchy
|
|
742
742
|
for (const dept of org.departments || []) {
|
|
743
743
|
for (const t of dept.teams || []) {
|
|
744
|
-
const pos = t.positions?.find(p => p.id === positionId)
|
|
744
|
+
const pos = t.positions?.find((p) => p.id === positionId)
|
|
745
745
|
if (pos) {
|
|
746
746
|
position = pos
|
|
747
747
|
team = t
|
|
@@ -755,7 +755,7 @@ export function resolvePermissions(
|
|
|
755
755
|
// Also check standalone teams
|
|
756
756
|
if (!position) {
|
|
757
757
|
for (const t of org.teams || []) {
|
|
758
|
-
const pos = t.positions?.find(p => p.id === positionId)
|
|
758
|
+
const pos = t.positions?.find((p) => p.id === positionId)
|
|
759
759
|
if (pos) {
|
|
760
760
|
position = pos
|
|
761
761
|
team = t
|
|
@@ -767,7 +767,7 @@ export function resolvePermissions(
|
|
|
767
767
|
if (!position) return null
|
|
768
768
|
|
|
769
769
|
// Find the role
|
|
770
|
-
const role = org.roles?.find(r => r
|
|
770
|
+
const role = org.roles?.find((r) => r['id'] === position.roleId)
|
|
771
771
|
|
|
772
772
|
// Build inheritance chain
|
|
773
773
|
const inheritanceChain: string[] = []
|
|
@@ -803,16 +803,16 @@ export function resolvePermissions(
|
|
|
803
803
|
|
|
804
804
|
// 4. Role permissions
|
|
805
805
|
if (role?.permissions) {
|
|
806
|
-
inheritanceChain.push(`role:${role
|
|
806
|
+
inheritanceChain.push(`role:${role['id']}`)
|
|
807
807
|
mergePermissions(permissions, role.permissions)
|
|
808
808
|
}
|
|
809
809
|
|
|
810
810
|
// 5. Role capabilities
|
|
811
|
-
if (role?.canApprove) {
|
|
812
|
-
canApprove.push(...role
|
|
811
|
+
if (role?.['canApprove']) {
|
|
812
|
+
canApprove.push(...role['canApprove'])
|
|
813
813
|
}
|
|
814
|
-
if (role?.canHandle) {
|
|
815
|
-
canHandle.push(...role
|
|
814
|
+
if (role?.['canHandle']) {
|
|
815
|
+
canHandle.push(...role['canHandle'])
|
|
816
816
|
}
|
|
817
817
|
|
|
818
818
|
// 6. Position-specific permissions
|
|
@@ -867,7 +867,7 @@ export function getApprovalChainForRequest(
|
|
|
867
867
|
requestType: string,
|
|
868
868
|
amount?: number
|
|
869
869
|
): ApproverSpec[] {
|
|
870
|
-
const chain = org.approvalChains?.find(c => c.type === requestType && c.active !== false)
|
|
870
|
+
const chain = org.approvalChains?.find((c) => c.type === requestType && c.active !== false)
|
|
871
871
|
if (!chain) return []
|
|
872
872
|
|
|
873
873
|
// Find the appropriate level based on amount
|
|
@@ -886,19 +886,16 @@ export function getApprovalChainForRequest(
|
|
|
886
886
|
/**
|
|
887
887
|
* Find manager for a position (follows reportsTo chain)
|
|
888
888
|
*/
|
|
889
|
-
export function findManager(
|
|
890
|
-
org: Organization,
|
|
891
|
-
positionId: string
|
|
892
|
-
): Position | null {
|
|
889
|
+
export function findManager(org: Organization, positionId: string): Position | null {
|
|
893
890
|
// Find the position
|
|
894
891
|
for (const dept of org.departments || []) {
|
|
895
892
|
for (const team of dept.teams || []) {
|
|
896
|
-
const position = team.positions?.find(p => p.id === positionId)
|
|
893
|
+
const position = team.positions?.find((p) => p.id === positionId)
|
|
897
894
|
if (position?.reportsTo) {
|
|
898
895
|
// Find the manager position
|
|
899
896
|
for (const d of org.departments || []) {
|
|
900
897
|
for (const t of d.teams || []) {
|
|
901
|
-
const manager = t.positions?.find(p => p.id === position.reportsTo)
|
|
898
|
+
const manager = t.positions?.find((p) => p.id === position.reportsTo)
|
|
902
899
|
if (manager) return manager
|
|
903
900
|
}
|
|
904
901
|
}
|
package/src/process.ts
CHANGED
|
@@ -89,7 +89,7 @@ export function getStepsByAutomationLevel(
|
|
|
89
89
|
process: ProcessDefinition,
|
|
90
90
|
level: ProcessStep['automationLevel']
|
|
91
91
|
): ProcessStep[] {
|
|
92
|
-
return process.steps?.filter(step => step.automationLevel === level) || []
|
|
92
|
+
return process.steps?.filter((step) => step.automationLevel === level) || []
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
/**
|
|
@@ -160,7 +160,7 @@ export function calculateAutomationPercentage(process: ProcessDefinition): numbe
|
|
|
160
160
|
if (!process.steps || process.steps.length === 0) return 0
|
|
161
161
|
|
|
162
162
|
const automatedSteps = process.steps.filter(
|
|
163
|
-
step => step.automationLevel === 'automated' || step.automationLevel === 'semi-automated'
|
|
163
|
+
(step) => step.automationLevel === 'automated' || step.automationLevel === 'semi-automated'
|
|
164
164
|
).length
|
|
165
165
|
|
|
166
166
|
return (automatedSteps / process.steps.length) * 100
|
|
@@ -170,7 +170,7 @@ export function calculateAutomationPercentage(process: ProcessDefinition): numbe
|
|
|
170
170
|
* Get metric by name
|
|
171
171
|
*/
|
|
172
172
|
export function getMetric(process: ProcessDefinition, name: string): ProcessMetric | undefined {
|
|
173
|
-
return process.metrics?.find(m => m.name === name)
|
|
173
|
+
return process.metrics?.find((m) => m.name === name)
|
|
174
174
|
}
|
|
175
175
|
|
|
176
176
|
/**
|
|
@@ -198,14 +198,13 @@ export function updateMetric(
|
|
|
198
198
|
metricName: string,
|
|
199
199
|
currentValue: number
|
|
200
200
|
): ProcessDefinition {
|
|
201
|
-
const metrics = process.metrics?.map(m =>
|
|
201
|
+
const metrics = process.metrics?.map((m) =>
|
|
202
202
|
m.name === metricName ? { ...m, current: currentValue } : m
|
|
203
203
|
)
|
|
204
204
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
}
|
|
205
|
+
const result: ProcessDefinition = { ...process }
|
|
206
|
+
if (metrics !== undefined) result.metrics = metrics
|
|
207
|
+
return result
|
|
209
208
|
}
|
|
210
209
|
|
|
211
210
|
/**
|
|
@@ -222,10 +221,10 @@ export function addStep(process: ProcessDefinition, step: ProcessStep): ProcessD
|
|
|
222
221
|
* Remove step from process
|
|
223
222
|
*/
|
|
224
223
|
export function removeStep(process: ProcessDefinition, stepOrder: number): ProcessDefinition {
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
224
|
+
const steps = process.steps?.filter((s) => s.order !== stepOrder)
|
|
225
|
+
const result: ProcessDefinition = { ...process }
|
|
226
|
+
if (steps !== undefined) result.steps = steps
|
|
227
|
+
return result
|
|
229
228
|
}
|
|
230
229
|
|
|
231
230
|
/**
|
package/src/product.ts
CHANGED
|
@@ -82,7 +82,7 @@ export function getRoadmapByStatus(
|
|
|
82
82
|
product: ProductDefinition,
|
|
83
83
|
status: RoadmapItem['status']
|
|
84
84
|
): RoadmapItem[] {
|
|
85
|
-
return product.roadmap?.filter(item => item.status === status) || []
|
|
85
|
+
return product.roadmap?.filter((item) => item.status === status) || []
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
/**
|
|
@@ -92,7 +92,7 @@ export function getRoadmapByPriority(
|
|
|
92
92
|
product: ProductDefinition,
|
|
93
93
|
priority: RoadmapItem['priority']
|
|
94
94
|
): RoadmapItem[] {
|
|
95
|
-
return product.roadmap?.filter(item => item.priority === priority) || []
|
|
95
|
+
return product.roadmap?.filter((item) => item.priority === priority) || []
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
/**
|
|
@@ -102,7 +102,7 @@ export function getOverdueRoadmapItems(product: ProductDefinition): RoadmapItem[
|
|
|
102
102
|
const now = new Date()
|
|
103
103
|
return (
|
|
104
104
|
product.roadmap?.filter(
|
|
105
|
-
item =>
|
|
105
|
+
(item) =>
|
|
106
106
|
item.targetDate &&
|
|
107
107
|
item.targetDate < now &&
|
|
108
108
|
item.status !== 'completed' &&
|
|
@@ -119,14 +119,13 @@ export function updateRoadmapItem(
|
|
|
119
119
|
itemName: string,
|
|
120
120
|
updates: Partial<RoadmapItem>
|
|
121
121
|
): ProductDefinition {
|
|
122
|
-
const roadmap = product.roadmap?.map(item =>
|
|
122
|
+
const roadmap = product.roadmap?.map((item) =>
|
|
123
123
|
item.name === itemName ? { ...item, ...updates } : item
|
|
124
124
|
)
|
|
125
125
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
}
|
|
126
|
+
const result: ProductDefinition = { ...product }
|
|
127
|
+
if (roadmap !== undefined) result.roadmap = roadmap
|
|
128
|
+
return result
|
|
130
129
|
}
|
|
131
130
|
|
|
132
131
|
/**
|
|
@@ -145,7 +144,7 @@ export function addFeature(product: ProductDefinition, feature: string): Product
|
|
|
145
144
|
export function removeFeature(product: ProductDefinition, feature: string): ProductDefinition {
|
|
146
145
|
return {
|
|
147
146
|
...product,
|
|
148
|
-
features: product.features?.filter(f => f !== feature) || [],
|
|
147
|
+
features: product.features?.filter((f) => f !== feature) || [],
|
|
149
148
|
}
|
|
150
149
|
}
|
|
151
150
|
|