@suveren/gateway 0.13.0 → 0.14.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 +19 -3
- package/bin/suveren-gateway.js +5 -0
- package/dist/control-plane/index.mjs +146 -114
- package/dist/mcp-server/http.mjs +162 -118
- package/dist/ui/assets/{index-CmLqzgqA.js → index-Cg6VaGKb.js} +12 -12
- package/dist/ui/index.html +1 -1
- package/lib/autostart-templates.mjs +15 -7
- package/node_modules/@hap/core/dist/index.d.mts +49 -1
- package/node_modules/@hap/core/dist/index.d.ts +49 -1
- package/node_modules/@hap/core/dist/index.js +50 -0
- package/node_modules/@hap/core/dist/index.mjs +49 -0
- package/node_modules/@hap/core/package.json +1 -1
- package/node_modules/@hap/core/src/frame.ts +63 -1
- package/node_modules/@hap/core/src/gatekeeper.ts +37 -0
- package/node_modules/@hap/core/src/types.ts +29 -1
- package/node_modules/hono/dist/cjs/hono-base.js +2 -0
- package/node_modules/hono/dist/cjs/middleware/language/language.js +1 -1
- package/node_modules/hono/dist/cjs/middleware/mount/index.js +71 -0
- package/node_modules/hono/dist/cjs/request.js +4 -4
- package/node_modules/hono/dist/hono-base.js +2 -0
- package/node_modules/hono/dist/middleware/mount/index.js +70 -0
- package/node_modules/hono/dist/request.js +4 -4
- package/node_modules/hono/dist/types/hono-base.d.ts +2 -0
- package/node_modules/hono/dist/types/jsx/base.d.ts +1 -1
- package/node_modules/hono/dist/types/middleware/mount/index.d.ts +46 -0
- package/node_modules/hono/dist/types/request.d.ts +4 -4
- package/node_modules/hono/package.json +9 -1
- package/package.json +2 -2
- package/profiles/index.json +3 -1
- package/profiles/purchase/0.6.profile.json +234 -0
- package/profiles/sales/0.3.profile.json +290 -0
- package/server.js +6 -3
|
@@ -189,7 +189,7 @@ var HonoRequest = class {
|
|
|
189
189
|
return this.#validatedData?.[target];
|
|
190
190
|
}
|
|
191
191
|
/**
|
|
192
|
-
* `.url
|
|
192
|
+
* `.url` can get the request url strings.
|
|
193
193
|
*
|
|
194
194
|
* @see {@link https://hono.dev/docs/api/request#url}
|
|
195
195
|
*
|
|
@@ -205,7 +205,7 @@ var HonoRequest = class {
|
|
|
205
205
|
return this.raw.url;
|
|
206
206
|
}
|
|
207
207
|
/**
|
|
208
|
-
* `.method
|
|
208
|
+
* `.method` can get the method name of the request.
|
|
209
209
|
*
|
|
210
210
|
* @see {@link https://hono.dev/docs/api/request#method}
|
|
211
211
|
*
|
|
@@ -223,7 +223,7 @@ var HonoRequest = class {
|
|
|
223
223
|
return this.#matchResult;
|
|
224
224
|
}
|
|
225
225
|
/**
|
|
226
|
-
* `.matchedRoutes
|
|
226
|
+
* `.matchedRoutes` can return a matched route in the handler
|
|
227
227
|
*
|
|
228
228
|
* @deprecated
|
|
229
229
|
*
|
|
@@ -253,7 +253,7 @@ var HonoRequest = class {
|
|
|
253
253
|
return this.#matchResult[0].map(([[, route]]) => route);
|
|
254
254
|
}
|
|
255
255
|
/**
|
|
256
|
-
*
|
|
256
|
+
* `.routePath` can retrieve the path registered within the handler
|
|
257
257
|
*
|
|
258
258
|
* @deprecated
|
|
259
259
|
*
|
|
@@ -175,6 +175,8 @@ var Hono = class Hono {
|
|
|
175
175
|
/**
|
|
176
176
|
* `.mount()` allows you to mount applications built with other frameworks into your Hono application.
|
|
177
177
|
*
|
|
178
|
+
* @deprecated Use `mount()` from `hono/mount` instead. `.mount()` will be removed in v5.
|
|
179
|
+
*
|
|
178
180
|
* @see {@link https://hono.dev/docs/api/hono#mount}
|
|
179
181
|
*
|
|
180
182
|
* @param {string} path - base Path
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { routePath } from "../../helper/route/index.js";
|
|
2
|
+
//#region src/middleware/mount/index.ts
|
|
3
|
+
const defaultReplaceRequest = (c) => {
|
|
4
|
+
const pathPrefix = routePath(c).replace(/\/\*$/, "");
|
|
5
|
+
const url = new URL(c.req.raw.url);
|
|
6
|
+
url.pathname = c.req.path.slice(pathPrefix.length) || "/";
|
|
7
|
+
return new Request(url, c.req.raw);
|
|
8
|
+
};
|
|
9
|
+
const defaultGetOptions = (c) => {
|
|
10
|
+
let executionContext = void 0;
|
|
11
|
+
try {
|
|
12
|
+
executionContext = c.executionCtx;
|
|
13
|
+
} catch {}
|
|
14
|
+
return [c.env, executionContext];
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* `mount()` allows you to mount applications built with other frameworks into your Hono application.
|
|
18
|
+
*
|
|
19
|
+
* @see {@link https://hono.dev/docs/api/hono#mount}
|
|
20
|
+
*
|
|
21
|
+
* @param {Function} applicationHandler - other Request Handler
|
|
22
|
+
* @param {MountOptions} [options] - options of `mount()`
|
|
23
|
+
* @returns {MiddlewareHandler} handler to register with `app.all()`
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```ts
|
|
27
|
+
* import { Router as IttyRouter } from 'itty-router'
|
|
28
|
+
* import { Hono } from 'hono'
|
|
29
|
+
* import { mount } from 'hono/mount'
|
|
30
|
+
* // Create itty-router application
|
|
31
|
+
* const ittyRouter = IttyRouter()
|
|
32
|
+
* // GET /itty-router/hello
|
|
33
|
+
* ittyRouter.get('/hello', () => new Response('Hello from itty-router'))
|
|
34
|
+
*
|
|
35
|
+
* const app = new Hono()
|
|
36
|
+
* app.all('/itty-router/*', mount(ittyRouter.handle))
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```ts
|
|
41
|
+
* const app = new Hono()
|
|
42
|
+
* // Send the request to another application without modification.
|
|
43
|
+
* app.all('/app/*', mount(anotherApp, {
|
|
44
|
+
* replaceRequest: (req) => req,
|
|
45
|
+
* }))
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
const mount = (applicationHandler, options) => {
|
|
49
|
+
let replaceRequest;
|
|
50
|
+
let optionHandler;
|
|
51
|
+
if (options) {
|
|
52
|
+
if (typeof options === "function") optionHandler = options;
|
|
53
|
+
else {
|
|
54
|
+
optionHandler = options.optionHandler;
|
|
55
|
+
if (options.replaceRequest === false) replaceRequest = (request) => request;
|
|
56
|
+
else replaceRequest = options.replaceRequest;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
const getOptions = optionHandler ? (c) => {
|
|
60
|
+
const options = optionHandler(c);
|
|
61
|
+
return Array.isArray(options) ? options : [options];
|
|
62
|
+
} : defaultGetOptions;
|
|
63
|
+
return async (c, next) => {
|
|
64
|
+
const res = await applicationHandler(replaceRequest ? replaceRequest(c.req.raw) : defaultReplaceRequest(c), ...getOptions(c));
|
|
65
|
+
if (res) return res;
|
|
66
|
+
await next();
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
//#endregion
|
|
70
|
+
export { mount };
|
|
@@ -188,7 +188,7 @@ var HonoRequest = class {
|
|
|
188
188
|
return this.#validatedData?.[target];
|
|
189
189
|
}
|
|
190
190
|
/**
|
|
191
|
-
* `.url
|
|
191
|
+
* `.url` can get the request url strings.
|
|
192
192
|
*
|
|
193
193
|
* @see {@link https://hono.dev/docs/api/request#url}
|
|
194
194
|
*
|
|
@@ -204,7 +204,7 @@ var HonoRequest = class {
|
|
|
204
204
|
return this.raw.url;
|
|
205
205
|
}
|
|
206
206
|
/**
|
|
207
|
-
* `.method
|
|
207
|
+
* `.method` can get the method name of the request.
|
|
208
208
|
*
|
|
209
209
|
* @see {@link https://hono.dev/docs/api/request#method}
|
|
210
210
|
*
|
|
@@ -222,7 +222,7 @@ var HonoRequest = class {
|
|
|
222
222
|
return this.#matchResult;
|
|
223
223
|
}
|
|
224
224
|
/**
|
|
225
|
-
* `.matchedRoutes
|
|
225
|
+
* `.matchedRoutes` can return a matched route in the handler
|
|
226
226
|
*
|
|
227
227
|
* @deprecated
|
|
228
228
|
*
|
|
@@ -252,7 +252,7 @@ var HonoRequest = class {
|
|
|
252
252
|
return this.#matchResult[0].map(([[, route]]) => route);
|
|
253
253
|
}
|
|
254
254
|
/**
|
|
255
|
-
*
|
|
255
|
+
* `.routePath` can retrieve the path registered within the handler
|
|
256
256
|
*
|
|
257
257
|
* @deprecated
|
|
258
258
|
*
|
|
@@ -140,6 +140,8 @@ declare class Hono<E extends Env = Env, S extends Schema = {}, BasePath extends
|
|
|
140
140
|
/**
|
|
141
141
|
* `.mount()` allows you to mount applications built with other frameworks into your Hono application.
|
|
142
142
|
*
|
|
143
|
+
* @deprecated Use `mount()` from `hono/mount` instead. `.mount()` will be removed in v5.
|
|
144
|
+
*
|
|
143
145
|
* @see {@link https://hono.dev/docs/api/hono#mount}
|
|
144
146
|
*
|
|
145
147
|
* @param {string} path - base Path
|
|
@@ -4,7 +4,7 @@ import { JSX as JSX$1 } from "./intrinsic-elements.js";
|
|
|
4
4
|
import { Context } from "./context.js";
|
|
5
5
|
//#region src/jsx/base.d.ts
|
|
6
6
|
export type Props = Record<string, any>;
|
|
7
|
-
type FunctionComponentResult = HtmlEscapedString | Child[] | Promise<HtmlEscapedString | Child[]> | null;
|
|
7
|
+
type FunctionComponentResult = HtmlEscapedString | JSXNode | Child[] | Promise<HtmlEscapedString | JSXNode | Child[]> | null;
|
|
8
8
|
export type FC<P = Props> = {
|
|
9
9
|
(props: P): FunctionComponentResult;
|
|
10
10
|
defaultProps?: Partial<P> | undefined;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { MiddlewareHandler } from "../../types.js";
|
|
2
|
+
import { Context } from "../../context.js";
|
|
3
|
+
//#region src/middleware/mount/index.d.ts
|
|
4
|
+
type ApplicationHandler = (request: Request, ...args: any) => Response | Promise<Response>;
|
|
5
|
+
type MountOptionHandler = (c: Context) => unknown;
|
|
6
|
+
type MountReplaceRequest = (originalRequest: Request) => Request;
|
|
7
|
+
type MountOptions = MountOptionHandler | {
|
|
8
|
+
optionHandler?: MountOptionHandler;
|
|
9
|
+
replaceRequest?: MountReplaceRequest | false;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* `mount()` allows you to mount applications built with other frameworks into your Hono application.
|
|
13
|
+
*
|
|
14
|
+
* @see {@link https://hono.dev/docs/api/hono#mount}
|
|
15
|
+
*
|
|
16
|
+
* @param {Function} applicationHandler - other Request Handler
|
|
17
|
+
* @param {MountOptions} [options] - options of `mount()`
|
|
18
|
+
* @returns {MiddlewareHandler} handler to register with `app.all()`
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* import { Router as IttyRouter } from 'itty-router'
|
|
23
|
+
* import { Hono } from 'hono'
|
|
24
|
+
* import { mount } from 'hono/mount'
|
|
25
|
+
* // Create itty-router application
|
|
26
|
+
* const ittyRouter = IttyRouter()
|
|
27
|
+
* // GET /itty-router/hello
|
|
28
|
+
* ittyRouter.get('/hello', () => new Response('Hello from itty-router'))
|
|
29
|
+
*
|
|
30
|
+
* const app = new Hono()
|
|
31
|
+
* app.all('/itty-router/*', mount(ittyRouter.handle))
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```ts
|
|
36
|
+
* const app = new Hono()
|
|
37
|
+
* // Send the request to another application without modification.
|
|
38
|
+
* app.all('/app/*', mount(anotherApp, {
|
|
39
|
+
* replaceRequest: (req) => req,
|
|
40
|
+
* }))
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export declare const mount: (applicationHandler: ApplicationHandler, options?: MountOptions) => MiddlewareHandler;
|
|
44
|
+
//#endregion
|
|
45
|
+
export type { ApplicationHandler, MountOptionHandler, MountOptions, MountReplaceRequest };
|
|
46
|
+
export {};
|
|
@@ -217,7 +217,7 @@ export declare class HonoRequest<P extends string = '/', I extends Input['out']
|
|
|
217
217
|
*/
|
|
218
218
|
valid<T extends keyof I & keyof ValidationTargets>(target: T): InputToDataByTarget<I, T>;
|
|
219
219
|
/**
|
|
220
|
-
* `.url
|
|
220
|
+
* `.url` can get the request url strings.
|
|
221
221
|
*
|
|
222
222
|
* @see {@link https://hono.dev/docs/api/request#url}
|
|
223
223
|
*
|
|
@@ -231,7 +231,7 @@ export declare class HonoRequest<P extends string = '/', I extends Input['out']
|
|
|
231
231
|
*/
|
|
232
232
|
get url(): string;
|
|
233
233
|
/**
|
|
234
|
-
* `.method
|
|
234
|
+
* `.method` can get the method name of the request.
|
|
235
235
|
*
|
|
236
236
|
* @see {@link https://hono.dev/docs/api/request#method}
|
|
237
237
|
*
|
|
@@ -245,7 +245,7 @@ export declare class HonoRequest<P extends string = '/', I extends Input['out']
|
|
|
245
245
|
get method(): string;
|
|
246
246
|
get [GET_MATCH_RESULT](): Result<[unknown, RouterRoute]>;
|
|
247
247
|
/**
|
|
248
|
-
* `.matchedRoutes
|
|
248
|
+
* `.matchedRoutes` can return a matched route in the handler
|
|
249
249
|
*
|
|
250
250
|
* @deprecated
|
|
251
251
|
*
|
|
@@ -273,7 +273,7 @@ export declare class HonoRequest<P extends string = '/', I extends Input['out']
|
|
|
273
273
|
*/
|
|
274
274
|
get matchedRoutes(): RouterRoute[];
|
|
275
275
|
/**
|
|
276
|
-
*
|
|
276
|
+
* `.routePath` can retrieve the path registered within the handler
|
|
277
277
|
*
|
|
278
278
|
* @deprecated
|
|
279
279
|
*
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hono",
|
|
3
|
-
"version": "4.13.
|
|
3
|
+
"version": "4.13.13",
|
|
4
4
|
"description": "Web framework built on Web Standards",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -103,6 +103,11 @@
|
|
|
103
103
|
"import": "./dist/helper/route/index.js",
|
|
104
104
|
"require": "./dist/cjs/helper/route/index.js"
|
|
105
105
|
},
|
|
106
|
+
"./mount": {
|
|
107
|
+
"types": "./dist/types/middleware/mount/index.d.ts",
|
|
108
|
+
"import": "./dist/middleware/mount/index.js",
|
|
109
|
+
"require": "./dist/cjs/middleware/mount/index.js"
|
|
110
|
+
},
|
|
106
111
|
"./cookie": {
|
|
107
112
|
"types": "./dist/types/helper/cookie/index.d.ts",
|
|
108
113
|
"import": "./dist/helper/cookie/index.js",
|
|
@@ -457,6 +462,9 @@
|
|
|
457
462
|
"route": [
|
|
458
463
|
"./dist/types/helper/route"
|
|
459
464
|
],
|
|
465
|
+
"mount": [
|
|
466
|
+
"./dist/types/middleware/mount"
|
|
467
|
+
],
|
|
460
468
|
"cookie": [
|
|
461
469
|
"./dist/types/helper/cookie"
|
|
462
470
|
],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@suveren/gateway",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"description": "Suveren gateway — local agent gateway built in compliance with the Human Agency Protocol (HAP). Runs the UI, control plane, and MCP server in one Node process.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "server.js",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"node": ">=22"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@hap/core": "npm:@humanagencyp/hap-core@^0.
|
|
27
|
+
"@hap/core": "npm:@humanagencyp/hap-core@^0.11.0",
|
|
28
28
|
"@hpke/core": "^1.9.0",
|
|
29
29
|
"express": "^4.18.0",
|
|
30
30
|
"http-proxy-middleware": "^3.0.0",
|
package/profiles/index.json
CHANGED
|
@@ -26,6 +26,8 @@
|
|
|
26
26
|
"github.com/humanagencyprotocol/hap-profiles/sales@0.1": "sales/0.1.profile.json",
|
|
27
27
|
"github.com/humanagencyprotocol/hap-profiles/sales@0.2": "sales/0.2.profile.json",
|
|
28
28
|
"github.com/humanagencyprotocol/hap-profiles/customers@0.8": "customers/0.8.profile.json",
|
|
29
|
-
"github.com/humanagencyprotocol/hap-profiles/email@0.7": "email/0.7.profile.json"
|
|
29
|
+
"github.com/humanagencyprotocol/hap-profiles/email@0.7": "email/0.7.profile.json",
|
|
30
|
+
"github.com/humanagencyprotocol/hap-profiles/sales@0.3": "sales/0.3.profile.json",
|
|
31
|
+
"github.com/humanagencyprotocol/hap-profiles/purchase@0.6": "purchase/0.6.profile.json"
|
|
30
32
|
}
|
|
31
33
|
}
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "github.com/humanagencyprotocol/hap-profiles/purchase@0.6",
|
|
3
|
+
"name": "Purchase",
|
|
4
|
+
"version": "0.6",
|
|
5
|
+
"description": "Purchase authority — governs spending company money: subscriptions, supplies, services, advertising",
|
|
6
|
+
"boundsSchema": {
|
|
7
|
+
"actionTypes": [
|
|
8
|
+
"purchase"
|
|
9
|
+
],
|
|
10
|
+
"keyOrder": [
|
|
11
|
+
"profile",
|
|
12
|
+
"spend_max",
|
|
13
|
+
"spend_daily_max",
|
|
14
|
+
"spend_monthly_max",
|
|
15
|
+
"transaction_count_daily_max"
|
|
16
|
+
],
|
|
17
|
+
"fields": {
|
|
18
|
+
"profile": {
|
|
19
|
+
"type": "string",
|
|
20
|
+
"required": true
|
|
21
|
+
},
|
|
22
|
+
"spend_max": {
|
|
23
|
+
"type": "number",
|
|
24
|
+
"required": true,
|
|
25
|
+
"displayName": "Max per transaction",
|
|
26
|
+
"description": "Maximum spend per transaction in currency units",
|
|
27
|
+
"unit": "currency:EUR",
|
|
28
|
+
"boundType": {
|
|
29
|
+
"kind": "per_transaction",
|
|
30
|
+
"of": "spend",
|
|
31
|
+
"requiredFor": [
|
|
32
|
+
"purchase"
|
|
33
|
+
]
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"spend_daily_max": {
|
|
37
|
+
"type": "number",
|
|
38
|
+
"required": true,
|
|
39
|
+
"displayName": "Daily spend limit",
|
|
40
|
+
"description": "Maximum cumulative spend per day in currency units",
|
|
41
|
+
"unit": "currency:EUR",
|
|
42
|
+
"boundType": {
|
|
43
|
+
"kind": "cumulative_sum",
|
|
44
|
+
"of": "spend",
|
|
45
|
+
"window": "daily"
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
"spend_monthly_max": {
|
|
49
|
+
"type": "number",
|
|
50
|
+
"required": true,
|
|
51
|
+
"displayName": "Monthly spend limit",
|
|
52
|
+
"description": "Maximum cumulative spend per month in currency units",
|
|
53
|
+
"unit": "currency:EUR",
|
|
54
|
+
"boundType": {
|
|
55
|
+
"kind": "cumulative_sum",
|
|
56
|
+
"of": "spend",
|
|
57
|
+
"window": "monthly"
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
"transaction_count_daily_max": {
|
|
61
|
+
"type": "number",
|
|
62
|
+
"required": true,
|
|
63
|
+
"displayName": "Daily transaction limit",
|
|
64
|
+
"description": "Maximum number of purchase transactions per day",
|
|
65
|
+
"unit": "count",
|
|
66
|
+
"boundType": {
|
|
67
|
+
"kind": "cumulative_count",
|
|
68
|
+
"window": "daily"
|
|
69
|
+
},
|
|
70
|
+
"appliesTo": [
|
|
71
|
+
"purchase"
|
|
72
|
+
]
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
"contextSchema": {
|
|
77
|
+
"keyOrder": [
|
|
78
|
+
"currency",
|
|
79
|
+
"category",
|
|
80
|
+
"allowed_vendors"
|
|
81
|
+
],
|
|
82
|
+
"fields": {
|
|
83
|
+
"currency": {
|
|
84
|
+
"type": "string",
|
|
85
|
+
"required": true,
|
|
86
|
+
"displayName": "Currency",
|
|
87
|
+
"description": "Permitted currency code",
|
|
88
|
+
"constraint": {
|
|
89
|
+
"type": "string",
|
|
90
|
+
"enforceable": [
|
|
91
|
+
"enum"
|
|
92
|
+
]
|
|
93
|
+
},
|
|
94
|
+
"enum": [
|
|
95
|
+
"USD",
|
|
96
|
+
"EUR",
|
|
97
|
+
"GBP",
|
|
98
|
+
"CHF",
|
|
99
|
+
"JPY",
|
|
100
|
+
"CAD",
|
|
101
|
+
"AUD"
|
|
102
|
+
]
|
|
103
|
+
},
|
|
104
|
+
"category": {
|
|
105
|
+
"type": "string",
|
|
106
|
+
"required": true,
|
|
107
|
+
"displayName": "Purchase category",
|
|
108
|
+
"description": "Authorized purchase category",
|
|
109
|
+
"constraint": {
|
|
110
|
+
"type": "string",
|
|
111
|
+
"enforceable": [
|
|
112
|
+
"enum"
|
|
113
|
+
]
|
|
114
|
+
},
|
|
115
|
+
"enum": [
|
|
116
|
+
"subscription",
|
|
117
|
+
"supply",
|
|
118
|
+
"service",
|
|
119
|
+
"advertising"
|
|
120
|
+
]
|
|
121
|
+
},
|
|
122
|
+
"allowed_vendors": {
|
|
123
|
+
"type": "string",
|
|
124
|
+
"required": false,
|
|
125
|
+
"displayName": "Allowed vendors",
|
|
126
|
+
"description": "Comma-separated list of approved vendor names",
|
|
127
|
+
"constraint": {
|
|
128
|
+
"type": "string",
|
|
129
|
+
"enforceable": [
|
|
130
|
+
"subset"
|
|
131
|
+
]
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
"executionContextSchema": {
|
|
137
|
+
"fields": {
|
|
138
|
+
"spend": {
|
|
139
|
+
"source": "declared",
|
|
140
|
+
"description": "Purchase amount in currency units",
|
|
141
|
+
"required": true,
|
|
142
|
+
"constraint": {
|
|
143
|
+
"type": "number",
|
|
144
|
+
"enforceable": [
|
|
145
|
+
"max"
|
|
146
|
+
]
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
"currency": {
|
|
150
|
+
"source": "declared",
|
|
151
|
+
"description": "Currency code",
|
|
152
|
+
"required": true,
|
|
153
|
+
"constraint": {
|
|
154
|
+
"type": "string",
|
|
155
|
+
"enforceable": [
|
|
156
|
+
"enum"
|
|
157
|
+
]
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
"category": {
|
|
161
|
+
"source": "declared",
|
|
162
|
+
"description": "Purchase category",
|
|
163
|
+
"required": true,
|
|
164
|
+
"constraint": {
|
|
165
|
+
"type": "string",
|
|
166
|
+
"enforceable": [
|
|
167
|
+
"enum"
|
|
168
|
+
]
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
"allowed_vendors": {
|
|
172
|
+
"source": "declared",
|
|
173
|
+
"description": "Vendor name for this purchase (checked against approved list)",
|
|
174
|
+
"required": false,
|
|
175
|
+
"constraint": {
|
|
176
|
+
"type": "string",
|
|
177
|
+
"enforceable": [
|
|
178
|
+
"subset"
|
|
179
|
+
]
|
|
180
|
+
}
|
|
181
|
+
},
|
|
182
|
+
"spend_daily": {
|
|
183
|
+
"source": "cumulative",
|
|
184
|
+
"cumulativeField": "spend",
|
|
185
|
+
"window": "daily",
|
|
186
|
+
"description": "Running daily spend total (resolved from execution log)",
|
|
187
|
+
"required": true,
|
|
188
|
+
"constraint": {
|
|
189
|
+
"type": "number",
|
|
190
|
+
"enforceable": [
|
|
191
|
+
"max"
|
|
192
|
+
]
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
"spend_monthly": {
|
|
196
|
+
"source": "cumulative",
|
|
197
|
+
"cumulativeField": "spend",
|
|
198
|
+
"window": "monthly",
|
|
199
|
+
"description": "Running monthly spend total (resolved from execution log)",
|
|
200
|
+
"required": true,
|
|
201
|
+
"constraint": {
|
|
202
|
+
"type": "number",
|
|
203
|
+
"enforceable": [
|
|
204
|
+
"max"
|
|
205
|
+
]
|
|
206
|
+
}
|
|
207
|
+
},
|
|
208
|
+
"transaction_count_daily": {
|
|
209
|
+
"source": "cumulative",
|
|
210
|
+
"cumulativeField": "_count",
|
|
211
|
+
"window": "daily",
|
|
212
|
+
"description": "Running daily transaction count (resolved from execution log)",
|
|
213
|
+
"required": true,
|
|
214
|
+
"constraint": {
|
|
215
|
+
"type": "number",
|
|
216
|
+
"enforceable": [
|
|
217
|
+
"max"
|
|
218
|
+
]
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
},
|
|
223
|
+
"requiredGates": [
|
|
224
|
+
"bounds",
|
|
225
|
+
"intent",
|
|
226
|
+
"commitment",
|
|
227
|
+
"decision_owner"
|
|
228
|
+
],
|
|
229
|
+
"ttl": {
|
|
230
|
+
"default": 86400,
|
|
231
|
+
"max": 2592000
|
|
232
|
+
},
|
|
233
|
+
"retention_minimum": 7776000
|
|
234
|
+
}
|