@adaptic/backend-legacy 0.0.83 → 0.0.85
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/esm/plugins/http-status-mapper.d.ts +33 -0
- package/esm/plugins/http-status-mapper.d.ts.map +1 -0
- package/esm/plugins/http-status-mapper.js.map +1 -0
- package/esm/plugins/http-status-mapper.mjs +87 -0
- package/esm/plugins/index.d.ts +1 -0
- package/esm/plugins/index.d.ts.map +1 -1
- package/esm/plugins/index.js.map +1 -1
- package/esm/plugins/index.mjs +1 -0
- package/helpers/deep-merge.cjs +33 -0
- package/helpers/deep-merge.d.ts +15 -0
- package/helpers/deep-merge.d.ts.map +1 -0
- package/helpers/deep-merge.js.map +1 -0
- package/helpers/effective-llm-config.cjs +24 -0
- package/helpers/effective-llm-config.d.ts +28 -0
- package/helpers/effective-llm-config.d.ts.map +1 -0
- package/helpers/effective-llm-config.js.map +1 -0
- package/helpers/effective-policy.cjs +130 -0
- package/helpers/effective-policy.d.ts +70 -0
- package/helpers/effective-policy.d.ts.map +1 -0
- package/helpers/effective-policy.js.map +1 -0
- package/helpers/kms-envelope.cjs +53 -0
- package/helpers/kms-envelope.d.ts +36 -0
- package/helpers/kms-envelope.d.ts.map +1 -0
- package/helpers/kms-envelope.js.map +1 -0
- package/helpers/kms-envelope.kms-adapter.cjs +25 -0
- package/helpers/kms-envelope.kms-adapter.d.ts +14 -0
- package/helpers/kms-envelope.kms-adapter.d.ts.map +1 -0
- package/helpers/kms-envelope.kms-adapter.js.map +1 -0
- package/package.json +3 -1
- package/server.cjs +13 -2
- package/types/llm-configuration.cjs +18 -0
- package/types/llm-configuration.d.ts +42 -0
- package/types/llm-configuration.d.ts.map +1 -0
- package/types/llm-configuration.js.map +1 -0
- package/types/policy-overlay.cjs +3 -0
- package/types/policy-overlay.d.ts +40 -0
- package/types/policy-overlay.d.ts.map +1 -0
- package/types/policy-overlay.js.map +1 -0
- package/types/trading-policy.cjs +70 -0
- package/types/trading-policy.d.ts +119 -0
- package/types/trading-policy.d.ts.map +1 -0
- package/types/trading-policy.js.map +1 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP Status Mapper Plugin for Apollo Server 5.
|
|
3
|
+
*
|
|
4
|
+
* Maps well-known GraphQL error codes to their semantically-correct HTTP
|
|
5
|
+
* status codes. Apollo Server 5 defaults to HTTP 500 for any error thrown
|
|
6
|
+
* inside the `context` function (wrapped as ContextFunctionError) and to
|
|
7
|
+
* HTTP 200 for errors thrown inside resolvers — neither default is correct
|
|
8
|
+
* for an authentication failure, and the 500 default actively harms
|
|
9
|
+
* consumers: Apollo Client's observable pipeline crashes on a 5xx response
|
|
10
|
+
* with a GraphQL-shaped body (`Cannot read properties of undefined (reading
|
|
11
|
+
* 'write')`), so the awaited `client.query(...)` Promise neither resolves
|
|
12
|
+
* nor rejects. Downstream `try/catch` blocks never run, and any UI that
|
|
13
|
+
* gates rendering on a `setIsLoading(false)` in `finally` is locked into a
|
|
14
|
+
* permanent loading state.
|
|
15
|
+
*
|
|
16
|
+
* This plugin runs in `willSendResponse` and inspects every GraphQL error in
|
|
17
|
+
* the final response body. If any error carries `extensions.code` in the
|
|
18
|
+
* lookup table below, the response's HTTP status is upgraded accordingly.
|
|
19
|
+
* Doing it here (rather than at each throw site) means we get the same
|
|
20
|
+
* mapping whether the error originated in a context function, a resolver,
|
|
21
|
+
* an `AuthChecker`, or a directive — and a future code path that throws
|
|
22
|
+
* UNAUTHENTICATED cannot accidentally regress to a 500.
|
|
23
|
+
*
|
|
24
|
+
* Mapping policy:
|
|
25
|
+
* UNAUTHENTICATED → 401 (most common; the bug above)
|
|
26
|
+
* FORBIDDEN → 403 (AuthChecker rejections per CORTEX-P0-001)
|
|
27
|
+
* BAD_USER_INPUT → 400 (GraphQL validation already handles syntax; this
|
|
28
|
+
* covers semantic input rejection from validators)
|
|
29
|
+
* Anything else → unchanged (200 for in-body errors, 500 for fatal)
|
|
30
|
+
*/
|
|
31
|
+
import type { ApolloServerPlugin } from '@apollo/server';
|
|
32
|
+
export declare function createHttpStatusMapperPlugin<TContext extends object = object>(): ApolloServerPlugin<TContext>;
|
|
33
|
+
//# sourceMappingURL=http-status-mapper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-status-mapper.d.ts","sourceRoot":"","sources":["../../../src/plugins/http-status-mapper.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,KAAK,EACV,kBAAkB,EAGnB,MAAM,gBAAgB,CAAC;AAgCxB,wBAAgB,4BAA4B,CAC1C,QAAQ,SAAS,MAAM,GAAG,MAAM,KAC7B,kBAAkB,CAAC,QAAQ,CAAC,CA2BhC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-status-mapper.js","sourceRoot":"","sources":["../../../src/plugins/http-status-mapper.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AASH,MAAM,mBAAmB,GAA2B;IAClD,eAAe,EAAE,GAAG;IACpB,SAAS,EAAE,GAAG;IACd,cAAc,EAAE,GAAG;CACpB,CAAC;AAEF;;;;;GAKG;AACH,SAAS,gBAAgB,CACvB,MAAwC;IAExC,IAAI,IAAwB,CAAC;IAC7B,MAAM,QAAQ,GAA2B,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;IACpE,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC;QAClC,IAAI,OAAO,IAAI,KAAK,QAAQ;YAAE,SAAS;QACvC,MAAM,MAAM,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;QACzC,IAAI,CAAC,MAAM;YAAE,SAAS;QACtB,IAAI,IAAI,KAAK,SAAS,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;YAC1E,IAAI,GAAG,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,4BAA4B;IAG1C,OAAO;QACL,KAAK,CAAC,eAAe;YACnB,OAAO;gBACL,KAAK,CAAC,gBAAgB,CACpB,cAA+D;oBAE/D,MAAM,EAAE,QAAQ,EAAE,GAAG,cAAc,CAAC;oBACpC,MAAM,EAAE,IAAI,EAAE,GAAG,QAAQ,CAAC;oBAC1B,kEAAkE;oBAClE,iEAAiE;oBACjE,4DAA4D;oBAC5D,8DAA8D;oBAC9D,UAAU;oBACV,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ;wBAAE,OAAO;oBACnC,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC;oBACxC,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;wBAAE,OAAO;oBAC3C,MAAM,MAAM,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;oBACxC,IAAI,MAAM,KAAK,SAAS;wBAAE,OAAO;oBACjC,4DAA4D;oBAC5D,+DAA+D;oBAC/D,qEAAqE;oBACrE,QAAQ,CAAC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;gBAChC,CAAC;aACF,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP Status Mapper Plugin for Apollo Server 5.
|
|
3
|
+
*
|
|
4
|
+
* Maps well-known GraphQL error codes to their semantically-correct HTTP
|
|
5
|
+
* status codes. Apollo Server 5 defaults to HTTP 500 for any error thrown
|
|
6
|
+
* inside the `context` function (wrapped as ContextFunctionError) and to
|
|
7
|
+
* HTTP 200 for errors thrown inside resolvers — neither default is correct
|
|
8
|
+
* for an authentication failure, and the 500 default actively harms
|
|
9
|
+
* consumers: Apollo Client's observable pipeline crashes on a 5xx response
|
|
10
|
+
* with a GraphQL-shaped body (`Cannot read properties of undefined (reading
|
|
11
|
+
* 'write')`), so the awaited `client.query(...)` Promise neither resolves
|
|
12
|
+
* nor rejects. Downstream `try/catch` blocks never run, and any UI that
|
|
13
|
+
* gates rendering on a `setIsLoading(false)` in `finally` is locked into a
|
|
14
|
+
* permanent loading state.
|
|
15
|
+
*
|
|
16
|
+
* This plugin runs in `willSendResponse` and inspects every GraphQL error in
|
|
17
|
+
* the final response body. If any error carries `extensions.code` in the
|
|
18
|
+
* lookup table below, the response's HTTP status is upgraded accordingly.
|
|
19
|
+
* Doing it here (rather than at each throw site) means we get the same
|
|
20
|
+
* mapping whether the error originated in a context function, a resolver,
|
|
21
|
+
* an `AuthChecker`, or a directive — and a future code path that throws
|
|
22
|
+
* UNAUTHENTICATED cannot accidentally regress to a 500.
|
|
23
|
+
*
|
|
24
|
+
* Mapping policy:
|
|
25
|
+
* UNAUTHENTICATED → 401 (most common; the bug above)
|
|
26
|
+
* FORBIDDEN → 403 (AuthChecker rejections per CORTEX-P0-001)
|
|
27
|
+
* BAD_USER_INPUT → 400 (GraphQL validation already handles syntax; this
|
|
28
|
+
* covers semantic input rejection from validators)
|
|
29
|
+
* Anything else → unchanged (200 for in-body errors, 500 for fatal)
|
|
30
|
+
*/
|
|
31
|
+
const CODE_TO_HTTP_STATUS = {
|
|
32
|
+
UNAUTHENTICATED: 401,
|
|
33
|
+
FORBIDDEN: 403,
|
|
34
|
+
BAD_USER_INPUT: 400,
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Returns the highest-priority HTTP status implied by the GraphQL errors in
|
|
38
|
+
* the response, or undefined if no mapping applies. Priority order: 401 over
|
|
39
|
+
* 403 over 400 — auth failures trump everything else because they're the
|
|
40
|
+
* primary signal a client needs to refresh its token / reauthenticate.
|
|
41
|
+
*/
|
|
42
|
+
function deriveHttpStatus(errors) {
|
|
43
|
+
let best;
|
|
44
|
+
const priority = { 401: 3, 403: 2, 400: 1 };
|
|
45
|
+
for (const err of errors) {
|
|
46
|
+
const code = err.extensions?.code;
|
|
47
|
+
if (typeof code !== 'string')
|
|
48
|
+
continue;
|
|
49
|
+
const status = CODE_TO_HTTP_STATUS[code];
|
|
50
|
+
if (!status)
|
|
51
|
+
continue;
|
|
52
|
+
if (best === undefined || (priority[status] ?? 0) > (priority[best] ?? 0)) {
|
|
53
|
+
best = status;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return best;
|
|
57
|
+
}
|
|
58
|
+
export function createHttpStatusMapperPlugin() {
|
|
59
|
+
return {
|
|
60
|
+
async requestDidStart() {
|
|
61
|
+
return {
|
|
62
|
+
async willSendResponse(requestContext) {
|
|
63
|
+
const { response } = requestContext;
|
|
64
|
+
const { body } = response;
|
|
65
|
+
// Only the `single` response kind carries a single `errors` array
|
|
66
|
+
// we can inspect synchronously. Incremental delivery (`@defer` /
|
|
67
|
+
// `@stream`) uses `incremental` and would require per-chunk
|
|
68
|
+
// mapping; we don't use those features yet, so this is a safe
|
|
69
|
+
// narrow.
|
|
70
|
+
if (body.kind !== 'single')
|
|
71
|
+
return;
|
|
72
|
+
const errors = body.singleResult.errors;
|
|
73
|
+
if (!errors || errors.length === 0)
|
|
74
|
+
return;
|
|
75
|
+
const status = deriveHttpStatus(errors);
|
|
76
|
+
if (status === undefined)
|
|
77
|
+
return;
|
|
78
|
+
// Apollo Server only sets `http.status` for fatal errors by
|
|
79
|
+
// default; assigning here overrides that. The `http` object is
|
|
80
|
+
// always present on the response when reached via expressMiddleware.
|
|
81
|
+
response.http.status = status;
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=http-status-mapper.js.map
|
package/esm/plugins/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACtE,OAAO,EAAE,4BAA4B,EAAE,MAAM,sBAAsB,CAAC"}
|
package/esm/plugins/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/plugins/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/plugins/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACtE,OAAO,EAAE,4BAA4B,EAAE,MAAM,sBAAsB,CAAC"}
|
package/esm/plugins/index.mjs
CHANGED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.deepMerge = void 0;
|
|
4
|
+
const isPlainObject = (v) => v !== null && typeof v === 'object' && !Array.isArray(v);
|
|
5
|
+
/**
|
|
6
|
+
* Pure, non-mutating deep merge.
|
|
7
|
+
* - Plain objects merge recursively.
|
|
8
|
+
* - Arrays and scalars: right side replaces.
|
|
9
|
+
* - `undefined` on the right is treated as absent (left value retained).
|
|
10
|
+
* - `null` on the right overrides to null.
|
|
11
|
+
*
|
|
12
|
+
* Used by effectivePolicy() and effectiveLlmConfig() to deep-merge
|
|
13
|
+
* Organization → Fund → BrokerageAccount policy layers per charter §2.2.
|
|
14
|
+
* Consumers must use this helper; do not re-implement merge semantics.
|
|
15
|
+
*/
|
|
16
|
+
const deepMerge = (left, right) => {
|
|
17
|
+
const out = { ...left };
|
|
18
|
+
for (const key of Object.keys(right)) {
|
|
19
|
+
const rv = right[key];
|
|
20
|
+
if (rv === undefined)
|
|
21
|
+
continue;
|
|
22
|
+
const lv = out[key];
|
|
23
|
+
if (isPlainObject(lv) && isPlainObject(rv)) {
|
|
24
|
+
out[key] = (0, exports.deepMerge)(lv, rv);
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
out[key] = rv;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return out;
|
|
31
|
+
};
|
|
32
|
+
exports.deepMerge = deepMerge;
|
|
33
|
+
//# sourceMappingURL=deep-merge.js.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
type Plain = Record<string, unknown>;
|
|
2
|
+
/**
|
|
3
|
+
* Pure, non-mutating deep merge.
|
|
4
|
+
* - Plain objects merge recursively.
|
|
5
|
+
* - Arrays and scalars: right side replaces.
|
|
6
|
+
* - `undefined` on the right is treated as absent (left value retained).
|
|
7
|
+
* - `null` on the right overrides to null.
|
|
8
|
+
*
|
|
9
|
+
* Used by effectivePolicy() and effectiveLlmConfig() to deep-merge
|
|
10
|
+
* Organization → Fund → BrokerageAccount policy layers per charter §2.2.
|
|
11
|
+
* Consumers must use this helper; do not re-implement merge semantics.
|
|
12
|
+
*/
|
|
13
|
+
export declare const deepMerge: <T extends Plain, U extends Plain>(left: T, right: U) => T & U;
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=deep-merge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deep-merge.d.ts","sourceRoot":"","sources":["../../src/helpers/deep-merge.ts"],"names":[],"mappings":"AAAA,KAAK,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAKrC;;;;;;;;;;GAUG;AACH,eAAO,MAAM,SAAS,GAAI,CAAC,SAAS,KAAK,EAAE,CAAC,SAAS,KAAK,EACxD,MAAM,CAAC,EACP,OAAO,CAAC,KACP,CAAC,GAAG,CAaN,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deep-merge.js","sourceRoot":"","sources":["../../src/helpers/deep-merge.ts"],"names":[],"mappings":";;;AAEA,MAAM,aAAa,GAAG,CAAC,CAAU,EAAc,EAAE,CAC/C,CAAC,KAAK,IAAI,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAE3D;;;;;;;;;;GAUG;AACI,MAAM,SAAS,GAAG,CACvB,IAAO,EACP,KAAQ,EACD,EAAE;IACT,MAAM,GAAG,GAAU,EAAE,GAAG,IAAI,EAAE,CAAC;IAC/B,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACrC,MAAM,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;QACtB,IAAI,EAAE,KAAK,SAAS;YAAE,SAAS;QAC/B,MAAM,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QACpB,IAAI,aAAa,CAAC,EAAE,CAAC,IAAI,aAAa,CAAC,EAAE,CAAC,EAAE,CAAC;YAC3C,GAAG,CAAC,GAAG,CAAC,GAAG,IAAA,iBAAS,EAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QAC/B,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;QAChB,CAAC;IACH,CAAC;IACD,OAAO,GAAY,CAAC;AACtB,CAAC,CAAC;AAhBW,QAAA,SAAS,aAgBpB"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.effectiveLlmConfig = effectiveLlmConfig;
|
|
4
|
+
const deep_merge_1 = require("./deep-merge.cjs");
|
|
5
|
+
const llm_configuration_1 = require("../types/llm-configuration.cjs");
|
|
6
|
+
/**
|
|
7
|
+
* Deep-merges DEFAULT_LLM_CONFIGURATION → Org.llmDefaults →
|
|
8
|
+
* Fund.llmOverrides into a single frozen `LlmConfigurationJson`.
|
|
9
|
+
*
|
|
10
|
+
* `apiKeys.<provider>` values are EncryptedApiKey envelopes; this
|
|
11
|
+
* helper does NOT decrypt. Use `decryptApiKey()` from
|
|
12
|
+
* `helpers/kms-envelope` with appropriate role gating per spec §4.3.
|
|
13
|
+
*/
|
|
14
|
+
function effectiveLlmConfig(fund) {
|
|
15
|
+
let cfg = { ...llm_configuration_1.DEFAULT_LLM_CONFIGURATION };
|
|
16
|
+
if (fund.organization.llmDefaults) {
|
|
17
|
+
cfg = (0, deep_merge_1.deepMerge)(cfg, fund.organization.llmDefaults);
|
|
18
|
+
}
|
|
19
|
+
if (fund.llmOverrides) {
|
|
20
|
+
cfg = (0, deep_merge_1.deepMerge)(cfg, fund.llmOverrides);
|
|
21
|
+
}
|
|
22
|
+
return Object.freeze(cfg);
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=effective-llm-config.js.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type LlmConfigurationJson } from '../types/llm-configuration';
|
|
2
|
+
/**
|
|
3
|
+
* The relation shape `effectiveLlmConfig()` requires.
|
|
4
|
+
*
|
|
5
|
+
* Note: there is no overlay tier (LLM config is not event-driven).
|
|
6
|
+
* Precedence is a two-level chain.
|
|
7
|
+
*/
|
|
8
|
+
interface FundWithLlmContext {
|
|
9
|
+
id: string;
|
|
10
|
+
llmOverrides: LlmConfigurationJson | null;
|
|
11
|
+
organization: {
|
|
12
|
+
id: string;
|
|
13
|
+
llmDefaults: LlmConfigurationJson | null;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Deep-merges DEFAULT_LLM_CONFIGURATION → Org.llmDefaults →
|
|
18
|
+
* Fund.llmOverrides into a single frozen `LlmConfigurationJson`.
|
|
19
|
+
*
|
|
20
|
+
* `apiKeys.<provider>` values are EncryptedApiKey envelopes; this
|
|
21
|
+
* helper does NOT decrypt. Use `decryptApiKey()` from
|
|
22
|
+
* `helpers/kms-envelope` with appropriate role gating per spec §4.3.
|
|
23
|
+
*/
|
|
24
|
+
export declare function effectiveLlmConfig(fund: FundWithLlmContext): Required<Omit<LlmConfigurationJson, 'apiKeys'>> & {
|
|
25
|
+
apiKeys: NonNullable<LlmConfigurationJson['apiKeys']>;
|
|
26
|
+
};
|
|
27
|
+
export {};
|
|
28
|
+
//# sourceMappingURL=effective-llm-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"effective-llm-config.d.ts","sourceRoot":"","sources":["../../src/helpers/effective-llm-config.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,4BAA4B,CAAC;AAEpC;;;;;GAKG;AACH,UAAU,kBAAkB;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAC1C,YAAY,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,oBAAoB,GAAG,IAAI,CAAA;KAAE,CAAC;CACxE;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,kBAAkB,GAAG,QAAQ,CACpE,IAAI,CAAC,oBAAoB,EAAE,SAAS,CAAC,CACtC,GAAG;IACF,OAAO,EAAE,WAAW,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAC,CAAC;CACvD,CAeA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"effective-llm-config.js","sourceRoot":"","sources":["../../src/helpers/effective-llm-config.ts"],"names":[],"mappings":";;AA0BA,gDAmBC;AA7CD,6CAAyC;AACzC,kEAGoC;AAcpC;;;;;;;GAOG;AACH,SAAgB,kBAAkB,CAAC,IAAwB;IAKzD,IAAI,GAAG,GAAyB,EAAE,GAAG,6CAAyB,EAAE,CAAC;IACjE,IAAI,IAAI,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC;QAClC,GAAG,GAAG,IAAA,sBAAS,EACb,GAA8B,EAC9B,IAAI,CAAC,YAAY,CAAC,WAAsC,CACjC,CAAC;IAC5B,CAAC;IACD,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;QACtB,GAAG,GAAG,IAAA,sBAAS,EACb,GAA8B,EAC9B,IAAI,CAAC,YAAuC,CACrB,CAAC;IAC5B,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,GAAG,CAA0C,CAAC;AACrE,CAAC"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.brokerageAccountWithPolicyContextSelectionSet = exports.EffectivePolicyContextError = void 0;
|
|
4
|
+
exports.effectivePolicy = effectivePolicy;
|
|
5
|
+
const deep_merge_1 = require("./deep-merge.cjs");
|
|
6
|
+
const trading_policy_1 = require("../types/trading-policy.cjs");
|
|
7
|
+
/**
|
|
8
|
+
* Thrown when a caller invokes effectivePolicy() with a
|
|
9
|
+
* BrokerageAccount whose required relations (`fund.organization`,
|
|
10
|
+
* `fund.policyOverlays`) were not loaded by the selection set. We do
|
|
11
|
+
* not silently fall back to defaults — silent fall-back hides bugs.
|
|
12
|
+
*/
|
|
13
|
+
class EffectivePolicyContextError extends Error {
|
|
14
|
+
constructor(field) {
|
|
15
|
+
super(`effectivePolicy(): missing relation \`${field}\`. ` +
|
|
16
|
+
`Fetch with brokerageAccountWithPolicyContextSelectionSet ` +
|
|
17
|
+
`(see @adaptic/backend-legacy docs).`);
|
|
18
|
+
this.name = 'EffectivePolicyContextError';
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
exports.EffectivePolicyContextError = EffectivePolicyContextError;
|
|
22
|
+
/**
|
|
23
|
+
* The 14 BrokerageAccount column fields preserved per charter §2.2.
|
|
24
|
+
* Read directly from the entity, not from the JSON merge.
|
|
25
|
+
*/
|
|
26
|
+
const BA_COLUMN_FIELDS = [
|
|
27
|
+
'enablePortfolioTrailingStop',
|
|
28
|
+
'portfolioTrailPercent',
|
|
29
|
+
'portfolioProfitThresholdPercent',
|
|
30
|
+
'reducedPortfolioTrailPercent',
|
|
31
|
+
'defaultTrailingStopPercentage100',
|
|
32
|
+
'firstTrailReductionThreshold100',
|
|
33
|
+
'secondTrailReductionThreshold100',
|
|
34
|
+
'firstReducedTrailPercentage100',
|
|
35
|
+
'secondReducedTrailPercentage100',
|
|
36
|
+
'minimumPriceChangePercent100',
|
|
37
|
+
'cryptoTradingEnabled',
|
|
38
|
+
'cryptoTradingPairs',
|
|
39
|
+
'tradeAllocationPct',
|
|
40
|
+
'cryptoTradeAllocationPct',
|
|
41
|
+
];
|
|
42
|
+
const severityRank = {
|
|
43
|
+
LOW: 0,
|
|
44
|
+
MEDIUM: 1,
|
|
45
|
+
HIGH: 2,
|
|
46
|
+
CRITICAL: 3,
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Canonical selection-set string for `adaptic.brokerageAccount.get(id, …)`.
|
|
50
|
+
* Loads fund + fund.organization + fund.policyOverlays in one query.
|
|
51
|
+
*
|
|
52
|
+
* Consumers should pass this verbatim to fetch a BrokerageAccount
|
|
53
|
+
* suitable for effectivePolicy().
|
|
54
|
+
*/
|
|
55
|
+
exports.brokerageAccountWithPolicyContextSelectionSet = `
|
|
56
|
+
id
|
|
57
|
+
enablePortfolioTrailingStop
|
|
58
|
+
portfolioTrailPercent
|
|
59
|
+
portfolioProfitThresholdPercent
|
|
60
|
+
reducedPortfolioTrailPercent
|
|
61
|
+
defaultTrailingStopPercentage100
|
|
62
|
+
firstTrailReductionThreshold100
|
|
63
|
+
secondTrailReductionThreshold100
|
|
64
|
+
firstReducedTrailPercentage100
|
|
65
|
+
secondReducedTrailPercentage100
|
|
66
|
+
minimumPriceChangePercent100
|
|
67
|
+
cryptoTradingEnabled
|
|
68
|
+
cryptoTradingPairs
|
|
69
|
+
tradeAllocationPct
|
|
70
|
+
cryptoTradeAllocationPct
|
|
71
|
+
fund {
|
|
72
|
+
id
|
|
73
|
+
tradingOverrides
|
|
74
|
+
policyOverlays
|
|
75
|
+
organization { id tradingDefaults }
|
|
76
|
+
}
|
|
77
|
+
`;
|
|
78
|
+
/**
|
|
79
|
+
* Deep-merges DEFAULT_TRADING_POLICY → Org.tradingDefaults →
|
|
80
|
+
* Fund.tradingOverrides → active Fund.policyOverlays (severity-sorted)
|
|
81
|
+
* → 14 BrokerageAccount column fields into a single canonical
|
|
82
|
+
* `Required<TradingPolicyJson>` plus the 14 column overrides.
|
|
83
|
+
*
|
|
84
|
+
* Consumers MUST use this helper — do not re-implement the precedence
|
|
85
|
+
* chain. The result is frozen.
|
|
86
|
+
*
|
|
87
|
+
* @throws EffectivePolicyContextError if `fund.organization` or
|
|
88
|
+
* `fund.policyOverlays` is missing (selection-set bug).
|
|
89
|
+
*/
|
|
90
|
+
function effectivePolicy(ba) {
|
|
91
|
+
var _a;
|
|
92
|
+
if (!ba.fund)
|
|
93
|
+
throw new EffectivePolicyContextError('fund');
|
|
94
|
+
if (!ba.fund.organization) {
|
|
95
|
+
throw new EffectivePolicyContextError('fund.organization');
|
|
96
|
+
}
|
|
97
|
+
if (ba.fund.policyOverlays === undefined) {
|
|
98
|
+
throw new EffectivePolicyContextError('fund.policyOverlays');
|
|
99
|
+
}
|
|
100
|
+
// 1) defaults
|
|
101
|
+
let policy = { ...trading_policy_1.DEFAULT_TRADING_POLICY };
|
|
102
|
+
// 2) Org defaults
|
|
103
|
+
if (ba.fund.organization.tradingDefaults) {
|
|
104
|
+
policy = (0, deep_merge_1.deepMerge)(policy, ba.fund.organization.tradingDefaults);
|
|
105
|
+
}
|
|
106
|
+
// 3) Fund overrides
|
|
107
|
+
if (ba.fund.tradingOverrides) {
|
|
108
|
+
policy = (0, deep_merge_1.deepMerge)(policy, ba.fund.tradingOverrides);
|
|
109
|
+
}
|
|
110
|
+
// 4) Active overlays (severity-sorted; CRITICAL last → highest precedence)
|
|
111
|
+
const now = new Date();
|
|
112
|
+
const active = ((_a = ba.fund.policyOverlays) !== null && _a !== void 0 ? _a : [])
|
|
113
|
+
.filter((o) => o.status === 'ACTIVE' &&
|
|
114
|
+
(o.expiresAt == null || new Date(o.expiresAt) > now))
|
|
115
|
+
.sort((a, b) => severityRank[a.severity] - severityRank[b.severity]);
|
|
116
|
+
for (const overlay of active) {
|
|
117
|
+
policy = (0, deep_merge_1.deepMerge)(policy, overlay.mutations);
|
|
118
|
+
}
|
|
119
|
+
// 5) BA column overrides (the 14 fields stay alongside the JSON)
|
|
120
|
+
const baCols = {};
|
|
121
|
+
for (const f of BA_COLUMN_FIELDS) {
|
|
122
|
+
baCols[f] = ba[f];
|
|
123
|
+
}
|
|
124
|
+
// 6) freeze and return
|
|
125
|
+
return Object.freeze({
|
|
126
|
+
...policy,
|
|
127
|
+
...baCols,
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=effective-policy.js.map
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { type TradingPolicyJson } from '../types/trading-policy';
|
|
2
|
+
import type { PolicyOverlayEntry } from '../types/policy-overlay';
|
|
3
|
+
/**
|
|
4
|
+
* Thrown when a caller invokes effectivePolicy() with a
|
|
5
|
+
* BrokerageAccount whose required relations (`fund.organization`,
|
|
6
|
+
* `fund.policyOverlays`) were not loaded by the selection set. We do
|
|
7
|
+
* not silently fall back to defaults — silent fall-back hides bugs.
|
|
8
|
+
*/
|
|
9
|
+
export declare class EffectivePolicyContextError extends Error {
|
|
10
|
+
constructor(field: string);
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* The 14 BrokerageAccount column fields preserved per charter §2.2.
|
|
14
|
+
* Read directly from the entity, not from the JSON merge.
|
|
15
|
+
*/
|
|
16
|
+
declare const BA_COLUMN_FIELDS: readonly ["enablePortfolioTrailingStop", "portfolioTrailPercent", "portfolioProfitThresholdPercent", "reducedPortfolioTrailPercent", "defaultTrailingStopPercentage100", "firstTrailReductionThreshold100", "secondTrailReductionThreshold100", "firstReducedTrailPercentage100", "secondReducedTrailPercentage100", "minimumPriceChangePercent100", "cryptoTradingEnabled", "cryptoTradingPairs", "tradeAllocationPct", "cryptoTradeAllocationPct"];
|
|
17
|
+
type BACol = (typeof BA_COLUMN_FIELDS)[number];
|
|
18
|
+
/**
|
|
19
|
+
* The relation shape effectivePolicy() requires. Consumers must fetch
|
|
20
|
+
* with the selection set below to populate these correctly.
|
|
21
|
+
*/
|
|
22
|
+
export interface BrokerageAccountWithPolicyContext {
|
|
23
|
+
id: string;
|
|
24
|
+
enablePortfolioTrailingStop: boolean;
|
|
25
|
+
portfolioTrailPercent: number;
|
|
26
|
+
portfolioProfitThresholdPercent: number;
|
|
27
|
+
reducedPortfolioTrailPercent: number;
|
|
28
|
+
defaultTrailingStopPercentage100: number;
|
|
29
|
+
firstTrailReductionThreshold100: number;
|
|
30
|
+
secondTrailReductionThreshold100: number;
|
|
31
|
+
firstReducedTrailPercentage100: number;
|
|
32
|
+
secondReducedTrailPercentage100: number;
|
|
33
|
+
minimumPriceChangePercent100: number;
|
|
34
|
+
cryptoTradingEnabled: boolean;
|
|
35
|
+
cryptoTradingPairs: string[];
|
|
36
|
+
tradeAllocationPct: number;
|
|
37
|
+
cryptoTradeAllocationPct: number;
|
|
38
|
+
fund: {
|
|
39
|
+
id: string;
|
|
40
|
+
tradingOverrides: TradingPolicyJson | null;
|
|
41
|
+
policyOverlays: PolicyOverlayEntry[] | null;
|
|
42
|
+
organization: {
|
|
43
|
+
id: string;
|
|
44
|
+
tradingDefaults: TradingPolicyJson | null;
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Canonical selection-set string for `adaptic.brokerageAccount.get(id, …)`.
|
|
50
|
+
* Loads fund + fund.organization + fund.policyOverlays in one query.
|
|
51
|
+
*
|
|
52
|
+
* Consumers should pass this verbatim to fetch a BrokerageAccount
|
|
53
|
+
* suitable for effectivePolicy().
|
|
54
|
+
*/
|
|
55
|
+
export declare const brokerageAccountWithPolicyContextSelectionSet = "\n id\n enablePortfolioTrailingStop\n portfolioTrailPercent\n portfolioProfitThresholdPercent\n reducedPortfolioTrailPercent\n defaultTrailingStopPercentage100\n firstTrailReductionThreshold100\n secondTrailReductionThreshold100\n firstReducedTrailPercentage100\n secondReducedTrailPercentage100\n minimumPriceChangePercent100\n cryptoTradingEnabled\n cryptoTradingPairs\n tradeAllocationPct\n cryptoTradeAllocationPct\n fund {\n id\n tradingOverrides\n policyOverlays\n organization { id tradingDefaults }\n }\n";
|
|
56
|
+
/**
|
|
57
|
+
* Deep-merges DEFAULT_TRADING_POLICY → Org.tradingDefaults →
|
|
58
|
+
* Fund.tradingOverrides → active Fund.policyOverlays (severity-sorted)
|
|
59
|
+
* → 14 BrokerageAccount column fields into a single canonical
|
|
60
|
+
* `Required<TradingPolicyJson>` plus the 14 column overrides.
|
|
61
|
+
*
|
|
62
|
+
* Consumers MUST use this helper — do not re-implement the precedence
|
|
63
|
+
* chain. The result is frozen.
|
|
64
|
+
*
|
|
65
|
+
* @throws EffectivePolicyContextError if `fund.organization` or
|
|
66
|
+
* `fund.policyOverlays` is missing (selection-set bug).
|
|
67
|
+
*/
|
|
68
|
+
export declare function effectivePolicy(ba: BrokerageAccountWithPolicyContext): Required<TradingPolicyJson> & Record<BACol, unknown>;
|
|
69
|
+
export {};
|
|
70
|
+
//# sourceMappingURL=effective-policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"effective-policy.d.ts","sourceRoot":"","sources":["../../src/helpers/effective-policy.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EACV,kBAAkB,EAEnB,MAAM,yBAAyB,CAAC;AAEjC;;;;;GAKG;AACH,qBAAa,2BAA4B,SAAQ,KAAK;gBACxC,KAAK,EAAE,MAAM;CAQ1B;AAED;;;GAGG;AACH,QAAA,MAAM,gBAAgB,sbAeZ,CAAC;AAEX,KAAK,KAAK,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE/C;;;GAGG;AACH,MAAM,WAAW,iCAAiC;IAChD,EAAE,EAAE,MAAM,CAAC;IACX,2BAA2B,EAAE,OAAO,CAAC;IACrC,qBAAqB,EAAE,MAAM,CAAC;IAC9B,+BAA+B,EAAE,MAAM,CAAC;IACxC,4BAA4B,EAAE,MAAM,CAAC;IACrC,gCAAgC,EAAE,MAAM,CAAC;IACzC,+BAA+B,EAAE,MAAM,CAAC;IACxC,gCAAgC,EAAE,MAAM,CAAC;IACzC,8BAA8B,EAAE,MAAM,CAAC;IACvC,+BAA+B,EAAE,MAAM,CAAC;IACxC,4BAA4B,EAAE,MAAM,CAAC;IACrC,oBAAoB,EAAE,OAAO,CAAC;IAC9B,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,wBAAwB,EAAE,MAAM,CAAC;IACjC,IAAI,EAAE;QACJ,EAAE,EAAE,MAAM,CAAC;QACX,gBAAgB,EAAE,iBAAiB,GAAG,IAAI,CAAC;QAC3C,cAAc,EAAE,kBAAkB,EAAE,GAAG,IAAI,CAAC;QAC5C,YAAY,EAAE;YACZ,EAAE,EAAE,MAAM,CAAC;YACX,eAAe,EAAE,iBAAiB,GAAG,IAAI,CAAC;SAC3C,CAAC;KACH,CAAC;CACH;AASD;;;;;;GAMG;AACH,eAAO,MAAM,6CAA6C,kiBAsBzD,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAC7B,EAAE,EAAE,iCAAiC,GACpC,QAAQ,CAAC,iBAAiB,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAuDtD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"effective-policy.js","sourceRoot":"","sources":["../../src/helpers/effective-policy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.decryptApiKey = exports.encryptApiKey = void 0;
|
|
4
|
+
const node_crypto_1 = require("node:crypto");
|
|
5
|
+
const kms_envelope_kms_adapter_1 = require("./kms-envelope.kms-adapter.cjs");
|
|
6
|
+
const requireKeyId = () => {
|
|
7
|
+
const k = process.env.KMS_KEY_ID;
|
|
8
|
+
if (!k) {
|
|
9
|
+
throw new Error('KMS_KEY_ID env var is required for kms-envelope');
|
|
10
|
+
}
|
|
11
|
+
return k;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Encrypts plaintext under a fresh per-record DEK wrapped by the
|
|
15
|
+
* configured KMS CMK. Returns the on-disk envelope shape.
|
|
16
|
+
*/
|
|
17
|
+
const encryptApiKey = async (plaintext) => {
|
|
18
|
+
const keyId = requireKeyId();
|
|
19
|
+
const dek = (0, node_crypto_1.randomBytes)(32); // 256-bit DEK
|
|
20
|
+
const iv = (0, node_crypto_1.randomBytes)(12); // 96-bit IV for GCM
|
|
21
|
+
const cipher = (0, node_crypto_1.createCipheriv)('aes-256-gcm', dek, iv);
|
|
22
|
+
const ct = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()]);
|
|
23
|
+
const authTag = cipher.getAuthTag();
|
|
24
|
+
const wrapped = await (0, kms_envelope_kms_adapter_1.kmsWrap)(dek, keyId);
|
|
25
|
+
return {
|
|
26
|
+
ciphertext: ct.toString('base64'),
|
|
27
|
+
iv: iv.toString('base64'),
|
|
28
|
+
authTag: authTag.toString('base64'),
|
|
29
|
+
keyId,
|
|
30
|
+
wrappedDek: wrapped.toString('base64'),
|
|
31
|
+
algorithm: 'AES-256-GCM',
|
|
32
|
+
createdAt: new Date().toISOString(),
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
exports.encryptApiKey = encryptApiKey;
|
|
36
|
+
/**
|
|
37
|
+
* Decrypts an EncryptedApiKey envelope. Throws on tampering,
|
|
38
|
+
* unsupported algorithm, or KMS unwrap failure.
|
|
39
|
+
*/
|
|
40
|
+
const decryptApiKey = async (env) => {
|
|
41
|
+
if (env.algorithm !== 'AES-256-GCM') {
|
|
42
|
+
throw new Error(`Unsupported algorithm: ${env.algorithm}`);
|
|
43
|
+
}
|
|
44
|
+
const dek = await (0, kms_envelope_kms_adapter_1.kmsUnwrap)(Buffer.from(env.wrappedDek, 'base64'), env.keyId);
|
|
45
|
+
const iv = Buffer.from(env.iv, 'base64');
|
|
46
|
+
const authTag = Buffer.from(env.authTag, 'base64');
|
|
47
|
+
const ct = Buffer.from(env.ciphertext, 'base64');
|
|
48
|
+
const decipher = (0, node_crypto_1.createDecipheriv)('aes-256-gcm', dek, iv);
|
|
49
|
+
decipher.setAuthTag(authTag);
|
|
50
|
+
return Buffer.concat([decipher.update(ct), decipher.final()]).toString('utf8');
|
|
51
|
+
};
|
|
52
|
+
exports.decryptApiKey = decryptApiKey;
|
|
53
|
+
//# sourceMappingURL=kms-envelope.js.map
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Envelope-encrypted secret at rest. Stored as a JSON value inside
|
|
3
|
+
* `Organization.llmDefaults.apiKeys.<provider>` and
|
|
4
|
+
* `Fund.llmOverrides.apiKeys.<provider>` per charter §2.4 F6 and
|
|
5
|
+
* spec §4.3.
|
|
6
|
+
*
|
|
7
|
+
* Algorithm: AES-256-GCM with per-record IV. The DEK is generated
|
|
8
|
+
* per-record and wrapped by a KMS-managed CMK identified by `keyId`.
|
|
9
|
+
*/
|
|
10
|
+
export interface EncryptedApiKey {
|
|
11
|
+
/** base64-encoded AES-GCM ciphertext */
|
|
12
|
+
ciphertext: string;
|
|
13
|
+
/** base64-encoded 12-byte IV */
|
|
14
|
+
iv: string;
|
|
15
|
+
/** base64-encoded 16-byte GCM auth tag */
|
|
16
|
+
authTag: string;
|
|
17
|
+
/** KMS key id used to wrap the DEK */
|
|
18
|
+
keyId: string;
|
|
19
|
+
/** base64-encoded KMS-wrapped DEK */
|
|
20
|
+
wrappedDek: string;
|
|
21
|
+
/** Locked to AES-256-GCM for now; future schemas extend this union. */
|
|
22
|
+
algorithm: 'AES-256-GCM';
|
|
23
|
+
/** ISO-8601 timestamp of when this envelope was created. */
|
|
24
|
+
createdAt: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Encrypts plaintext under a fresh per-record DEK wrapped by the
|
|
28
|
+
* configured KMS CMK. Returns the on-disk envelope shape.
|
|
29
|
+
*/
|
|
30
|
+
export declare const encryptApiKey: (plaintext: string) => Promise<EncryptedApiKey>;
|
|
31
|
+
/**
|
|
32
|
+
* Decrypts an EncryptedApiKey envelope. Throws on tampering,
|
|
33
|
+
* unsupported algorithm, or KMS unwrap failure.
|
|
34
|
+
*/
|
|
35
|
+
export declare const decryptApiKey: (env: EncryptedApiKey) => Promise<string>;
|
|
36
|
+
//# sourceMappingURL=kms-envelope.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kms-envelope.d.ts","sourceRoot":"","sources":["../../src/helpers/kms-envelope.ts"],"names":[],"mappings":"AAGA;;;;;;;;GAQG;AACH,MAAM,WAAW,eAAe;IAC9B,wCAAwC;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,gCAAgC;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,0CAA0C;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,sCAAsC;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,qCAAqC;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,uEAAuE;IACvE,SAAS,EAAE,aAAa,CAAC;IACzB,4DAA4D;IAC5D,SAAS,EAAE,MAAM,CAAC;CACnB;AAUD;;;GAGG;AACH,eAAO,MAAM,aAAa,GACxB,WAAW,MAAM,KAChB,OAAO,CAAC,eAAe,CAiBzB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,aAAa,GAAU,KAAK,eAAe,KAAG,OAAO,CAAC,MAAM,CAaxE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kms-envelope.js","sourceRoot":"","sources":["../../src/helpers/kms-envelope.ts"],"names":[],"mappings":";;;AAAA,6CAA4E;AAC5E,yEAAgE;AA4BhE,MAAM,YAAY,GAAG,GAAW,EAAE;IAChC,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;IACjC,IAAI,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC,CAAC;AAEF;;;GAGG;AACI,MAAM,aAAa,GAAG,KAAK,EAChC,SAAiB,EACS,EAAE;IAC5B,MAAM,KAAK,GAAG,YAAY,EAAE,CAAC;IAC7B,MAAM,GAAG,GAAG,IAAA,yBAAW,EAAC,EAAE,CAAC,CAAC,CAAC,cAAc;IAC3C,MAAM,EAAE,GAAG,IAAA,yBAAW,EAAC,EAAE,CAAC,CAAC,CAAC,oBAAoB;IAChD,MAAM,MAAM,GAAG,IAAA,4BAAc,EAAC,aAAa,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;IACtD,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAC7E,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;IACpC,MAAM,OAAO,GAAG,MAAM,IAAA,kCAAO,EAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC1C,OAAO;QACL,UAAU,EAAE,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC;QACjC,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC;QACzB,OAAO,EAAE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;QACnC,KAAK;QACL,UAAU,EAAE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;QACtC,SAAS,EAAE,aAAa;QACxB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,CAAC;AACJ,CAAC,CAAC;AAnBW,QAAA,aAAa,iBAmBxB;AAEF;;;GAGG;AACI,MAAM,aAAa,GAAG,KAAK,EAAE,GAAoB,EAAmB,EAAE;IAC3E,IAAI,GAAG,CAAC,SAAS,KAAK,aAAa,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,0BAA0B,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC;IAC7D,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,IAAA,oCAAS,EAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,QAAQ,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;IAC9E,MAAM,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IACnD,MAAM,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IACjD,MAAM,QAAQ,GAAG,IAAA,8BAAgB,EAAC,aAAa,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;IAC1D,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IAC7B,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,QAAQ,CACpE,MAAM,CACP,CAAC;AACJ,CAAC,CAAC;AAbW,QAAA,aAAa,iBAaxB"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* KMS adapter — wraps/unwraps the per-record Data Encryption Key (DEK).
|
|
4
|
+
*
|
|
5
|
+
* Unit tests mock this module to provide deterministic wrap/unwrap.
|
|
6
|
+
* The runtime implementation should wire to AWS KMS via
|
|
7
|
+
* `@aws-sdk/client-kms` (or GCP KMS via `@google-cloud/kms`) and
|
|
8
|
+
* be replaced via a build-time alias or runtime injection.
|
|
9
|
+
*
|
|
10
|
+
* The default exports throw so unintended use in production surfaces
|
|
11
|
+
* an obvious error rather than silently returning plaintext-as-wrapped.
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.kmsUnwrap = exports.kmsWrap = void 0;
|
|
15
|
+
const kmsWrap = async (_dek, _keyId) => {
|
|
16
|
+
throw new Error('kmsWrap not wired to a real KMS provider. Mock this module in tests, ' +
|
|
17
|
+
'or wire to AWS KMS via @aws-sdk/client-kms (or GCP KMS via @google-cloud/kms).');
|
|
18
|
+
};
|
|
19
|
+
exports.kmsWrap = kmsWrap;
|
|
20
|
+
const kmsUnwrap = async (_wrapped, _keyId) => {
|
|
21
|
+
throw new Error('kmsUnwrap not wired to a real KMS provider. Mock this module in tests, ' +
|
|
22
|
+
'or wire to AWS KMS via @aws-sdk/client-kms (or GCP KMS via @google-cloud/kms).');
|
|
23
|
+
};
|
|
24
|
+
exports.kmsUnwrap = kmsUnwrap;
|
|
25
|
+
//# sourceMappingURL=kms-envelope.kms-adapter.js.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* KMS adapter — wraps/unwraps the per-record Data Encryption Key (DEK).
|
|
3
|
+
*
|
|
4
|
+
* Unit tests mock this module to provide deterministic wrap/unwrap.
|
|
5
|
+
* The runtime implementation should wire to AWS KMS via
|
|
6
|
+
* `@aws-sdk/client-kms` (or GCP KMS via `@google-cloud/kms`) and
|
|
7
|
+
* be replaced via a build-time alias or runtime injection.
|
|
8
|
+
*
|
|
9
|
+
* The default exports throw so unintended use in production surfaces
|
|
10
|
+
* an obvious error rather than silently returning plaintext-as-wrapped.
|
|
11
|
+
*/
|
|
12
|
+
export declare const kmsWrap: (_dek: Buffer, _keyId: string) => Promise<Buffer>;
|
|
13
|
+
export declare const kmsUnwrap: (_wrapped: Buffer, _keyId: string) => Promise<Buffer>;
|
|
14
|
+
//# sourceMappingURL=kms-envelope.kms-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kms-envelope.kms-adapter.d.ts","sourceRoot":"","sources":["../../src/helpers/kms-envelope.kms-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,eAAO,MAAM,OAAO,GAClB,MAAM,MAAM,EACZ,QAAQ,MAAM,KACb,OAAO,CAAC,MAAM,CAKhB,CAAC;AAEF,eAAO,MAAM,SAAS,GACpB,UAAU,MAAM,EAChB,QAAQ,MAAM,KACb,OAAO,CAAC,MAAM,CAKhB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kms-envelope.kms-adapter.js","sourceRoot":"","sources":["../../src/helpers/kms-envelope.kms-adapter.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;;AAEI,MAAM,OAAO,GAAG,KAAK,EAC1B,IAAY,EACZ,MAAc,EACG,EAAE;IACnB,MAAM,IAAI,KAAK,CACb,uEAAuE;QACrE,gFAAgF,CACnF,CAAC;AACJ,CAAC,CAAC;AARW,QAAA,OAAO,WAQlB;AAEK,MAAM,SAAS,GAAG,KAAK,EAC5B,QAAgB,EAChB,MAAc,EACG,EAAE;IACnB,MAAM,IAAI,KAAK,CACb,yEAAyE;QACvE,gFAAgF,CACnF,CAAC;AACJ,CAAC,CAAC;AARW,QAAA,SAAS,aAQpB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adaptic/backend-legacy",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.85",
|
|
4
4
|
"description": "Backend executable CRUD functions with dynamic variables construction, and type definitions for the Adaptic AI platform.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -24,6 +24,8 @@
|
|
|
24
24
|
"validators/",
|
|
25
25
|
"config/",
|
|
26
26
|
"middleware/",
|
|
27
|
+
"types/",
|
|
28
|
+
"helpers/",
|
|
27
29
|
"*.d.ts",
|
|
28
30
|
"*.js",
|
|
29
31
|
"*.cjs",
|
package/server.cjs
CHANGED
|
@@ -22,6 +22,7 @@ const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
|
|
|
22
22
|
const auth_1 = require("./middleware/auth.cjs");
|
|
23
23
|
const audit_logger_1 = require("./middleware/audit-logger.cjs");
|
|
24
24
|
const jwtConfig_1 = require("./config/jwtConfig.cjs");
|
|
25
|
+
const http_status_mapper_1 = require("./plugins/http-status-mapper.cjs");
|
|
25
26
|
const prismaClient_1 = __importDefault(require("./prismaClient.cjs"));
|
|
26
27
|
const health_1 = require("./health.cjs");
|
|
27
28
|
const child_process_1 = require("child_process");
|
|
@@ -70,6 +71,7 @@ const startServer = async () => {
|
|
|
70
71
|
plugins: [
|
|
71
72
|
(0, drainHttpServer_1.ApolloServerPluginDrainHttpServer)({ httpServer }),
|
|
72
73
|
(0, audit_logger_1.createAuditLogPlugin)(),
|
|
74
|
+
(0, http_status_mapper_1.createHttpStatusMapperPlugin)(),
|
|
73
75
|
],
|
|
74
76
|
formatError: (err) => {
|
|
75
77
|
var _a;
|
|
@@ -136,8 +138,17 @@ const startServer = async () => {
|
|
|
136
138
|
// Health check endpoint - mounted before Apollo middleware so it's not behind GraphQL or auth
|
|
137
139
|
app.use((0, health_1.createHealthRouter)());
|
|
138
140
|
// Configure CORS with allowed origins
|
|
139
|
-
const defaultOrigins = [
|
|
140
|
-
|
|
141
|
+
const defaultOrigins = [
|
|
142
|
+
'http://localhost:3000',
|
|
143
|
+
'http://localhost:3001',
|
|
144
|
+
'http://localhost:4000',
|
|
145
|
+
'https://adaptic.ai',
|
|
146
|
+
'https://api.adaptic.ai',
|
|
147
|
+
'https://os.adaptic.ai',
|
|
148
|
+
];
|
|
149
|
+
const envOrigins = process.env.ALLOWED_ORIGINS
|
|
150
|
+
? process.env.ALLOWED_ORIGINS.split(',').map((o) => o.trim())
|
|
151
|
+
: [];
|
|
141
152
|
const allowedOrigins = [...new Set([...defaultOrigins, ...envOrigins])];
|
|
142
153
|
const corsOptions = {
|
|
143
154
|
origin: (origin, callback) => {
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_LLM_CONFIGURATION = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Built-in safe defaults consumed by effectiveLlmConfig() as the
|
|
6
|
+
* lowest-precedence layer.
|
|
7
|
+
*/
|
|
8
|
+
exports.DEFAULT_LLM_CONFIGURATION = {
|
|
9
|
+
defaultProvider: 'OPENAI',
|
|
10
|
+
miniProvider: 'OPENAI',
|
|
11
|
+
normalProvider: 'OPENAI',
|
|
12
|
+
advancedProvider: 'ANTHROPIC',
|
|
13
|
+
miniModel: 'gpt-5.5',
|
|
14
|
+
normalModel: 'gpt-5',
|
|
15
|
+
advancedModel: 'claude-opus-4-7',
|
|
16
|
+
apiKeys: {},
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=llm-configuration.js.map
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { EncryptedApiKey } from '../helpers/kms-envelope';
|
|
2
|
+
export type LlmProvider = 'OPENAI' | 'ANTHROPIC' | 'DEEPSEEK' | 'KIMI' | 'QWEN' | 'XAI' | 'GEMINI';
|
|
3
|
+
/**
|
|
4
|
+
* Canonical LlmConfigurationJson shape stored at:
|
|
5
|
+
* Organization.llmDefaults (org-wide defaults)
|
|
6
|
+
* Fund.llmOverrides (fund-level overrides)
|
|
7
|
+
*
|
|
8
|
+
* Read-time merging is precedence-ordered (charter §2.4 F6, spec §4.3):
|
|
9
|
+
* built-in DEFAULT_LLM_CONFIGURATION → Org.llmDefaults → Fund.llmOverrides
|
|
10
|
+
*
|
|
11
|
+
* Consumers MUST use `effectiveLlmConfig()` from
|
|
12
|
+
* `@adaptic/backend-legacy/helpers/effective-llm-config`.
|
|
13
|
+
*
|
|
14
|
+
* API keys (`apiKeys.<provider>`) are stored as EncryptedApiKey
|
|
15
|
+
* envelopes; encrypt/decrypt is gated by org-membership role per
|
|
16
|
+
* spec §4.3.
|
|
17
|
+
*/
|
|
18
|
+
export interface LlmConfigurationJson {
|
|
19
|
+
/** Provider used when a tier-specific provider is unset. */
|
|
20
|
+
defaultProvider?: LlmProvider;
|
|
21
|
+
/** Per-tier provider overrides (null = inherit from defaultProvider). */
|
|
22
|
+
miniProvider?: LlmProvider;
|
|
23
|
+
normalProvider?: LlmProvider;
|
|
24
|
+
advancedProvider?: LlmProvider;
|
|
25
|
+
/** Per-tier model id strings (e.g. "gpt-5.5", "claude-opus-4-7"). */
|
|
26
|
+
miniModel?: string;
|
|
27
|
+
normalModel?: string;
|
|
28
|
+
advancedModel?: string;
|
|
29
|
+
/**
|
|
30
|
+
* Per-provider API keys, stored at rest as EncryptedApiKey envelopes.
|
|
31
|
+
* Plaintext only ever crosses the GraphQL mutation boundary.
|
|
32
|
+
*/
|
|
33
|
+
apiKeys?: Partial<Record<Lowercase<LlmProvider>, EncryptedApiKey>>;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Built-in safe defaults consumed by effectiveLlmConfig() as the
|
|
37
|
+
* lowest-precedence layer.
|
|
38
|
+
*/
|
|
39
|
+
export declare const DEFAULT_LLM_CONFIGURATION: Required<Omit<LlmConfigurationJson, 'apiKeys'>> & {
|
|
40
|
+
apiKeys: NonNullable<LlmConfigurationJson['apiKeys']>;
|
|
41
|
+
};
|
|
42
|
+
//# sourceMappingURL=llm-configuration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm-configuration.d.ts","sourceRoot":"","sources":["../../src/types/llm-configuration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE/D,MAAM,MAAM,WAAW,GACnB,QAAQ,GACR,WAAW,GACX,UAAU,GACV,MAAM,GACN,MAAM,GACN,KAAK,GACL,QAAQ,CAAC;AAEb;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,oBAAoB;IACnC,4DAA4D;IAC5D,eAAe,CAAC,EAAE,WAAW,CAAC;IAC9B,yEAAyE;IACzE,YAAY,CAAC,EAAE,WAAW,CAAC;IAC3B,cAAc,CAAC,EAAE,WAAW,CAAC;IAC7B,gBAAgB,CAAC,EAAE,WAAW,CAAC;IAC/B,qEAAqE;IACrE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,EAAE,eAAe,CAAC,CAAC,CAAC;CACpE;AAED;;;GAGG;AACH,eAAO,MAAM,yBAAyB,EAAE,QAAQ,CAC9C,IAAI,CAAC,oBAAoB,EAAE,SAAS,CAAC,CACtC,GAAG;IACF,OAAO,EAAE,WAAW,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAC,CAAC;CAUvD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm-configuration.js","sourceRoot":"","sources":["../../src/types/llm-configuration.ts"],"names":[],"mappings":";;;AA4CA;;;GAGG;AACU,QAAA,yBAAyB,GAIlC;IACF,eAAe,EAAE,QAAQ;IACzB,YAAY,EAAE,QAAQ;IACtB,cAAc,EAAE,QAAQ;IACxB,gBAAgB,EAAE,WAAW;IAC7B,SAAS,EAAE,SAAS;IACpB,WAAW,EAAE,OAAO;IACpB,aAAa,EAAE,iBAAiB;IAChC,OAAO,EAAE,EAAE;CACZ,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { TradingPolicyJson } from './trading-policy';
|
|
2
|
+
export type OverlayType = 'RISK_GATE' | 'NEWS_GATE' | 'COMPLIANCE_GATE' | 'MANUAL_HALT' | 'CIRCUIT_BREAKER';
|
|
3
|
+
export type OverlaySeverity = 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL';
|
|
4
|
+
export type OverlayStatus = 'ACTIVE' | 'EXPIRED' | 'DEACTIVATED';
|
|
5
|
+
/**
|
|
6
|
+
* Active and recent policy overlays stored on `Fund.policyOverlays`
|
|
7
|
+
* (Json[] column) per charter §2.4 F4 and spec §4.4.
|
|
8
|
+
*
|
|
9
|
+
* `effectivePolicy()` filters this list to entries where
|
|
10
|
+
* `status === 'ACTIVE' && (expiresAt == null || expiresAt > now)`,
|
|
11
|
+
* sorts by severity ascending (CRITICAL last → highest precedence),
|
|
12
|
+
* and deep-merges each overlay's `mutations` over the policy chain.
|
|
13
|
+
*
|
|
14
|
+
* On every status flip away from ACTIVE the engine archiver moves
|
|
15
|
+
* the entry to Tier-A `PolicyOverlayHistory` and removes it from this
|
|
16
|
+
* array atomically (one DB transaction). Steady-state size ≤ 20.
|
|
17
|
+
*/
|
|
18
|
+
export interface PolicyOverlayEntry {
|
|
19
|
+
/** UUID for cross-referencing with Tier-A PolicyOverlayHistory. */
|
|
20
|
+
id: string;
|
|
21
|
+
overlayType: OverlayType;
|
|
22
|
+
/** Source service that activated this overlay (e.g. "engine.risk.var-breach"). */
|
|
23
|
+
source: string;
|
|
24
|
+
/** Human-readable reason; surfaced in alerts. */
|
|
25
|
+
reason: string;
|
|
26
|
+
severity: OverlaySeverity;
|
|
27
|
+
/** Policy paths to override while ACTIVE. */
|
|
28
|
+
mutations: Partial<TradingPolicyJson>;
|
|
29
|
+
status: OverlayStatus;
|
|
30
|
+
/** ISO-8601 activation timestamp. */
|
|
31
|
+
activatedAt: string;
|
|
32
|
+
/** ISO-8601 expiry timestamp; absence means "until manually deactivated". */
|
|
33
|
+
expiresAt?: string;
|
|
34
|
+
deactivatedAt?: string;
|
|
35
|
+
deactivatedBy?: string;
|
|
36
|
+
/** Correlation id linking this overlay to the event that triggered it. */
|
|
37
|
+
correlationId?: string;
|
|
38
|
+
triggerEventId?: string;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=policy-overlay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy-overlay.d.ts","sourceRoot":"","sources":["../../src/types/policy-overlay.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,MAAM,MAAM,WAAW,GACnB,WAAW,GACX,WAAW,GACX,iBAAiB,GACjB,aAAa,GACb,iBAAiB,CAAC;AAEtB,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;AAErE,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,SAAS,GAAG,aAAa,CAAC;AAEjE;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,kBAAkB;IACjC,mEAAmE;IACnE,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,WAAW,CAAC;IACzB,kFAAkF;IAClF,MAAM,EAAE,MAAM,CAAC;IACf,iDAAiD;IACjD,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,eAAe,CAAC;IAC1B,6CAA6C;IAC7C,SAAS,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACtC,MAAM,EAAE,aAAa,CAAC;IACtB,qCAAqC;IACrC,WAAW,EAAE,MAAM,CAAC;IACpB,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,0EAA0E;IAC1E,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy-overlay.js","sourceRoot":"","sources":["../../src/types/policy-overlay.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_TRADING_POLICY = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Built-in safe defaults consumed by effectivePolicy() as the
|
|
6
|
+
* lowest-precedence layer. Tunings here are conservative and broadly
|
|
7
|
+
* safe; `@adaptic/utils` re-exports a more tuned variant for short-horizon
|
|
8
|
+
* day trading (see utils U1 plan).
|
|
9
|
+
*/
|
|
10
|
+
exports.DEFAULT_TRADING_POLICY = {
|
|
11
|
+
autonomy: {
|
|
12
|
+
enableAutoEntry: false,
|
|
13
|
+
enableAutoExit: true,
|
|
14
|
+
enableAutoRebalance: false,
|
|
15
|
+
requireHumanApprovalAboveNotional: 100000,
|
|
16
|
+
},
|
|
17
|
+
risk: {
|
|
18
|
+
maxPortfolioVarPct: 0.05,
|
|
19
|
+
maxSinglePositionPct: 0.1,
|
|
20
|
+
maxSectorExposurePct: 0.3,
|
|
21
|
+
maxAssetClassPct: { equity: 1.0, crypto: 0.2, options: 0.2 },
|
|
22
|
+
minBuyingPowerReservePct: 0.05,
|
|
23
|
+
},
|
|
24
|
+
allocation: {
|
|
25
|
+
perTradeEquityPct: 0.05,
|
|
26
|
+
perTradeCryptoPct: 0.05,
|
|
27
|
+
perTradeOptionsPct: 0.02,
|
|
28
|
+
autoAllocation: true,
|
|
29
|
+
},
|
|
30
|
+
scalping: {
|
|
31
|
+
enableScalping: false,
|
|
32
|
+
maxConcurrentScalps: 0,
|
|
33
|
+
minHoldSeconds: 0,
|
|
34
|
+
maxHoldSeconds: 0,
|
|
35
|
+
profitTargetBps: 0,
|
|
36
|
+
stopLossBps: 0,
|
|
37
|
+
requireRSIConfirm: false,
|
|
38
|
+
requireMACDConfirm: false,
|
|
39
|
+
requireVolumeSurge: false,
|
|
40
|
+
cooldownAfterLossMs: 0,
|
|
41
|
+
cooldownAfterWinMs: 0,
|
|
42
|
+
maxScalpsPerSession: 0,
|
|
43
|
+
},
|
|
44
|
+
compliance: {
|
|
45
|
+
equityWashTradeCooldownMs: 0,
|
|
46
|
+
restrictedTickerOverrides: [],
|
|
47
|
+
requireAuditLogForAll: true,
|
|
48
|
+
},
|
|
49
|
+
assetClasses: { equity: true, crypto: false, options: false },
|
|
50
|
+
sentiment: {
|
|
51
|
+
minSentimentScoreToEnter: 0,
|
|
52
|
+
maxNegativeSentimentToHold: -0.5,
|
|
53
|
+
requireRecentNews: false,
|
|
54
|
+
newsLookbackMinutes: 1440,
|
|
55
|
+
},
|
|
56
|
+
backtest: {
|
|
57
|
+
defaultUniverse: [],
|
|
58
|
+
defaultPeriodDays: 30,
|
|
59
|
+
defaultStrategyId: '',
|
|
60
|
+
},
|
|
61
|
+
runtime: {
|
|
62
|
+
enginePersonalityProfile: 'balanced',
|
|
63
|
+
signalRoutingRules: null,
|
|
64
|
+
manualOverrideAllowlist: [],
|
|
65
|
+
riskOverrideJustifications: [],
|
|
66
|
+
enableShadowMode: false,
|
|
67
|
+
experimentBucket: null,
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
//# sourceMappingURL=trading-policy.js.map
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical TradingPolicyJson shape stored at:
|
|
3
|
+
* Organization.tradingDefaults (org-wide defaults)
|
|
4
|
+
* Fund.tradingOverrides (fund-level overrides)
|
|
5
|
+
*
|
|
6
|
+
* Read-time merging is precedence-ordered (charter §2.2, spec §4.2.2):
|
|
7
|
+
* built-in DEFAULT_TRADING_POLICY → Org.tradingDefaults
|
|
8
|
+
* → Fund.tradingOverrides → active Fund.policyOverlays
|
|
9
|
+
* → 14 per-BrokerageAccount column overrides
|
|
10
|
+
*
|
|
11
|
+
* Consumers MUST use `effectivePolicy()` from
|
|
12
|
+
* `@adaptic/backend-legacy/helpers/effective-policy` — do NOT
|
|
13
|
+
* re-implement the precedence chain.
|
|
14
|
+
*/
|
|
15
|
+
export interface TradingPolicyJson {
|
|
16
|
+
/** Autonomy — when the engine is allowed to act without human approval. */
|
|
17
|
+
autonomy?: {
|
|
18
|
+
enableAutoEntry?: boolean;
|
|
19
|
+
enableAutoExit?: boolean;
|
|
20
|
+
enableAutoRebalance?: boolean;
|
|
21
|
+
requireHumanApprovalAboveNotional?: number;
|
|
22
|
+
};
|
|
23
|
+
/** Risk caps applied per-strategy and per-portfolio. */
|
|
24
|
+
risk?: {
|
|
25
|
+
/** Maximum portfolio Value-at-Risk as a fraction (0..1). */
|
|
26
|
+
maxPortfolioVarPct?: number;
|
|
27
|
+
/** Maximum single-position weight as a fraction (0..1). */
|
|
28
|
+
maxSinglePositionPct?: number;
|
|
29
|
+
/** Maximum sector exposure as a fraction (0..1). */
|
|
30
|
+
maxSectorExposurePct?: number;
|
|
31
|
+
/** Per-asset-class caps as fractions of NAV. */
|
|
32
|
+
maxAssetClassPct?: {
|
|
33
|
+
equity?: number;
|
|
34
|
+
crypto?: number;
|
|
35
|
+
options?: number;
|
|
36
|
+
};
|
|
37
|
+
/** Minimum buying-power reserve as a fraction (0..1). */
|
|
38
|
+
minBuyingPowerReservePct?: number;
|
|
39
|
+
};
|
|
40
|
+
/** Per-trade allocation defaults (SR's tradeAllocationPct collapsed here). */
|
|
41
|
+
allocation?: {
|
|
42
|
+
perTradeEquityPct?: number;
|
|
43
|
+
perTradeCryptoPct?: number;
|
|
44
|
+
perTradeOptionsPct?: number;
|
|
45
|
+
autoAllocation?: boolean;
|
|
46
|
+
};
|
|
47
|
+
/** Scalping / intraday-specific policy (12 W3-3 fields from SR commit 10b63819d). */
|
|
48
|
+
scalping?: {
|
|
49
|
+
enableScalping?: boolean;
|
|
50
|
+
maxConcurrentScalps?: number;
|
|
51
|
+
minHoldSeconds?: number;
|
|
52
|
+
maxHoldSeconds?: number;
|
|
53
|
+
profitTargetBps?: number;
|
|
54
|
+
stopLossBps?: number;
|
|
55
|
+
requireRSIConfirm?: boolean;
|
|
56
|
+
requireMACDConfirm?: boolean;
|
|
57
|
+
requireVolumeSurge?: boolean;
|
|
58
|
+
cooldownAfterLossMs?: number;
|
|
59
|
+
cooldownAfterWinMs?: number;
|
|
60
|
+
maxScalpsPerSession?: number;
|
|
61
|
+
};
|
|
62
|
+
/** Compliance — FINRA / SEC operational rules. */
|
|
63
|
+
compliance?: {
|
|
64
|
+
/** FINRA 5210 wash-trade cooldown in milliseconds. */
|
|
65
|
+
equityWashTradeCooldownMs?: number;
|
|
66
|
+
/** Tickers explicitly excluded from autonomous trading. */
|
|
67
|
+
restrictedTickerOverrides?: string[];
|
|
68
|
+
/** Force AuditLog row creation on every order. */
|
|
69
|
+
requireAuditLogForAll?: boolean;
|
|
70
|
+
};
|
|
71
|
+
/** Asset-class enablement (defaults set in DEFAULT_TRADING_POLICY). */
|
|
72
|
+
assetClasses?: {
|
|
73
|
+
equity?: boolean;
|
|
74
|
+
crypto?: boolean;
|
|
75
|
+
options?: boolean;
|
|
76
|
+
};
|
|
77
|
+
/** Sentiment / news subscription policy (fund-scope per charter §2.4 F5). */
|
|
78
|
+
sentiment?: {
|
|
79
|
+
minSentimentScoreToEnter?: number;
|
|
80
|
+
maxNegativeSentimentToHold?: number;
|
|
81
|
+
requireRecentNews?: boolean;
|
|
82
|
+
newsLookbackMinutes?: number;
|
|
83
|
+
};
|
|
84
|
+
/** Backtest scope (fund-scope per charter §2.4 F7). */
|
|
85
|
+
backtest?: {
|
|
86
|
+
defaultUniverse?: string[];
|
|
87
|
+
defaultPeriodDays?: number;
|
|
88
|
+
defaultStrategyId?: string;
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* Engine runtime config (charter §2.4 F1/F8/F9 catch-all).
|
|
92
|
+
*
|
|
93
|
+
* Populated when sub-project 6 (engine port) has not yet committed
|
|
94
|
+
* to owning `EngineFundConfig` in Tier-A. Carries the 6 SR
|
|
95
|
+
* `TradingPolicy` policy-shape fields that have no canonical JSON
|
|
96
|
+
* home: enginePersonalityProfile, signalRoutingRules,
|
|
97
|
+
* manualOverrideAllowlist, riskOverrideJustifications,
|
|
98
|
+
* enableShadowMode, experimentBucket.
|
|
99
|
+
*
|
|
100
|
+
* If/when sub-project 6 promotes these to Tier-A, this group can be
|
|
101
|
+
* migrated out and removed.
|
|
102
|
+
*/
|
|
103
|
+
runtime?: {
|
|
104
|
+
enginePersonalityProfile?: string;
|
|
105
|
+
signalRoutingRules?: unknown;
|
|
106
|
+
manualOverrideAllowlist?: string[];
|
|
107
|
+
riskOverrideJustifications?: unknown[];
|
|
108
|
+
enableShadowMode?: boolean;
|
|
109
|
+
experimentBucket?: string | null;
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Built-in safe defaults consumed by effectivePolicy() as the
|
|
114
|
+
* lowest-precedence layer. Tunings here are conservative and broadly
|
|
115
|
+
* safe; `@adaptic/utils` re-exports a more tuned variant for short-horizon
|
|
116
|
+
* day trading (see utils U1 plan).
|
|
117
|
+
*/
|
|
118
|
+
export declare const DEFAULT_TRADING_POLICY: Required<TradingPolicyJson>;
|
|
119
|
+
//# sourceMappingURL=trading-policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trading-policy.d.ts","sourceRoot":"","sources":["../../src/types/trading-policy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trading-policy.js","sourceRoot":"","sources":["../../src/types/trading-policy.ts"],"names":[],"mappings":";;;AAwHA;;;;;GAKG;AACU,QAAA,sBAAsB,GAAgC;IACjE,QAAQ,EAAE;QACR,eAAe,EAAE,KAAK;QACtB,cAAc,EAAE,IAAI;QACpB,mBAAmB,EAAE,KAAK;QAC1B,iCAAiC,EAAE,MAAO;KAC3C;IACD,IAAI,EAAE;QACJ,kBAAkB,EAAE,IAAI;QACxB,oBAAoB,EAAE,GAAG;QACzB,oBAAoB,EAAE,GAAG;QACzB,gBAAgB,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE;QAC5D,wBAAwB,EAAE,IAAI;KAC/B;IACD,UAAU,EAAE;QACV,iBAAiB,EAAE,IAAI;QACvB,iBAAiB,EAAE,IAAI;QACvB,kBAAkB,EAAE,IAAI;QACxB,cAAc,EAAE,IAAI;KACrB;IACD,QAAQ,EAAE;QACR,cAAc,EAAE,KAAK;QACrB,mBAAmB,EAAE,CAAC;QACtB,cAAc,EAAE,CAAC;QACjB,cAAc,EAAE,CAAC;QACjB,eAAe,EAAE,CAAC;QAClB,WAAW,EAAE,CAAC;QACd,iBAAiB,EAAE,KAAK;QACxB,kBAAkB,EAAE,KAAK;QACzB,kBAAkB,EAAE,KAAK;QACzB,mBAAmB,EAAE,CAAC;QACtB,kBAAkB,EAAE,CAAC;QACrB,mBAAmB,EAAE,CAAC;KACvB;IACD,UAAU,EAAE;QACV,yBAAyB,EAAE,CAAC;QAC5B,yBAAyB,EAAE,EAAE;QAC7B,qBAAqB,EAAE,IAAI;KAC5B;IACD,YAAY,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE;IAC7D,SAAS,EAAE;QACT,wBAAwB,EAAE,CAAC;QAC3B,0BAA0B,EAAE,CAAC,GAAG;QAChC,iBAAiB,EAAE,KAAK;QACxB,mBAAmB,EAAE,IAAI;KAC1B;IACD,QAAQ,EAAE;QACR,eAAe,EAAE,EAAE;QACnB,iBAAiB,EAAE,EAAE;QACrB,iBAAiB,EAAE,EAAE;KACtB;IACD,OAAO,EAAE;QACP,wBAAwB,EAAE,UAAU;QACpC,kBAAkB,EAAE,IAAI;QACxB,uBAAuB,EAAE,EAAE;QAC3B,0BAA0B,EAAE,EAAE;QAC9B,gBAAgB,EAAE,KAAK;QACvB,gBAAgB,EAAE,IAAI;KACvB;CACF,CAAC"}
|