@actuarial-ts/core 0.8.1 → 0.10.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/README.md CHANGED
@@ -6,13 +6,13 @@ The package is designed to support the actuary's compliance with the ASOPs; it d
6
6
 
7
7
  SDK 0.8 adds versioned loss history, irregular period and exposure contracts,
8
8
  population statistics, shared financial terms, and deterministic recipe and
9
- scenario execution. See the [0.8 adoption guide](https://github.com/yerromnitsuj/actng/blob/v0.8.1/docs/migrations/0.8-reusable-customization.md)
10
- and [customization reference](https://github.com/yerromnitsuj/actng/blob/v0.8.1/docs/reference/reusable-customization.md).
9
+ scenario execution. See the [0.8 adoption guide](https://github.com/yerromnitsuj/actng/blob/v0.10.0/docs/migrations/0.8-reusable-customization.md)
10
+ and [customization reference](https://github.com/yerromnitsuj/actng/blob/v0.10.0/docs/reference/reusable-customization.md).
11
11
 
12
12
  ## Install
13
13
 
14
14
  ```bash
15
- npm install @actuarial-ts/core@0.8.1
15
+ npm install @actuarial-ts/core@0.10.0
16
16
  ```
17
17
 
18
18
  ESM, TypeScript-first, zero runtime dependencies, Node 20+.
@@ -114,8 +114,8 @@ ordinary preparation. These functions do not issue review or execution receipts.
114
114
 
115
115
  These are lower-level calculation APIs. For a host import or analysis boundary
116
116
  that enforces both review and metric execution policy, use the validated gateway
117
- in `@actuarial-ts/data`. The runnable [compact adoption guide](https://github.com/yerromnitsuj/actng/blob/v0.8.1/docs/migrations/0.7-compact-diagnostics.md)
118
- covers the complete workflow and [streamed replay](https://github.com/yerromnitsuj/actng/blob/v0.8.1/docs/reference/diagnostic-replay-stream.md).
117
+ in `@actuarial-ts/data`. The runnable [compact adoption guide](https://github.com/yerromnitsuj/actng/blob/v0.10.0/docs/migrations/0.7-compact-diagnostics.md)
118
+ covers the complete workflow and [streamed replay](https://github.com/yerromnitsuj/actng/blob/v0.10.0/docs/reference/diagnostic-replay-stream.md).
119
119
 
120
120
  The six built-in formulas are basis-independent. The factory creates ten count instances plus six per amount basis (`10 + 6 × basisCount`): one basis produces 16, two produce 22. A `$250K`, primary, gross, net, or ceded calculation is represented by caller-declared amount measures and a structured `AmountBasisDefinition`; it does not need a separate capped formula. Claim-level caps use `claim-layer` derivations before aggregation. Pre-limited external values record their source/transformation instead of implying the SDK recreated an unavailable claim-level operation.
121
121
 
@@ -132,7 +132,7 @@ numeric exposure values. This is a bounded capacity, not an unlimited scale clai
132
132
 
133
133
  Compilation validates the whole graph atomically: IDs, sources, role types, compatibility groups, development semantics, derivation acyclicity, expression limits, rule operands, basis/population references, and period coordinates. Authentic compiled/prepared objects are owner-branded and frozen. Formula, calculation, definition, preparation, and result identities are deterministic FNV-1a/JCS integrity aids—not cryptographic signatures.
134
134
 
135
- See the generated [formula and instance catalog](https://github.com/yerromnitsuj/actng/blob/v0.8.1/docs/reference/diagnostic-formulas.md) and [0.6 migration guide](https://github.com/yerromnitsuj/actng/blob/v0.8.1/docs/migrations/0.6-generalized-diagnostics.md).
135
+ See the generated [formula and instance catalog](https://github.com/yerromnitsuj/actng/blob/v0.10.0/docs/reference/diagnostic-formulas.md) and [0.6 migration guide](https://github.com/yerromnitsuj/actng/blob/v0.10.0/docs/migrations/0.6-generalized-diagnostics.md).
136
136
 
137
137
  ## Main method families
138
138
 
@@ -145,3 +145,13 @@ Published-value tests are the numerical contract. A reserving math change is not
145
145
  ## License
146
146
 
147
147
  Apache-2.0. See LICENSE and NOTICE.
148
+
149
+ SDK 0.9 adds native post-aggregation formulas and correct financial currency units.
150
+ See the [0.9 migration guide](https://github.com/yerromnitsuj/actng/blob/v0.10.0/docs/migrations/0.9-analysis-expressions.md).
151
+
152
+ ## Composite history sources
153
+
154
+ SDK 0.10 adds multiple original artifacts within one claim namespace, explicit
155
+ composite identity selectors and complete input-artifact membership checks.
156
+ Upgrade the five SDK packages together and preserve the producing runtime
157
+ with archived evidence. See the [0.10 migration guide](https://github.com/yerromnitsuj/actng/blob/v0.10.0/docs/migrations/0.10-composite-history.md).
@@ -0,0 +1,24 @@
1
+ import type { AnalysisDefinition, AnalysisDerivedMeasureDefinition, AnalysisResultValue, CustomizationCapabilityFinding } from "./customizationContracts.js";
2
+ type Factors = Readonly<Record<string, number>>;
3
+ export type CompiledAnalysisExpression = {
4
+ readonly definition: AnalysisDerivedMeasureDefinition;
5
+ readonly unit: string;
6
+ readonly unitFactors: Factors;
7
+ readonly dependencies: readonly string[];
8
+ };
9
+ export declare function formatAnalysisUnit(factors: Factors): string;
10
+ /** Validates a bounded dependency graph and resolves dimensions without evaluating any values. */
11
+ export declare function compileAnalysisExpressions(definition: AnalysisDefinition): readonly CompiledAnalysisExpression[];
12
+ /** Resolves requested outputs and their transitive statistic dependencies. */
13
+ export declare function analysisExpressionDependencies(compiled: readonly CompiledAnalysisExpression[], requested: ReadonlySet<string>): ReadonlySet<string>;
14
+ /** Executes post-aggregation expressions on one exact origin/evaluation coordinate. */
15
+ export declare function evaluateAnalysisExpressions(input: {
16
+ readonly definition: AnalysisDefinition;
17
+ readonly values: readonly AnalysisResultValue[];
18
+ readonly coordinates: AnalysisResultValue["coordinates"];
19
+ readonly exposures: ReadonlyMap<string, number>;
20
+ readonly exposureFindings: ReadonlyMap<string, readonly CustomizationCapabilityFinding[]>;
21
+ readonly requested: ReadonlySet<string>;
22
+ }): readonly AnalysisResultValue[];
23
+ export {};
24
+ //# sourceMappingURL=analysisExpressions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analysisExpressions.d.ts","sourceRoot":"","sources":["../src/analysisExpressions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAAE,gCAAgC,EACpD,mBAAmB,EAA4B,8BAA8B,EAC9E,MAAM,6BAA6B,CAAC;AAKrC,KAAK,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAChD,MAAM,MAAM,0BAA0B,GAAG;IAAE,QAAQ,CAAC,UAAU,EAAE,gCAAgC,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC;AAoBnM,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAS3D;AAED,kGAAkG;AAClG,wBAAgB,0BAA0B,CAAC,UAAU,EAAE,kBAAkB,GAAG,SAAS,0BAA0B,EAAE,CAkFhH;AAED,8EAA8E;AAC9E,wBAAgB,8BAA8B,CAAC,QAAQ,EAAE,SAAS,0BAA0B,EAAE,EAAE,SAAS,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,WAAW,CAAC,MAAM,CAAC,CAUnJ;AAED,uFAAuF;AACvF,wBAAgB,2BAA2B,CAAC,KAAK,EAAE;IACjD,QAAQ,CAAC,UAAU,EAAE,kBAAkB,CAAC;IACxC,QAAQ,CAAC,MAAM,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAChD,QAAQ,CAAC,WAAW,EAAE,mBAAmB,CAAC,aAAa,CAAC,CAAC;IACzD,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChD,QAAQ,CAAC,gBAAgB,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,8BAA8B,EAAE,CAAC,CAAC;IAC1F,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CACzC,GAAG,SAAS,mBAAmB,EAAE,CA4EjC"}
@@ -0,0 +1,256 @@
1
+ import { canonicalJson } from "./canonical.js";
2
+ import { isDiagnosticPlainRecord, isDiagnosticToken, snapshotDiagnosticJson } from "./diagnosticRuntime.js";
3
+ import { DiagnosticValidationError } from "./types.js";
4
+ const invalid = (message, path = "$.definition.derivedMeasures", code = "invalid-configuration") => {
5
+ throw new DiagnosticValidationError([{ domain: "definition", code, path, message }]);
6
+ };
7
+ function normalizedFactors(raw) {
8
+ if (!isDiagnosticPlainRecord(raw) || Object.keys(raw).length > 32)
9
+ return invalid("Unit factors require a bounded record of integer powers");
10
+ const result = [];
11
+ for (const [unit, power] of Object.entries(raw)) {
12
+ if (!isDiagnosticToken(unit) || typeof power !== "number" || !Number.isSafeInteger(power) || Math.abs(power) > 32)
13
+ return invalid("Unit factors require valid unit names and integer powers between -32 and 32");
14
+ if (power !== 0)
15
+ result.push([unit, power]);
16
+ }
17
+ return Object.fromEntries(result.sort(([a], [b]) => a.localeCompare(b)));
18
+ }
19
+ function combine(left, right, direction) {
20
+ const result = new Map(Object.entries(left));
21
+ for (const [unit, power] of Object.entries(right))
22
+ result.set(unit, (result.get(unit) ?? 0) + direction * power);
23
+ return normalizedFactors(Object.fromEntries(result));
24
+ }
25
+ export function formatAnalysisUnit(factors) {
26
+ const normalized = normalizedFactors(factors);
27
+ const part = (sign) => Object.entries(normalized).filter(([, power]) => power * sign > 0).map(([unit, power]) => {
28
+ const atom = /[*/^()[\]{}]/.test(unit) ? `[${unit}]` : unit;
29
+ return Math.abs(power) === 1 ? atom : `${atom}^${Math.abs(power)}`;
30
+ }).join("*");
31
+ const numerator = part(1) || "1";
32
+ const denominator = part(-1);
33
+ return denominator ? `${numerator}/${denominator.includes("*") ? `(${denominator})` : denominator}` : numerator;
34
+ }
35
+ /** Validates a bounded dependency graph and resolves dimensions without evaluating any values. */
36
+ export function compileAnalysisExpressions(definition) {
37
+ const derived = definition.derivedMeasures ?? [];
38
+ if (derived.length > 64)
39
+ return invalid("At most 64 derived measures are supported", undefined, "expression-limit");
40
+ const base = new Map(definition.measures.map((m) => [m.id, m]));
41
+ const declarations = new Map(derived.map((m) => [m.id, m]));
42
+ if (base.size !== definition.measures.length || declarations.size !== derived.length || derived.some((m) => !isDiagnosticToken(m.id) || base.has(m.id)))
43
+ return invalid("Base and derived measure IDs must be distinct valid tokens");
44
+ const compiled = new Map();
45
+ const visiting = new Set();
46
+ let totalNodes = 0;
47
+ const resolve = (id) => {
48
+ const raw = base.get(id);
49
+ if (raw)
50
+ return normalizedFactors(raw.unitFactors ?? { [raw.unit]: 1 });
51
+ const prior = compiled.get(id);
52
+ if (prior)
53
+ return prior.unitFactors;
54
+ const measure = declarations.get(id);
55
+ if (!measure)
56
+ return invalid(`Unknown measure ${id}`, undefined, "unknown-reference");
57
+ if (visiting.has(id))
58
+ return invalid(`Derived measure cycle at ${id}`, undefined, "cycle");
59
+ visiting.add(id);
60
+ const dependencies = new Set();
61
+ const walk = (raw, depth, ancestors) => {
62
+ if (++totalNodes > 1024 || depth > 16)
63
+ return invalid("Derived expressions exceed 1024 total nodes or 16 nested levels", undefined, "expression-limit");
64
+ if (!isDiagnosticPlainRecord(raw))
65
+ return invalid("Expression nodes must be objects");
66
+ if (ancestors.has(raw))
67
+ return invalid("Expression contains an object cycle", undefined, "cycle");
68
+ const next = new Set(ancestors).add(raw);
69
+ const keys = { measure: ["op", "measureId"], exposure: ["op", "exposureId"], constant: ["op", "value", "unitFactors"], add: ["op", "terms"], subtract: ["op", "left", "right"], multiply: ["op", "left", "right"], divide: ["op", "numerator", "denominator"] };
70
+ const allowed = typeof raw.op === "string" && Object.hasOwn(keys, raw.op) ? keys[raw.op] : undefined;
71
+ if (!allowed || Object.keys(raw).some((key) => !allowed.includes(key)))
72
+ return invalid("Unknown expression operator or field");
73
+ if (raw.op === "measure") {
74
+ if (!isDiagnosticToken(raw.measureId))
75
+ return invalid("Invalid measure reference");
76
+ dependencies.add(raw.measureId);
77
+ return resolve(raw.measureId);
78
+ }
79
+ if (raw.op === "exposure") {
80
+ const exposure = definition.exposures.find((item) => item.id === raw.exposureId);
81
+ if (!exposure)
82
+ return invalid(`Unknown exposure ${String(raw.exposureId)}`, undefined, "unknown-reference");
83
+ return normalizedFactors({ [exposure.unit]: 1 });
84
+ }
85
+ if (raw.op === "constant") {
86
+ if (typeof raw.value !== "number" || !Number.isFinite(raw.value))
87
+ return invalid("Constants must be finite numbers");
88
+ return normalizedFactors(raw.unitFactors);
89
+ }
90
+ if (raw.op === "add") {
91
+ if (!Array.isArray(raw.terms) || raw.terms.length < 1 || raw.terms.length > 32)
92
+ return invalid("Addition requires 1 to 32 terms");
93
+ const terms = raw.terms.map((term) => walk(term, depth + 1, next));
94
+ if (terms.some((term) => canonicalJson(term) !== canonicalJson(terms[0])))
95
+ return invalid("Addition requires matching units", undefined, "incompatible-semantics");
96
+ return terms[0];
97
+ }
98
+ const left = walk(raw.op === "divide" ? raw.numerator : raw.left, depth + 1, next);
99
+ const right = walk(raw.op === "divide" ? raw.denominator : raw.right, depth + 1, next);
100
+ if (raw.op === "subtract") {
101
+ if (canonicalJson(left) !== canonicalJson(right))
102
+ return invalid("Subtraction requires matching units", undefined, "incompatible-semantics");
103
+ return left;
104
+ }
105
+ return combine(left, right, raw.op === "divide" ? -1 : 1);
106
+ };
107
+ const unitFactors = walk(measure.expression, 0, new Set());
108
+ if (measure.developmentSemantics !== "point-in-time") {
109
+ const dimensionlessConstant = (expression) => expression.op === "constant" && Object.keys(normalizedFactors(expression.unitFactors)).length === 0;
110
+ const checkStage = (expression) => {
111
+ if (expression.op === "constant")
112
+ return;
113
+ if (expression.op === "measure") {
114
+ const referenced = base.get(expression.measureId) ?? declarations.get(expression.measureId);
115
+ if (referenced.developmentSemantics !== measure.developmentSemantics)
116
+ invalid("Cumulative/incremental expressions require components with matching development meaning", undefined, "incompatible-semantics");
117
+ return;
118
+ }
119
+ if (expression.op === "add") {
120
+ expression.terms.forEach(checkStage);
121
+ return;
122
+ }
123
+ if (expression.op === "subtract") {
124
+ checkStage(expression.left);
125
+ checkStage(expression.right);
126
+ return;
127
+ }
128
+ if (expression.op === "multiply" && dimensionlessConstant(expression.left)) {
129
+ checkStage(expression.right);
130
+ return;
131
+ }
132
+ if (expression.op === "multiply" && dimensionlessConstant(expression.right)) {
133
+ checkStage(expression.left);
134
+ return;
135
+ }
136
+ if (expression.op === "divide" && dimensionlessConstant(expression.denominator)) {
137
+ checkStage(expression.numerator);
138
+ return;
139
+ }
140
+ invalid("Ratios, products and exposure expressions require point-in-time development meaning unless scaling by a dimensionless constant", undefined, "incompatible-semantics");
141
+ };
142
+ checkStage(measure.expression);
143
+ }
144
+ compiled.set(id, { definition: measure, unit: formatAnalysisUnit(unitFactors), unitFactors, dependencies: [...dependencies].sort() });
145
+ visiting.delete(id);
146
+ return unitFactors;
147
+ };
148
+ for (const measure of derived)
149
+ resolve(measure.id);
150
+ return snapshotDiagnosticJson([...compiled.values()]);
151
+ }
152
+ /** Resolves requested outputs and their transitive statistic dependencies. */
153
+ export function analysisExpressionDependencies(compiled, requested) {
154
+ const dependencies = new Set(requested);
155
+ const pending = [...requested];
156
+ while (pending.length) {
157
+ const id = pending.pop();
158
+ for (const dependency of compiled.find((item) => item.definition.id === id)?.dependencies ?? []) {
159
+ if (!dependencies.has(dependency)) {
160
+ dependencies.add(dependency);
161
+ pending.push(dependency);
162
+ }
163
+ }
164
+ }
165
+ return dependencies;
166
+ }
167
+ /** Executes post-aggregation expressions on one exact origin/evaluation coordinate. */
168
+ export function evaluateAnalysisExpressions(input) {
169
+ const compiled = compileAnalysisExpressions(input.definition);
170
+ if (compiled.length === 0)
171
+ return [];
172
+ for (const id of input.requested)
173
+ if (!input.definition.measures.some((measure) => measure.id === id) && !compiled.some((item) => item.definition.id === id))
174
+ return invalid(`Unknown requested measure ${id}`, undefined, "unknown-reference");
175
+ const required = analysisExpressionDependencies(compiled, input.requested);
176
+ for (const value of input.values) {
177
+ if (canonicalJson(value.coordinates) !== canonicalJson(input.coordinates))
178
+ return invalid("Expression components must share the exact origin/evaluation coordinate", undefined, "incompatible-semantics");
179
+ const measure = input.definition.measures.find((m) => m.id === value.measureId);
180
+ if (!measure || value.unit !== measure.unit || (value.value !== null && !Number.isFinite(value.value)))
181
+ return invalid("Expression components must match declared base measures, units and finite values", undefined, "incompatible-semantics");
182
+ }
183
+ if (new Set(input.values.map((value) => value.measureId)).size !== input.values.length)
184
+ return invalid("Expression components contain duplicate measure results");
185
+ const values = new Map(input.values.map((value) => [value.measureId, value]));
186
+ const output = [];
187
+ for (const item of compiled) {
188
+ if (!required.has(item.definition.id))
189
+ continue;
190
+ const components = new Map();
191
+ const findings = [];
192
+ const unavailable = (message) => {
193
+ findings.push({ code: "missing-prerequisite", capability: "derived-analysis-measures", path: `$.derivedMeasures.${item.definition.id}`, message });
194
+ return null;
195
+ };
196
+ let numerator = null;
197
+ let denominator = null;
198
+ const evaluate = (expression, root = false) => {
199
+ if (expression.op === "constant")
200
+ return expression.value;
201
+ if (expression.op === "measure") {
202
+ const value = values.get(expression.measureId);
203
+ if (value) {
204
+ components.set(`measure:${expression.measureId}`, { kind: "measure", id: expression.measureId, unit: value.unit, value: value.value, status: value.status, contributingObservations: value.contributingObservations, excludedObservations: value.excludedObservations });
205
+ findings.push(...value.findings);
206
+ }
207
+ else {
208
+ const unit = input.definition.measures.find((m) => m.id === expression.measureId)?.unit ?? compiled.find((m) => m.definition.id === expression.measureId).unit;
209
+ components.set(`measure:${expression.measureId}`, { kind: "measure", id: expression.measureId, unit, value: null, status: "unavailable", contributingObservations: 0, excludedObservations: 0 });
210
+ }
211
+ return !value || value.status !== "available" || value.value === null || value.excludedObservations > 0
212
+ ? unavailable(`Measure ${expression.measureId} requires a complete available result`) : value.value;
213
+ }
214
+ if (expression.op === "exposure") {
215
+ const value = input.exposures.get(expression.exposureId);
216
+ const exposureFindings = input.exposureFindings.get(expression.exposureId) ?? [];
217
+ findings.push(...exposureFindings);
218
+ const available = value !== undefined && Number.isFinite(value) && exposureFindings.length === 0;
219
+ components.set(`exposure:${expression.exposureId}`, { kind: "exposure", id: expression.exposureId, unit: input.definition.exposures.find((e) => e.id === expression.exposureId).unit, value: available ? value : null, status: available ? "available" : "unavailable", contributingObservations: 0, excludedObservations: 0 });
220
+ return available ? value : unavailable(`Exposure ${expression.exposureId} requires an available allocated result`);
221
+ }
222
+ let value;
223
+ if (expression.op === "add") {
224
+ const terms = expression.terms.map((term) => evaluate(term));
225
+ if (terms.some((term) => term === null))
226
+ return null;
227
+ value = terms.reduce((sum, term) => sum + term, 0);
228
+ }
229
+ else {
230
+ const left = evaluate(expression.op === "divide" ? expression.numerator : expression.left);
231
+ const right = evaluate(expression.op === "divide" ? expression.denominator : expression.right);
232
+ if (root && expression.op === "divide") {
233
+ numerator = left;
234
+ denominator = right;
235
+ }
236
+ if (left === null || right === null)
237
+ return null;
238
+ if (expression.op === "divide" && right <= 0)
239
+ return unavailable("Division requires a strictly positive denominator");
240
+ value = expression.op === "subtract" ? left - right : expression.op === "multiply" ? left * right : left / right;
241
+ }
242
+ return Number.isFinite(value) ? value : unavailable("Expression arithmetic overflowed; no finite result is available");
243
+ };
244
+ const value = evaluate(item.definition.expression, true);
245
+ const result = {
246
+ measureId: item.definition.id, unit: item.unit, coordinates: input.coordinates, value,
247
+ status: value === null ? "unavailable" : "available", contributingObservations: 0, excludedObservations: 0, exact: true,
248
+ numerator, denominator, findings: [...new Map(findings.map((finding) => [canonicalJson(finding), finding])).values()],
249
+ derivation: { stage: "post-aggregation", unitFactors: item.unitFactors, components: [...components.values()] },
250
+ };
251
+ values.set(result.measureId, result);
252
+ output.push(result);
253
+ }
254
+ return snapshotDiagnosticJson(output);
255
+ }
256
+ //# sourceMappingURL=analysisExpressions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analysisExpressions.js","sourceRoot":"","sources":["../src/analysisExpressions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { AnalysisDefinition, AnalysisRecipe } from "./customizationContracts.js";
2
+ /** Resolves the declared output units of an ordered financial pipeline before calculating results. */
3
+ export declare function resolveAnalysisFinancialUnits(definition: AnalysisDefinition, recipe: AnalysisRecipe): AnalysisDefinition;
4
+ //# sourceMappingURL=analysisFinancialUnits.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analysisFinancialUnits.d.ts","sourceRoot":"","sources":["../src/analysisFinancialUnits.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAQtF,sGAAsG;AACtG,wBAAgB,6BAA6B,CAAC,UAAU,EAAE,kBAAkB,EAAE,MAAM,EAAE,cAAc,GAAG,kBAAkB,CA6CxH"}
@@ -0,0 +1,62 @@
1
+ import { formatAnalysisUnit } from "./analysisExpressions.js";
2
+ import { DiagnosticValidationError } from "./types.js";
3
+ const incompatible = (message) => {
4
+ throw new DiagnosticValidationError([{ domain: "configuration", code: "incompatible-semantics", path: "$.recipe.steps", message }]);
5
+ };
6
+ /** Resolves the declared output units of an ordered financial pipeline before calculating results. */
7
+ export function resolveAnalysisFinancialUnits(definition, recipe) {
8
+ const step = recipe.steps.find((item) => item.kind === "apply-financial-pipeline");
9
+ if (step?.kind !== "apply-financial-pipeline")
10
+ return definition;
11
+ const stages = step.stageIds.map((id) => definition.financialAdjustments?.find((item) => item.id === id));
12
+ if (!stages.some((stage) => stage?.kind === "currency"))
13
+ return definition;
14
+ const rawUnits = new Map();
15
+ for (const measure of definition.measures) {
16
+ if (measure.statistic.kind !== "sum")
17
+ continue;
18
+ const id = measure.statistic.measureId;
19
+ const units = rawUnits.get(id) ?? new Set();
20
+ units.add(measure.unit);
21
+ rawUnits.set(id, units);
22
+ }
23
+ const rawUnit = (id) => {
24
+ const units = rawUnits.get(id);
25
+ if (!units || units.size !== 1)
26
+ return incompatible(`Currency conversion needs one declared sum unit for ${id}`);
27
+ return [...units][0];
28
+ };
29
+ const initialUnit = rawUnit(step.amountMeasureId);
30
+ let outputUnit = initialUnit;
31
+ for (const stage of stages) {
32
+ if (!stage)
33
+ continue;
34
+ if (stage.kind === "currency") {
35
+ if (stage.fromUnit !== outputUnit)
36
+ return incompatible(`Currency stage ${stage.id} expects ${stage.fromUnit}, not ${outputUnit}`);
37
+ outputUnit = stage.toUnit;
38
+ }
39
+ else if (stage.kind === "include-expense" || stage.kind === "exclude-expense" || stage.kind === "net-recovery") {
40
+ const id = stage.kind === "net-recovery" ? stage.recoveryMeasureId : stage.expenseMeasureId;
41
+ if (rawUnit(id) !== outputUnit)
42
+ return incompatible(`Financial component ${id} must use the current pipeline unit ${outputUnit}`);
43
+ }
44
+ }
45
+ const effectiveUnit = (id) => id === step.amountMeasureId ? outputUnit : definition.exposures.find((e) => e.id === id)?.unit ?? rawUnit(id);
46
+ const measures = definition.measures.map((measure) => {
47
+ const statistic = measure.statistic;
48
+ if (statistic.kind === "ratio") {
49
+ if (statistic.numeratorMeasureId !== step.amountMeasureId && statistic.denominatorMeasureId !== step.amountMeasureId)
50
+ return measure;
51
+ const numerator = effectiveUnit(statistic.numeratorMeasureId);
52
+ const denominator = effectiveUnit(statistic.denominatorMeasureId);
53
+ const factors = numerator === denominator ? {} : { [numerator]: 1, [denominator]: -1 };
54
+ return { ...measure, unit: numerator === denominator ? "ratio" : formatAnalysisUnit(factors), unitFactors: factors };
55
+ }
56
+ if ("measureId" in statistic && statistic.measureId === step.amountMeasureId)
57
+ return { ...measure, unit: outputUnit, unitFactors: { [outputUnit]: 1 } };
58
+ return measure;
59
+ });
60
+ return { ...definition, measures };
61
+ }
62
+ //# sourceMappingURL=analysisFinancialUnits.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analysisFinancialUnits.js","sourceRoot":"","sources":["../src/analysisFinancialUnits.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"analysisRecipe.d.ts","sourceRoot":"","sources":["../src/analysisRecipe.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"analysisRecipe.d.ts","sourceRoot":"","sources":["../src/analysisRecipe.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,8 @@ import { canonicalJson, fnv1a64 } from "./canonical.js";
2
2
  import { CORE_PACKAGE_VERSION } from "./version.js";
3
3
  import { calculateAnalysisStatistic } from "./descriptiveStatistics.js";
4
4
  import { calculateRecipeExposureRatio } from "./analysisRecipeStatistics.js";
5
+ import { compileAnalysisExpressions, analysisExpressionDependencies, evaluateAnalysisExpressions } from "./analysisExpressions.js";
6
+ import { resolveAnalysisFinancialUnits } from "./analysisFinancialUnits.js";
5
7
  import { compareAnalysisEvaluations, compareAnalysisResults } from "./analysisComparison.js";
6
8
  export { compareAnalysisResults } from "./analysisComparison.js";
7
9
  import { isDiagnosticToken, snapshotDiagnosticJson } from "./diagnosticRuntime.js";
@@ -49,7 +51,7 @@ function recipeIssues(recipe, definition, history) {
49
51
  hasCalculate = true;
50
52
  if (step.kind === "calculate")
51
53
  step.measureIds.forEach((id) => {
52
- if (!definition.measures.some((measure) => measure.id === id))
54
+ if (![...definition.measures, ...(definition.derivedMeasures ?? [])].some((measure) => measure.id === id))
53
55
  issues.push({ domain: "configuration", code: "unknown-reference", path: `$.recipe.steps[${index}].measureIds`, message: `Unknown measure ${id}` });
54
56
  });
55
57
  if (step.kind === "earn-exposure")
@@ -127,6 +129,8 @@ export function runAnalysisRecipe(input) {
127
129
  const issues = recipeIssues(input.recipe, input.definition, input.history);
128
130
  if (issues.length > 0)
129
131
  throw new DiagnosticValidationError(issues);
132
+ const outputDefinition = resolveAnalysisFinancialUnits(input.definition, input.recipe);
133
+ const expressions = compileAnalysisExpressions(outputDefinition);
130
134
  const prepared = prepareHistoricalDataset(input.history);
131
135
  const evaluationDate = input.evaluationDate ?? maxEvaluationDate(prepared.observations);
132
136
  const selected = selectedAt(prepared.observations, evaluationDate, input.definition.period.observationSelection);
@@ -246,14 +250,16 @@ export function runAnalysisRecipe(input) {
246
250
  else
247
251
  group.observations.push(observation);
248
252
  }
249
- const measureIds = new Set(input.recipe.steps.filter((step) => step.kind === "calculate").flatMap((step) => step.measureIds));
253
+ const requestedMeasureIds = new Set(input.recipe.steps.filter((step) => step.kind === "calculate").flatMap((step) => step.measureIds));
254
+ const measureIds = analysisExpressionDependencies(expressions, requestedMeasureIds);
250
255
  // When preparation excluded every observation, retain visible unavailable
251
256
  // output instead of hiding the preparation findings in an empty result.
252
257
  if (groups.size === 0 && prepared.findings.length > 0)
253
258
  groups.set("unassigned", { label: "Unavailable history", observations: [] });
254
259
  const values = [];
255
260
  for (const [originId, group] of [...groups].sort(([left], [right]) => left.localeCompare(right))) {
256
- for (const measure of input.definition.measures.filter((candidate) => measureIds.has(candidate.id))) {
261
+ const start = values.length;
262
+ for (const measure of outputDefinition.measures.filter((candidate) => measureIds.has(candidate.id))) {
257
263
  let measureObservations = measure.populationScopeId === input.definition.scopes.financial.id
258
264
  ? group.observations
259
265
  : group.observations.filter((observation) => reportingKeys.has(key(observation)));
@@ -323,9 +329,18 @@ export function runAnalysisRecipe(input) {
323
329
  findings: statistic.findings,
324
330
  });
325
331
  }
332
+ values.push(...evaluateAnalysisExpressions({
333
+ definition: outputDefinition,
334
+ values: values.slice(start),
335
+ coordinates: { originId, originLabel: group.label, evaluationDate },
336
+ exposures: exposedByTarget.get(originId) ?? new Map(),
337
+ exposureFindings: exposureFindingsByMeasure,
338
+ requested: requestedMeasureIds,
339
+ }));
326
340
  }
327
341
  if (originFailures.length > 0) {
328
- for (const measure of input.definition.measures.filter((candidate) => measureIds.has(candidate.id))) {
342
+ const start = values.length;
343
+ for (const measure of outputDefinition.measures.filter((candidate) => measureIds.has(candidate.id))) {
329
344
  const originFindings = originFailures
330
345
  .filter(({ observation }) => measure.populationScopeId === input.definition.scopes.financial.id || reportingKeys.has(key(observation)))
331
346
  .map(({ finding }) => finding);
@@ -345,6 +360,12 @@ export function runAnalysisRecipe(input) {
345
360
  findings: originFindings,
346
361
  });
347
362
  }
363
+ values.push(...evaluateAnalysisExpressions({
364
+ definition: outputDefinition,
365
+ values: values.slice(start),
366
+ coordinates: { originId: "unassigned", originLabel: "Unavailable origin", evaluationDate },
367
+ exposures: new Map(), exposureFindings: exposureFindingsByMeasure, requested: requestedMeasureIds,
368
+ }));
348
369
  }
349
370
  const calculationInput = {
350
371
  corePackageVersion: CORE_PACKAGE_VERSION,