@lerianstudio/matcher-mcp 1.0.0-beta.5
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/LICENSE +202 -0
- package/README.md +281 -0
- package/dist/auth/request-token.js +117 -0
- package/dist/auth/request-token.js.map +1 -0
- package/dist/config.js +95 -0
- package/dist/config.js.map +1 -0
- package/dist/matcher/client.js +168 -0
- package/dist/matcher/client.js.map +1 -0
- package/dist/observability/otel.js +223 -0
- package/dist/observability/otel.js.map +1 -0
- package/dist/server.js +245 -0
- package/dist/server.js.map +1 -0
- package/dist/spec/curated-operations.js +145 -0
- package/dist/spec/curated-operations.js.map +1 -0
- package/dist/spec/index.js +155 -0
- package/dist/spec/index.js.map +1 -0
- package/dist/spec/load.js +76 -0
- package/dist/spec/load.js.map +1 -0
- package/dist/spec/openapi.yaml +15217 -0
- package/dist/tools/context/create.js +100 -0
- package/dist/tools/context/create.js.map +1 -0
- package/dist/tools/context/get.js +31 -0
- package/dist/tools/context/get.js.map +1 -0
- package/dist/tools/context/index.js +21 -0
- package/dist/tools/context/index.js.map +1 -0
- package/dist/tools/context/list.js +78 -0
- package/dist/tools/context/list.js.map +1 -0
- package/dist/tools/context/shared.js +61 -0
- package/dist/tools/context/shared.js.map +1 -0
- package/dist/tools/context/update.js +105 -0
- package/dist/tools/context/update.js.map +1 -0
- package/dist/tools/dashboard/aggregates.js +34 -0
- package/dist/tools/dashboard/aggregates.js.map +1 -0
- package/dist/tools/dashboard/cash-impact.js +36 -0
- package/dist/tools/dashboard/cash-impact.js.map +1 -0
- package/dist/tools/dashboard/index.js +27 -0
- package/dist/tools/dashboard/index.js.map +1 -0
- package/dist/tools/dashboard/match-rate.js +35 -0
- package/dist/tools/dashboard/match-rate.js.map +1 -0
- package/dist/tools/dashboard/metrics.js +36 -0
- package/dist/tools/dashboard/metrics.js.map +1 -0
- package/dist/tools/dashboard/shared.js +122 -0
- package/dist/tools/dashboard/shared.js.map +1 -0
- package/dist/tools/dashboard/sla.js +33 -0
- package/dist/tools/dashboard/sla.js.map +1 -0
- package/dist/tools/dashboard/source-breakdown.js +36 -0
- package/dist/tools/dashboard/source-breakdown.js.map +1 -0
- package/dist/tools/dashboard/volume.js +35 -0
- package/dist/tools/dashboard/volume.js.map +1 -0
- package/dist/tools/dispute/close.js +49 -0
- package/dist/tools/dispute/close.js.map +1 -0
- package/dist/tools/dispute/get.js +27 -0
- package/dist/tools/dispute/get.js.map +1 -0
- package/dist/tools/dispute/index.js +17 -0
- package/dist/tools/dispute/index.js.map +1 -0
- package/dist/tools/dispute/list.js +137 -0
- package/dist/tools/dispute/list.js.map +1 -0
- package/dist/tools/dispute/shared.js +66 -0
- package/dist/tools/dispute/shared.js.map +1 -0
- package/dist/tools/dispute/submit-evidence.js +58 -0
- package/dist/tools/dispute/submit-evidence.js.map +1 -0
- package/dist/tools/exception/add-comment.js +50 -0
- package/dist/tools/exception/add-comment.js.map +1 -0
- package/dist/tools/exception/adjust-entry.js +71 -0
- package/dist/tools/exception/adjust-entry.js.map +1 -0
- package/dist/tools/exception/bulk-assign.js +47 -0
- package/dist/tools/exception/bulk-assign.js.map +1 -0
- package/dist/tools/exception/bulk-dispatch.js +69 -0
- package/dist/tools/exception/bulk-dispatch.js.map +1 -0
- package/dist/tools/exception/bulk-resolve.js +64 -0
- package/dist/tools/exception/bulk-resolve.js.map +1 -0
- package/dist/tools/exception/delete-comment.js +40 -0
- package/dist/tools/exception/delete-comment.js.map +1 -0
- package/dist/tools/exception/dispatch.js +64 -0
- package/dist/tools/exception/dispatch.js.map +1 -0
- package/dist/tools/exception/force-match.js +55 -0
- package/dist/tools/exception/force-match.js.map +1 -0
- package/dist/tools/exception/get.js +34 -0
- package/dist/tools/exception/get.js.map +1 -0
- package/dist/tools/exception/history.js +61 -0
- package/dist/tools/exception/history.js.map +1 -0
- package/dist/tools/exception/index.js +39 -0
- package/dist/tools/exception/index.js.map +1 -0
- package/dist/tools/exception/list-comments.js +35 -0
- package/dist/tools/exception/list-comments.js.map +1 -0
- package/dist/tools/exception/list.js +169 -0
- package/dist/tools/exception/list.js.map +1 -0
- package/dist/tools/exception/open-dispute.js +53 -0
- package/dist/tools/exception/open-dispute.js.map +1 -0
- package/dist/tools/exception/shared.js +98 -0
- package/dist/tools/exception/shared.js.map +1 -0
- package/dist/tools/fee-rule/create.js +106 -0
- package/dist/tools/fee-rule/create.js.map +1 -0
- package/dist/tools/fee-rule/delete.js +27 -0
- package/dist/tools/fee-rule/delete.js.map +1 -0
- package/dist/tools/fee-rule/get.js +27 -0
- package/dist/tools/fee-rule/get.js.map +1 -0
- package/dist/tools/fee-rule/index.js +21 -0
- package/dist/tools/fee-rule/index.js.map +1 -0
- package/dist/tools/fee-rule/list.js +64 -0
- package/dist/tools/fee-rule/list.js.map +1 -0
- package/dist/tools/fee-rule/shared.js +67 -0
- package/dist/tools/fee-rule/shared.js.map +1 -0
- package/dist/tools/fee-rule/update.js +70 -0
- package/dist/tools/fee-rule/update.js.map +1 -0
- package/dist/tools/fee-schedule/create.js +105 -0
- package/dist/tools/fee-schedule/create.js.map +1 -0
- package/dist/tools/fee-schedule/delete.js +32 -0
- package/dist/tools/fee-schedule/delete.js.map +1 -0
- package/dist/tools/fee-schedule/get.js +30 -0
- package/dist/tools/fee-schedule/get.js.map +1 -0
- package/dist/tools/fee-schedule/index.js +22 -0
- package/dist/tools/fee-schedule/index.js.map +1 -0
- package/dist/tools/fee-schedule/list.js +56 -0
- package/dist/tools/fee-schedule/list.js.map +1 -0
- package/dist/tools/fee-schedule/shared.js +58 -0
- package/dist/tools/fee-schedule/shared.js.map +1 -0
- package/dist/tools/fee-schedule/simulate.js +54 -0
- package/dist/tools/fee-schedule/simulate.js.map +1 -0
- package/dist/tools/fee-schedule/update.js +69 -0
- package/dist/tools/fee-schedule/update.js.map +1 -0
- package/dist/tools/generic/describe-operation.js +157 -0
- package/dist/tools/generic/describe-operation.js.map +1 -0
- package/dist/tools/generic/invoke.js +343 -0
- package/dist/tools/generic/invoke.js.map +1 -0
- package/dist/tools/generic/list-operations.js +73 -0
- package/dist/tools/generic/list-operations.js.map +1 -0
- package/dist/tools/ingestion/index.js +29 -0
- package/dist/tools/ingestion/index.js.map +1 -0
- package/dist/tools/ingestion/job-errors-list.js +45 -0
- package/dist/tools/ingestion/job-errors-list.js.map +1 -0
- package/dist/tools/ingestion/job-get.js +42 -0
- package/dist/tools/ingestion/job-get.js.map +1 -0
- package/dist/tools/ingestion/job-transactions-list.js +93 -0
- package/dist/tools/ingestion/job-transactions-list.js.map +1 -0
- package/dist/tools/ingestion/jobs-list.js +89 -0
- package/dist/tools/ingestion/jobs-list.js.map +1 -0
- package/dist/tools/ingestion/shared.js +84 -0
- package/dist/tools/ingestion/shared.js.map +1 -0
- package/dist/tools/ingestion/transaction-ignore.js +51 -0
- package/dist/tools/ingestion/transaction-ignore.js.map +1 -0
- package/dist/tools/ingestion/transactions-search.js +143 -0
- package/dist/tools/ingestion/transactions-search.js.map +1 -0
- package/dist/tools/match-rule/create.js +64 -0
- package/dist/tools/match-rule/create.js.map +1 -0
- package/dist/tools/match-rule/delete.js +35 -0
- package/dist/tools/match-rule/delete.js.map +1 -0
- package/dist/tools/match-rule/get.js +32 -0
- package/dist/tools/match-rule/get.js.map +1 -0
- package/dist/tools/match-rule/index.js +22 -0
- package/dist/tools/match-rule/index.js.map +1 -0
- package/dist/tools/match-rule/list.js +72 -0
- package/dist/tools/match-rule/list.js.map +1 -0
- package/dist/tools/match-rule/reorder.js +45 -0
- package/dist/tools/match-rule/reorder.js.map +1 -0
- package/dist/tools/match-rule/shared.js +71 -0
- package/dist/tools/match-rule/shared.js.map +1 -0
- package/dist/tools/match-rule/update.js +68 -0
- package/dist/tools/match-rule/update.js.map +1 -0
- package/dist/tools/matching/get.js +48 -0
- package/dist/tools/matching/get.js.map +1 -0
- package/dist/tools/matching/groups.js +98 -0
- package/dist/tools/matching/groups.js.map +1 -0
- package/dist/tools/matching/index.js +19 -0
- package/dist/tools/matching/index.js.map +1 -0
- package/dist/tools/matching/list.js +76 -0
- package/dist/tools/matching/list.js.map +1 -0
- package/dist/tools/matching/shared.js +77 -0
- package/dist/tools/matching/shared.js.map +1 -0
- package/dist/tools/matching/start.js +55 -0
- package/dist/tools/matching/start.js.map +1 -0
- package/dist/tools/report/count-exceptions.js +45 -0
- package/dist/tools/report/count-exceptions.js.map +1 -0
- package/dist/tools/report/count-matched.js +46 -0
- package/dist/tools/report/count-matched.js.map +1 -0
- package/dist/tools/report/count-transactions.js +44 -0
- package/dist/tools/report/count-transactions.js.map +1 -0
- package/dist/tools/report/count-unmatched.js +44 -0
- package/dist/tools/report/count-unmatched.js.map +1 -0
- package/dist/tools/report/export-exceptions.js +46 -0
- package/dist/tools/report/export-exceptions.js.map +1 -0
- package/dist/tools/report/export-matched.js +47 -0
- package/dist/tools/report/export-matched.js.map +1 -0
- package/dist/tools/report/export-summary.js +47 -0
- package/dist/tools/report/export-summary.js.map +1 -0
- package/dist/tools/report/export-unmatched.js +47 -0
- package/dist/tools/report/export-unmatched.js.map +1 -0
- package/dist/tools/report/export-variance.js +46 -0
- package/dist/tools/report/export-variance.js.map +1 -0
- package/dist/tools/report/index.js +40 -0
- package/dist/tools/report/index.js.map +1 -0
- package/dist/tools/report/matched.js +44 -0
- package/dist/tools/report/matched.js.map +1 -0
- package/dist/tools/report/shared.js +176 -0
- package/dist/tools/report/shared.js.map +1 -0
- package/dist/tools/report/summary.js +41 -0
- package/dist/tools/report/summary.js.map +1 -0
- package/dist/tools/report/unmatched.js +44 -0
- package/dist/tools/report/unmatched.js.map +1 -0
- package/dist/tools/report/variance.js +44 -0
- package/dist/tools/report/variance.js.map +1 -0
- package/dist/tools/source/create.js +84 -0
- package/dist/tools/source/create.js.map +1 -0
- package/dist/tools/source/get.js +41 -0
- package/dist/tools/source/get.js.map +1 -0
- package/dist/tools/source/index.js +22 -0
- package/dist/tools/source/index.js.map +1 -0
- package/dist/tools/source/list.js +72 -0
- package/dist/tools/source/list.js.map +1 -0
- package/dist/tools/source/shared.js +63 -0
- package/dist/tools/source/shared.js.map +1 -0
- package/dist/tools/source/update.js +73 -0
- package/dist/tools/source/update.js.map +1 -0
- package/dist/tools/tool-error.js +74 -0
- package/dist/tools/tool-error.js.map +1 -0
- package/dist/transport/body-limit.js +82 -0
- package/dist/transport/body-limit.js.map +1 -0
- package/dist/transport/http.js +154 -0
- package/dist/transport/http.js.map +1 -0
- package/package.json +68 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// Curated exception vertical: thirteen typed tools over the matcher
|
|
2
|
+
// reconciliation-exception resource — list/get, the history + comments
|
|
3
|
+
// sub-resources (list/add/delete), the per-exception action verbs (dispatch,
|
|
4
|
+
// open-dispute, force-match, adjust-entry), and the cross-exception bulk
|
|
5
|
+
// actions (assign/resolve/dispatch). Every tool shares the fail-closed relay
|
|
6
|
+
// (shared.ts) and the RFC 9457 → tool-error mapping (toToolError) with the
|
|
7
|
+
// generic surface, so curated and generic map matcher errors identically. No
|
|
8
|
+
// tool carries a tenant field; the optional contextId on list is a routing
|
|
9
|
+
// filter matcher validates against the relayed token's tenant.
|
|
10
|
+
import { registerExceptionAddCommentTool } from './add-comment.js';
|
|
11
|
+
import { registerExceptionAdjustEntryTool } from './adjust-entry.js';
|
|
12
|
+
import { registerExceptionBulkAssignTool } from './bulk-assign.js';
|
|
13
|
+
import { registerExceptionBulkDispatchTool } from './bulk-dispatch.js';
|
|
14
|
+
import { registerExceptionBulkResolveTool } from './bulk-resolve.js';
|
|
15
|
+
import { registerExceptionDeleteCommentTool } from './delete-comment.js';
|
|
16
|
+
import { registerExceptionDispatchTool } from './dispatch.js';
|
|
17
|
+
import { registerExceptionForceMatchTool } from './force-match.js';
|
|
18
|
+
import { registerExceptionGetTool } from './get.js';
|
|
19
|
+
import { registerExceptionHistoryTool } from './history.js';
|
|
20
|
+
import { registerExceptionListTool } from './list.js';
|
|
21
|
+
import { registerExceptionListCommentsTool } from './list-comments.js';
|
|
22
|
+
import { registerExceptionOpenDisputeTool } from './open-dispute.js';
|
|
23
|
+
/** Register all thirteen curated exception tools on the given server. */
|
|
24
|
+
export function registerExceptionTools(server) {
|
|
25
|
+
registerExceptionListTool(server);
|
|
26
|
+
registerExceptionGetTool(server);
|
|
27
|
+
registerExceptionHistoryTool(server);
|
|
28
|
+
registerExceptionListCommentsTool(server);
|
|
29
|
+
registerExceptionAddCommentTool(server);
|
|
30
|
+
registerExceptionDeleteCommentTool(server);
|
|
31
|
+
registerExceptionDispatchTool(server);
|
|
32
|
+
registerExceptionOpenDisputeTool(server);
|
|
33
|
+
registerExceptionForceMatchTool(server);
|
|
34
|
+
registerExceptionAdjustEntryTool(server);
|
|
35
|
+
registerExceptionBulkAssignTool(server);
|
|
36
|
+
registerExceptionBulkResolveTool(server);
|
|
37
|
+
registerExceptionBulkDispatchTool(server);
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/exception/index.ts"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,uEAAuE;AACvE,6EAA6E;AAC7E,yEAAyE;AACzE,6EAA6E;AAC7E,2EAA2E;AAC3E,6EAA6E;AAC7E,2EAA2E;AAC3E,+DAA+D;AAI/D,OAAO,EAAE,+BAA+B,EAAE,MAAM,kBAAkB,CAAA;AAClE,OAAO,EAAE,gCAAgC,EAAE,MAAM,mBAAmB,CAAA;AACpE,OAAO,EAAE,+BAA+B,EAAE,MAAM,kBAAkB,CAAA;AAClE,OAAO,EAAE,iCAAiC,EAAE,MAAM,oBAAoB,CAAA;AACtE,OAAO,EAAE,gCAAgC,EAAE,MAAM,mBAAmB,CAAA;AACpE,OAAO,EAAE,kCAAkC,EAAE,MAAM,qBAAqB,CAAA;AACxE,OAAO,EAAE,6BAA6B,EAAE,MAAM,eAAe,CAAA;AAC7D,OAAO,EAAE,+BAA+B,EAAE,MAAM,kBAAkB,CAAA;AAClE,OAAO,EAAE,wBAAwB,EAAE,MAAM,UAAU,CAAA;AACnD,OAAO,EAAE,4BAA4B,EAAE,MAAM,cAAc,CAAA;AAC3D,OAAO,EAAE,yBAAyB,EAAE,MAAM,WAAW,CAAA;AACrD,OAAO,EAAE,iCAAiC,EAAE,MAAM,oBAAoB,CAAA;AACtE,OAAO,EAAE,gCAAgC,EAAE,MAAM,mBAAmB,CAAA;AAEpE,yEAAyE;AACzE,MAAM,UAAU,sBAAsB,CAAC,MAAiB;IACtD,yBAAyB,CAAC,MAAM,CAAC,CAAA;IACjC,wBAAwB,CAAC,MAAM,CAAC,CAAA;IAChC,4BAA4B,CAAC,MAAM,CAAC,CAAA;IACpC,iCAAiC,CAAC,MAAM,CAAC,CAAA;IACzC,+BAA+B,CAAC,MAAM,CAAC,CAAA;IACvC,kCAAkC,CAAC,MAAM,CAAC,CAAA;IAC1C,6BAA6B,CAAC,MAAM,CAAC,CAAA;IACrC,gCAAgC,CAAC,MAAM,CAAC,CAAA;IACxC,+BAA+B,CAAC,MAAM,CAAC,CAAA;IACvC,gCAAgC,CAAC,MAAM,CAAC,CAAA;IACxC,+BAA+B,CAAC,MAAM,CAAC,CAAA;IACvC,gCAAgC,CAAC,MAAM,CAAC,CAAA;IACxC,iCAAiC,CAAC,MAAM,CAAC,CAAA;AAC3C,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// `exception_list_comments` — curated GET /v1/exceptions/{exceptionId}/comments.
|
|
2
|
+
//
|
|
3
|
+
// Returns every discussion comment on one exception, ordered oldest-first. No
|
|
4
|
+
// query params (matcher returns the full list). exceptionId is a path param;
|
|
5
|
+
// the exception must belong to the relayed token's tenant, and no tenant field
|
|
6
|
+
// is accepted.
|
|
7
|
+
import { z } from 'zod';
|
|
8
|
+
import { dispatchException, exceptionCommentsPath } from './shared.js';
|
|
9
|
+
/** Zod raw shape for `exception_list_comments` input — the exception path id. */
|
|
10
|
+
export const listCommentsInputShape = {
|
|
11
|
+
exceptionId: z
|
|
12
|
+
.string()
|
|
13
|
+
.min(1)
|
|
14
|
+
.describe('The exception id (UUID) whose comments to list.'),
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Register `exception_list_comments`. Substitutes the id into the path and
|
|
18
|
+
* dispatches a GET through the shared fail-closed relay; a matcher error
|
|
19
|
+
* surfaces via the shared toToolError.
|
|
20
|
+
*/
|
|
21
|
+
export function registerExceptionListCommentsTool(server) {
|
|
22
|
+
server.registerTool('exception_list_comments', {
|
|
23
|
+
description: 'List the discussion comments on a reconciliation exception, ordered ' +
|
|
24
|
+
'oldest-first. Provide exceptionId (UUID). The exception must belong to ' +
|
|
25
|
+
"your token's tenant (no tenant field is accepted). Returns the comments, " +
|
|
26
|
+
'or a structured RFC 9457 error.',
|
|
27
|
+
inputSchema: listCommentsInputShape,
|
|
28
|
+
}, async (args, extra) => {
|
|
29
|
+
return dispatchException({
|
|
30
|
+
method: 'GET',
|
|
31
|
+
path: exceptionCommentsPath(args.exceptionId),
|
|
32
|
+
}, extra);
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=list-comments.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-comments.js","sourceRoot":"","sources":["../../../src/tools/exception/list-comments.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,EAAE;AACF,8EAA8E;AAC9E,6EAA6E;AAC7E,+EAA+E;AAC/E,eAAe;AAEf,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AAEtE,iFAAiF;AACjF,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,WAAW,EAAE,CAAC;SACX,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,CAAC,iDAAiD,CAAC;CAC/D,CAAA;AAOD;;;;GAIG;AACH,MAAM,UAAU,iCAAiC,CAAC,MAAiB;IACjE,MAAM,CAAC,YAAY,CACjB,yBAAyB,EACzB;QACE,WAAW,EACT,sEAAsE;YACtE,yEAAyE;YACzE,2EAA2E;YAC3E,iCAAiC;QACnC,WAAW,EAAE,sBAAsB;KACpC,EACD,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;QACpB,OAAO,iBAAiB,CACtB;YACE,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,qBAAqB,CAAC,IAAI,CAAC,WAAW,CAAC;SAC9C,EACD,KAAK,CACN,CAAA;IACH,CAAC,CACF,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
// `exception_list` — curated GET /v1/exceptions.
|
|
2
|
+
//
|
|
3
|
+
// Cursor-paginated list of the tenant's reconciliation exceptions, with the
|
|
4
|
+
// spec's rich filter set (contextId, status, severity, reason, assigned_to,
|
|
5
|
+
// external_system, date_from, date_to) plus sort/pagination knobs. Filters pass
|
|
6
|
+
// through untouched and matcher's { items, nextCursor, ... } envelope is
|
|
7
|
+
// returned as-is — no auto-pagination (the model re-calls with the returned
|
|
8
|
+
// cursor). The list is implicitly tenant-scoped by the relayed token; contextId
|
|
9
|
+
// is a routing filter, not a tenant field, and no tenant field is accepted.
|
|
10
|
+
import { z } from 'zod';
|
|
11
|
+
import { dispatchException, EXCEPTIONS_PATH } from './shared.js';
|
|
12
|
+
/** Lifecycle states an exception can be filtered by (matcher's queue states). */
|
|
13
|
+
export const EXCEPTION_STATUSES = ['OPEN', 'ASSIGNED', 'RESOLVED'];
|
|
14
|
+
/** Severity buckets an exception can be filtered by. */
|
|
15
|
+
export const EXCEPTION_SEVERITIES = ['LOW', 'MEDIUM', 'HIGH', 'CRITICAL'];
|
|
16
|
+
/** The reason an exception was raised (the matching defect that produced it). */
|
|
17
|
+
export const EXCEPTION_REASONS = [
|
|
18
|
+
'UNMATCHED',
|
|
19
|
+
'FX_RATE_UNAVAILABLE',
|
|
20
|
+
'MISSING_BASE_AMOUNT',
|
|
21
|
+
'MISSING_BASE_CURRENCY',
|
|
22
|
+
'SPLIT_INCOMPLETE',
|
|
23
|
+
'VALIDATION_FAILED',
|
|
24
|
+
'SOURCE_MISMATCH',
|
|
25
|
+
'DUPLICATE_TRANSACTION',
|
|
26
|
+
'FEE_VARIANCE',
|
|
27
|
+
'FEE_DATA_MISSING',
|
|
28
|
+
'FEE_CURRENCY_MISMATCH',
|
|
29
|
+
'FX_RATE_VARIANCE',
|
|
30
|
+
'AGED_BREAK',
|
|
31
|
+
'OVER_SETTLED',
|
|
32
|
+
];
|
|
33
|
+
/** Sortable columns (default queue ordering applies when both sort knobs are omitted). */
|
|
34
|
+
export const EXCEPTION_SORT_BY = [
|
|
35
|
+
'id',
|
|
36
|
+
'created_at',
|
|
37
|
+
'updated_at',
|
|
38
|
+
'severity',
|
|
39
|
+
'status',
|
|
40
|
+
];
|
|
41
|
+
/** Sort direction for the explicit single-column sort. */
|
|
42
|
+
export const EXCEPTION_SORT_ORDER = ['asc', 'desc'];
|
|
43
|
+
/** Zod raw shape for `exception_list` input — filters + sort + pagination. */
|
|
44
|
+
export const listExceptionsInputShape = {
|
|
45
|
+
contextId: z
|
|
46
|
+
.string()
|
|
47
|
+
.min(1)
|
|
48
|
+
.optional()
|
|
49
|
+
.describe('Filter by reconciliation context id (UUID), verified against your ' +
|
|
50
|
+
"token's tenant. Routing filter, not a tenant field."),
|
|
51
|
+
status: z
|
|
52
|
+
.enum(EXCEPTION_STATUSES)
|
|
53
|
+
.optional()
|
|
54
|
+
.describe('Filter by lifecycle status (OPEN|ASSIGNED|RESOLVED).'),
|
|
55
|
+
severity: z
|
|
56
|
+
.enum(EXCEPTION_SEVERITIES)
|
|
57
|
+
.optional()
|
|
58
|
+
.describe('Filter by severity (LOW|MEDIUM|HIGH|CRITICAL).'),
|
|
59
|
+
reason: z
|
|
60
|
+
.enum(EXCEPTION_REASONS)
|
|
61
|
+
.optional()
|
|
62
|
+
.describe('Filter by the reason the exception was raised (e.g. UNMATCHED, ' +
|
|
63
|
+
'FEE_VARIANCE, DUPLICATE_TRANSACTION).'),
|
|
64
|
+
assigned_to: z
|
|
65
|
+
.string()
|
|
66
|
+
.optional()
|
|
67
|
+
.describe('Filter by assigned user (e.g. "user@example.com").'),
|
|
68
|
+
external_system: z
|
|
69
|
+
.string()
|
|
70
|
+
.optional()
|
|
71
|
+
.describe('Filter by external system the exception was dispatched to (e.g. "JIRA").'),
|
|
72
|
+
date_from: z
|
|
73
|
+
.string()
|
|
74
|
+
.optional()
|
|
75
|
+
.describe('Inclusive lower bound as an RFC 3339 timestamp (e.g. "2025-01-01T00:00:00Z").'),
|
|
76
|
+
date_to: z
|
|
77
|
+
.string()
|
|
78
|
+
.optional()
|
|
79
|
+
.describe('Inclusive upper bound as an RFC 3339 timestamp (e.g. "2025-01-31T23:59:59Z").'),
|
|
80
|
+
cursor: z
|
|
81
|
+
.string()
|
|
82
|
+
.optional()
|
|
83
|
+
.describe('Opaque pagination cursor from a prior response. Re-call with the ' +
|
|
84
|
+
'returned nextCursor to page forward (there is no auto-pagination). ' +
|
|
85
|
+
'Cursors are bound to the ordering that minted them — do not switch ' +
|
|
86
|
+
'sort_by/sort_order mid-pagination.'),
|
|
87
|
+
limit: z
|
|
88
|
+
.number()
|
|
89
|
+
.int()
|
|
90
|
+
.min(1)
|
|
91
|
+
.max(200)
|
|
92
|
+
.optional()
|
|
93
|
+
.describe('Maximum number of records to return (1–200, default 20).'),
|
|
94
|
+
sort_by: z
|
|
95
|
+
.enum(EXCEPTION_SORT_BY)
|
|
96
|
+
.optional()
|
|
97
|
+
.describe('Sort field (id|created_at|updated_at|severity|status). Omit both sort ' +
|
|
98
|
+
'knobs for the default queue ordering (status ASC, then created_at DESC).'),
|
|
99
|
+
sort_order: z
|
|
100
|
+
.enum(EXCEPTION_SORT_ORDER)
|
|
101
|
+
.optional()
|
|
102
|
+
.describe('Sort direction (asc|desc) for the explicit single-column sort.'),
|
|
103
|
+
};
|
|
104
|
+
/** Build the list query, omitting unset knobs so the request stays minimal. */
|
|
105
|
+
export function buildListQuery(args) {
|
|
106
|
+
const query = {};
|
|
107
|
+
if (args.contextId !== undefined) {
|
|
108
|
+
query.contextId = args.contextId;
|
|
109
|
+
}
|
|
110
|
+
if (args.status !== undefined) {
|
|
111
|
+
query.status = args.status;
|
|
112
|
+
}
|
|
113
|
+
if (args.severity !== undefined) {
|
|
114
|
+
query.severity = args.severity;
|
|
115
|
+
}
|
|
116
|
+
if (args.reason !== undefined) {
|
|
117
|
+
query.reason = args.reason;
|
|
118
|
+
}
|
|
119
|
+
if (args.assigned_to !== undefined) {
|
|
120
|
+
query.assigned_to = args.assigned_to;
|
|
121
|
+
}
|
|
122
|
+
if (args.external_system !== undefined) {
|
|
123
|
+
query.external_system = args.external_system;
|
|
124
|
+
}
|
|
125
|
+
if (args.date_from !== undefined) {
|
|
126
|
+
query.date_from = args.date_from;
|
|
127
|
+
}
|
|
128
|
+
if (args.date_to !== undefined) {
|
|
129
|
+
query.date_to = args.date_to;
|
|
130
|
+
}
|
|
131
|
+
if (args.cursor !== undefined) {
|
|
132
|
+
query.cursor = args.cursor;
|
|
133
|
+
}
|
|
134
|
+
if (args.limit !== undefined) {
|
|
135
|
+
query.limit = args.limit;
|
|
136
|
+
}
|
|
137
|
+
if (args.sort_by !== undefined) {
|
|
138
|
+
query.sort_by = args.sort_by;
|
|
139
|
+
}
|
|
140
|
+
if (args.sort_order !== undefined) {
|
|
141
|
+
query.sort_order = args.sort_order;
|
|
142
|
+
}
|
|
143
|
+
return Object.keys(query).length > 0 ? query : undefined;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Register `exception_list`. Passes the filter/sort/pagination knobs through and
|
|
147
|
+
* returns matcher's pagination envelope verbatim; a matcher error surfaces via
|
|
148
|
+
* the shared toToolError.
|
|
149
|
+
*/
|
|
150
|
+
export function registerExceptionListTool(server) {
|
|
151
|
+
server.registerTool('exception_list', {
|
|
152
|
+
description: 'List reconciliation exceptions (cursor-paginated). Optional filters: ' +
|
|
153
|
+
'contextId (UUID — not a tenant field), status (OPEN|ASSIGNED|RESOLVED), ' +
|
|
154
|
+
'severity (LOW|MEDIUM|HIGH|CRITICAL), reason (e.g. UNMATCHED, ' +
|
|
155
|
+
'FEE_VARIANCE), assigned_to, external_system, date_from/date_to (RFC ' +
|
|
156
|
+
'3339), plus sort_by/sort_order and limit (1–200)/cursor. The response ' +
|
|
157
|
+
'carries { items, nextCursor } — paginate by re-calling with the returned ' +
|
|
158
|
+
'nextCursor (do not change sort mid-pagination). No tenant field is accepted.',
|
|
159
|
+
inputSchema: listExceptionsInputShape,
|
|
160
|
+
}, async (args, extra) => {
|
|
161
|
+
const query = buildListQuery(args);
|
|
162
|
+
return dispatchException({
|
|
163
|
+
method: 'GET',
|
|
164
|
+
path: EXCEPTIONS_PATH,
|
|
165
|
+
...(query !== undefined ? { query } : {}),
|
|
166
|
+
}, extra);
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/tools/exception/list.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// `exception_open_dispute` — curated POST /v1/exceptions/{exceptionId}/disputes.
|
|
2
|
+
//
|
|
3
|
+
// Opens a formal dispute against one exception, used to challenge or investigate
|
|
4
|
+
// a discrepancy with an external party. Mirrors the spec's OpenDisputeRequest —
|
|
5
|
+
// category (1–255) and description (1–5000), both required. exceptionId is a
|
|
6
|
+
// path param; no tenant field is accepted.
|
|
7
|
+
import { z } from 'zod';
|
|
8
|
+
import { dispatchException, exceptionDisputesPath } from './shared.js';
|
|
9
|
+
/** Zod raw shape for `exception_open_dispute` input — path id + dispute body. */
|
|
10
|
+
export const openDisputeInputShape = {
|
|
11
|
+
exceptionId: z
|
|
12
|
+
.string()
|
|
13
|
+
.min(1)
|
|
14
|
+
.describe('The exception id (UUID) to open a dispute against.'),
|
|
15
|
+
category: z
|
|
16
|
+
.string()
|
|
17
|
+
.min(1)
|
|
18
|
+
.max(255)
|
|
19
|
+
.describe('Category of the dispute (1–255 chars, e.g. "AMOUNT_MISMATCH").'),
|
|
20
|
+
description: z
|
|
21
|
+
.string()
|
|
22
|
+
.min(1)
|
|
23
|
+
.max(5000)
|
|
24
|
+
.describe('Detailed description of the dispute (1–5000 chars).'),
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Build the POST body from the input minus the path-only `exceptionId`. Only the
|
|
28
|
+
* OpenDisputeRequest fields are sent; exceptionId travels in the path.
|
|
29
|
+
*/
|
|
30
|
+
export function buildOpenDisputeBody(args) {
|
|
31
|
+
return { category: args.category, description: args.description };
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Register `exception_open_dispute`. Substitutes the id into the path, builds the
|
|
35
|
+
* body from the typed input, and dispatches a POST through the shared
|
|
36
|
+
* fail-closed relay; a matcher error surfaces via the shared toToolError.
|
|
37
|
+
*/
|
|
38
|
+
export function registerExceptionOpenDisputeTool(server) {
|
|
39
|
+
server.registerTool('exception_open_dispute', {
|
|
40
|
+
description: 'Open a formal dispute against a reconciliation exception. Provide ' +
|
|
41
|
+
'exceptionId (UUID path param), category (1–255), and description ' +
|
|
42
|
+
'(1–5000). No tenant field is accepted. Returns the created dispute, or a ' +
|
|
43
|
+
'structured RFC 9457 error.',
|
|
44
|
+
inputSchema: openDisputeInputShape,
|
|
45
|
+
}, async (args, extra) => {
|
|
46
|
+
return dispatchException({
|
|
47
|
+
method: 'POST',
|
|
48
|
+
path: exceptionDisputesPath(args.exceptionId),
|
|
49
|
+
body: buildOpenDisputeBody(args),
|
|
50
|
+
}, extra);
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=open-dispute.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open-dispute.js","sourceRoot":"","sources":["../../../src/tools/exception/open-dispute.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,EAAE;AACF,iFAAiF;AACjF,gFAAgF;AAChF,6EAA6E;AAC7E,2CAA2C;AAE3C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AAEtE,iFAAiF;AACjF,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,WAAW,EAAE,CAAC;SACX,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,CAAC,oDAAoD,CAAC;IACjE,QAAQ,EAAE,CAAC;SACR,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,GAAG,CAAC;SACR,QAAQ,CAAC,gEAAgE,CAAC;IAC7E,WAAW,EAAE,CAAC;SACX,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,IAAI,CAAC;SACT,QAAQ,CAAC,qDAAqD,CAAC;CACnE,CAAA;AAOD;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAClC,IAAsB;IAEtB,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,CAAA;AACnE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gCAAgC,CAAC,MAAiB;IAChE,MAAM,CAAC,YAAY,CACjB,wBAAwB,EACxB;QACE,WAAW,EACT,oEAAoE;YACpE,mEAAmE;YACnE,2EAA2E;YAC3E,4BAA4B;QAC9B,WAAW,EAAE,qBAAqB;KACnC,EACD,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;QACpB,OAAO,iBAAiB,CACtB;YACE,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,qBAAqB,CAAC,IAAI,CAAC,WAAW,CAAC;YAC7C,IAAI,EAAE,oBAAoB,CAAC,IAAI,CAAC;SACjC,EACD,KAAK,CACN,CAAA;IACH,CAAC,CACF,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
// Shared plumbing for the curated exception tools.
|
|
2
|
+
//
|
|
3
|
+
// Exceptions are the flat top-level resource at /v1/exceptions, with a handful
|
|
4
|
+
// of sub-resources (/{id}, /{id}/history, /{id}/comments[/{commentId}],
|
|
5
|
+
// /{id}/disputes) and per-exception action verbs (/{id}/dispatch, /force-match,
|
|
6
|
+
// /adjust-entry), plus the cross-exception bulk endpoints under /bulk/*. This
|
|
7
|
+
// module factors every path helper plus the relay/error-mapping boilerplate
|
|
8
|
+
// exactly once so the thirteen tools stay thin — they only "build the request".
|
|
9
|
+
//
|
|
10
|
+
// The relay shape is identical to the source / fee-schedule verticals: fail
|
|
11
|
+
// closed via requireMatcherClient, dispatch one assembled MatcherRequest, then
|
|
12
|
+
// return matcher's JSON on success or the SHARED toToolError on a
|
|
13
|
+
// MatcherApiError. Curated and generic surfaces therefore map matcher errors
|
|
14
|
+
// through the same path.
|
|
15
|
+
//
|
|
16
|
+
// Security: the bearer token is never read here directly — requireMatcherClient
|
|
17
|
+
// owns the request-scoped relay and fails closed when no usable credential was
|
|
18
|
+
// provided. No tenant identifier is ever read or injected (matcher derives
|
|
19
|
+
// tenant from the relayed JWT); no exception tool input carries one.
|
|
20
|
+
import { requireMatcherClient, UnauthenticatedError, } from '../../auth/request-token.js';
|
|
21
|
+
import { isMatcherApiError, toToolError } from '../tool-error.js';
|
|
22
|
+
/** Base path for the flat exceptions collection (list). */
|
|
23
|
+
export const EXCEPTIONS_PATH = '/v1/exceptions';
|
|
24
|
+
/** Single-exception sub-path (get / action verbs), id URL-encoded so reserved chars are safe. */
|
|
25
|
+
export function exceptionPath(exceptionId) {
|
|
26
|
+
return `${EXCEPTIONS_PATH}/${encodeURIComponent(exceptionId)}`;
|
|
27
|
+
}
|
|
28
|
+
/** History sub-resource of one exception (audit trail, cursor-paginated). */
|
|
29
|
+
export function exceptionHistoryPath(exceptionId) {
|
|
30
|
+
return `${exceptionPath(exceptionId)}/history`;
|
|
31
|
+
}
|
|
32
|
+
/** Comments collection of one exception (list / add). */
|
|
33
|
+
export function exceptionCommentsPath(exceptionId) {
|
|
34
|
+
return `${exceptionPath(exceptionId)}/comments`;
|
|
35
|
+
}
|
|
36
|
+
/** A single comment under one exception (delete), both ids URL-encoded. */
|
|
37
|
+
export function exceptionCommentPath(exceptionId, commentId) {
|
|
38
|
+
return `${exceptionCommentsPath(exceptionId)}/${encodeURIComponent(commentId)}`;
|
|
39
|
+
}
|
|
40
|
+
/** Dispatch action for one exception (push to an external ticketing system). */
|
|
41
|
+
export function exceptionDispatchPath(exceptionId) {
|
|
42
|
+
return `${exceptionPath(exceptionId)}/dispatch`;
|
|
43
|
+
}
|
|
44
|
+
/** Disputes collection of one exception (open a dispute). */
|
|
45
|
+
export function exceptionDisputesPath(exceptionId) {
|
|
46
|
+
return `${exceptionPath(exceptionId)}/disputes`;
|
|
47
|
+
}
|
|
48
|
+
/** Force-match action for one exception (resolve by overriding the match). */
|
|
49
|
+
export function exceptionForceMatchPath(exceptionId) {
|
|
50
|
+
return `${exceptionPath(exceptionId)}/force-match`;
|
|
51
|
+
}
|
|
52
|
+
/** Adjust-entry action for one exception (resolve via a balancing adjustment). */
|
|
53
|
+
export function exceptionAdjustEntryPath(exceptionId) {
|
|
54
|
+
return `${exceptionPath(exceptionId)}/adjust-entry`;
|
|
55
|
+
}
|
|
56
|
+
/** Bulk-assign action across many exceptions. */
|
|
57
|
+
export const EXCEPTIONS_BULK_ASSIGN_PATH = `${EXCEPTIONS_PATH}/bulk/assign`;
|
|
58
|
+
/** Bulk-resolve action across many exceptions. */
|
|
59
|
+
export const EXCEPTIONS_BULK_RESOLVE_PATH = `${EXCEPTIONS_PATH}/bulk/resolve`;
|
|
60
|
+
/** Bulk-dispatch action across many exceptions. */
|
|
61
|
+
export const EXCEPTIONS_BULK_DISPATCH_PATH = `${EXCEPTIONS_PATH}/bulk/dispatch`;
|
|
62
|
+
/**
|
|
63
|
+
* Run one assembled request through the relay: fail-closed auth, dispatch, and
|
|
64
|
+
* RFC 9457 → tool-error mapping — identical to the generic invoke's dispatch so
|
|
65
|
+
* both surfaces produce the same structured error shape.
|
|
66
|
+
*
|
|
67
|
+
* `clientFor` is injectable for tests; production callers pass nothing and get
|
|
68
|
+
* the request-scoped, fail-closed `requireMatcherClient`.
|
|
69
|
+
*/
|
|
70
|
+
export async function dispatchException(request, extra, clientFor = requireMatcherClient) {
|
|
71
|
+
let client;
|
|
72
|
+
try {
|
|
73
|
+
// Fail-closed on a missing / empty / non-Bearer credential.
|
|
74
|
+
client = clientFor(extra);
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
if (err instanceof UnauthenticatedError) {
|
|
78
|
+
return { isError: true, content: [{ type: 'text', text: err.message }] };
|
|
79
|
+
}
|
|
80
|
+
throw err;
|
|
81
|
+
}
|
|
82
|
+
try {
|
|
83
|
+
const result = await client.request(request);
|
|
84
|
+
// Success → matcher's JSON returned as-is (incl. pagination envelopes and
|
|
85
|
+
// 204 → null for delete-comment).
|
|
86
|
+
return { content: [{ type: 'text', text: JSON.stringify(result ?? null) }] };
|
|
87
|
+
}
|
|
88
|
+
catch (err) {
|
|
89
|
+
// RFC 9457 problem → the SHARED structured tool error (status/title/detail/
|
|
90
|
+
// code preserved). A non-matcher error is a bug, not a matcher failure, and
|
|
91
|
+
// is re-thrown rather than masqueraded as one.
|
|
92
|
+
if (isMatcherApiError(err)) {
|
|
93
|
+
return toToolError(err);
|
|
94
|
+
}
|
|
95
|
+
throw err;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=shared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../src/tools/exception/shared.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
// `fee_rule_create` — curated POST /v1/contexts/{contextId}/fee-rules.
|
|
2
|
+
//
|
|
3
|
+
// A typed, richly-described front door to creating a fee rule, mirroring the
|
|
4
|
+
// spec's CreateFeeRuleRequest. The rule binds a fee schedule to a reconciliation
|
|
5
|
+
// context with a side + predicates that a transaction's metadata must satisfy.
|
|
6
|
+
//
|
|
7
|
+
// Path is context-nested: `contextId` is a REQUIRED path param (routing — matcher
|
|
8
|
+
// validates the context belongs to the relayed token's tenant), NOT a tenant
|
|
9
|
+
// field. The body is the input minus `contextId`.
|
|
10
|
+
//
|
|
11
|
+
// The predicate sub-object is modeled explicitly (the operator enum set is small
|
|
12
|
+
// and known: EQUALS / IN / EXISTS), so an operator-driving LLM gets the exact
|
|
13
|
+
// shape; `value`/`values` are optional because EXISTS needs neither.
|
|
14
|
+
import { z } from 'zod';
|
|
15
|
+
import { contextFeeRulesPath, dispatchFeeRule } from './shared.js';
|
|
16
|
+
/** Side a fee rule applies to. LEFT/RIGHT target one side; ANY matches either. */
|
|
17
|
+
export const FEE_RULE_SIDES = ['LEFT', 'RIGHT', 'ANY'];
|
|
18
|
+
/** Predicate comparison operators matcher supports for fee-rule predicates. */
|
|
19
|
+
export const PREDICATE_OPERATORS = ['EQUALS', 'IN', 'EXISTS'];
|
|
20
|
+
/**
|
|
21
|
+
* One field predicate. ANDed with the rule's other predicates. `field` and
|
|
22
|
+
* `operator` are required; `value` is used by EQUALS, `values` by IN, and EXISTS
|
|
23
|
+
* needs neither — they are optional here and matcher is the authoritative
|
|
24
|
+
* validator of the operator/value pairing.
|
|
25
|
+
*/
|
|
26
|
+
export const feeRulePredicateShape = z
|
|
27
|
+
.object({
|
|
28
|
+
field: z
|
|
29
|
+
.string()
|
|
30
|
+
.describe('Transaction metadata field the predicate tests, e.g. "institution".'),
|
|
31
|
+
operator: z
|
|
32
|
+
.enum(PREDICATE_OPERATORS)
|
|
33
|
+
.describe('Comparison operator. EQUALS matches a single `value`; IN matches any ' +
|
|
34
|
+
'of `values`; EXISTS asserts the field is present (needs neither).'),
|
|
35
|
+
value: z
|
|
36
|
+
.string()
|
|
37
|
+
.optional()
|
|
38
|
+
.describe('Comparison value — required for the EQUALS operator.'),
|
|
39
|
+
values: z
|
|
40
|
+
.array(z.string())
|
|
41
|
+
.optional()
|
|
42
|
+
.describe('Candidate values — required for the IN operator.'),
|
|
43
|
+
})
|
|
44
|
+
.describe('A single field predicate a transaction must satisfy for the rule to apply.');
|
|
45
|
+
/** Zod raw shape for `fee_rule_create` input — mirrors CreateFeeRuleRequest. */
|
|
46
|
+
export const createFeeRuleInputShape = {
|
|
47
|
+
contextId: z
|
|
48
|
+
.string()
|
|
49
|
+
.min(1)
|
|
50
|
+
.describe('The reconciliation context id (UUID) the fee rule is created under. A ' +
|
|
51
|
+
'routing path param — matcher validates the context belongs to your ' +
|
|
52
|
+
"token's tenant. NOT a tenant field."),
|
|
53
|
+
side: z
|
|
54
|
+
.enum(FEE_RULE_SIDES)
|
|
55
|
+
.describe('Side the rule applies to. LEFT and RIGHT target one reconciliation side; ' +
|
|
56
|
+
'ANY matches transactions on either side.'),
|
|
57
|
+
feeScheduleId: z
|
|
58
|
+
.string()
|
|
59
|
+
.min(1)
|
|
60
|
+
.describe('UUID of the fee schedule this rule applies when its predicates match. You ' +
|
|
61
|
+
'must be allowed to read the referenced schedule.'),
|
|
62
|
+
name: z
|
|
63
|
+
.string()
|
|
64
|
+
.min(1)
|
|
65
|
+
.max(100)
|
|
66
|
+
.describe('Human-readable name of the fee rule (1–100 chars).'),
|
|
67
|
+
priority: z
|
|
68
|
+
.number()
|
|
69
|
+
.int()
|
|
70
|
+
.describe('Evaluation priority; lower numbers are evaluated first. Must be unique ' +
|
|
71
|
+
'within the context — LEFT, RIGHT, and ANY rules share one priority space.'),
|
|
72
|
+
predicates: z
|
|
73
|
+
.array(feeRulePredicateShape)
|
|
74
|
+
.describe('Predicates (ANDed together) a transaction\'s metadata must satisfy for ' +
|
|
75
|
+
'this rule to apply.'),
|
|
76
|
+
};
|
|
77
|
+
/** Build the POST body from the input minus the path-only `contextId`. */
|
|
78
|
+
export function buildCreateBody(args) {
|
|
79
|
+
const { contextId: _contextId, ...body } = args;
|
|
80
|
+
void _contextId;
|
|
81
|
+
return body;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Register `fee_rule_create`. Substitutes `contextId` into the context-nested
|
|
85
|
+
* path and dispatches the body through the shared fail-closed relay; a matcher
|
|
86
|
+
* error surfaces via the shared toToolError (same shape as matcher_invoke).
|
|
87
|
+
*/
|
|
88
|
+
export function registerFeeRuleCreateTool(server) {
|
|
89
|
+
server.registerTool('fee_rule_create', {
|
|
90
|
+
description: 'Create a fee rule under a reconciliation context, binding a fee schedule ' +
|
|
91
|
+
'to transactions whose metadata satisfies the predicates. Provide ' +
|
|
92
|
+
'contextId (path), side (LEFT|RIGHT|ANY), feeScheduleId (UUID), name ' +
|
|
93
|
+
'(1–100), priority (unique within the context across all sides), and ' +
|
|
94
|
+
'predicates[] (each { field, operator EQUALS|IN|EXISTS, value?, values? }). ' +
|
|
95
|
+
'The rule is scoped to your token\'s tenant (no tenant field is accepted). ' +
|
|
96
|
+
'Returns the created rule, or a structured RFC 9457 error.',
|
|
97
|
+
inputSchema: createFeeRuleInputShape,
|
|
98
|
+
}, async (args, extra) => {
|
|
99
|
+
return dispatchFeeRule({
|
|
100
|
+
method: 'POST',
|
|
101
|
+
path: contextFeeRulesPath(args.contextId),
|
|
102
|
+
body: buildCreateBody(args),
|
|
103
|
+
}, extra);
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=create.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.js","sourceRoot":"","sources":["../../../src/tools/fee-rule/create.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// `fee_rule_delete` — curated DELETE /v1/fee-rules/{feeRuleId}.
|
|
2
|
+
//
|
|
3
|
+
// Removes a fee rule by id via the FLAT path. A successful delete returns 204
|
|
4
|
+
// (no content), which the relay renders as null. feeRuleId is a UUID path param;
|
|
5
|
+
// no tenant field is accepted (matcher scopes to the relayed token's tenant).
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
import { dispatchFeeRule, feeRulePath } from './shared.js';
|
|
8
|
+
/** Zod raw shape for `fee_rule_delete` input — just the fee-rule id (flat path). */
|
|
9
|
+
export const deleteFeeRuleInputShape = {
|
|
10
|
+
feeRuleId: z.string().min(1).describe('The fee rule id (UUID) to delete.'),
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Register `fee_rule_delete`. Substitutes the id into the flat path and
|
|
14
|
+
* dispatches a DELETE through the shared fail-closed relay; any matcher error
|
|
15
|
+
* surfaces via the shared toToolError.
|
|
16
|
+
*/
|
|
17
|
+
export function registerFeeRuleDeleteTool(server) {
|
|
18
|
+
server.registerTool('fee_rule_delete', {
|
|
19
|
+
description: 'Delete a fee rule by id (UUID) via the flat path. The rule must belong ' +
|
|
20
|
+
"to your token's tenant (no tenant field is accepted). Returns no content " +
|
|
21
|
+
'on success, or a structured RFC 9457 error.',
|
|
22
|
+
inputSchema: deleteFeeRuleInputShape,
|
|
23
|
+
}, async (args, extra) => {
|
|
24
|
+
return dispatchFeeRule({ method: 'DELETE', path: feeRulePath(args.feeRuleId) }, extra);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=delete.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delete.js","sourceRoot":"","sources":["../../../src/tools/fee-rule/delete.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,EAAE;AACF,8EAA8E;AAC9E,iFAAiF;AACjF,8EAA8E;AAE9E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAE1D,oFAAoF;AACpF,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,mCAAmC,CAAC;CAC3E,CAAA;AAOD;;;;GAIG;AACH,MAAM,UAAU,yBAAyB,CAAC,MAAiB;IACzD,MAAM,CAAC,YAAY,CACjB,iBAAiB,EACjB;QACE,WAAW,EACT,yEAAyE;YACzE,2EAA2E;YAC3E,6CAA6C;QAC/C,WAAW,EAAE,uBAAuB;KACrC,EACD,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;QACpB,OAAO,eAAe,CACpB,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EACvD,KAAK,CACN,CAAA;IACH,CAAC,CACF,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// `fee_rule_get` — curated GET /v1/fee-rules/{feeRuleId}.
|
|
2
|
+
//
|
|
3
|
+
// Reads one fee rule by id via the FLAT path (no contextId). feeRuleId is the
|
|
4
|
+
// only input (a UUID path param). The rule must belong to the relayed token's
|
|
5
|
+
// tenant — matcher enforces that; no tenant field is accepted.
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
import { dispatchFeeRule, feeRulePath } from './shared.js';
|
|
8
|
+
/** Zod raw shape for `fee_rule_get` input — just the fee-rule id (flat path). */
|
|
9
|
+
export const getFeeRuleInputShape = {
|
|
10
|
+
feeRuleId: z.string().min(1).describe('The fee rule id (UUID) to fetch.'),
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Register `fee_rule_get`. Substitutes the id into the flat path and dispatches a
|
|
14
|
+
* GET through the shared fail-closed relay; a matcher error (e.g. 404) surfaces
|
|
15
|
+
* via the shared toToolError.
|
|
16
|
+
*/
|
|
17
|
+
export function registerFeeRuleGetTool(server) {
|
|
18
|
+
server.registerTool('fee_rule_get', {
|
|
19
|
+
description: 'Fetch a single fee rule by id (UUID). The rule must belong to your ' +
|
|
20
|
+
"token's tenant. Returns the rule, or a structured RFC 9457 error (e.g. " +
|
|
21
|
+
'404 if it does not exist or is not yours).',
|
|
22
|
+
inputSchema: getFeeRuleInputShape,
|
|
23
|
+
}, async (args, extra) => {
|
|
24
|
+
return dispatchFeeRule({ method: 'GET', path: feeRulePath(args.feeRuleId) }, extra);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=get.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get.js","sourceRoot":"","sources":["../../../src/tools/fee-rule/get.ts"],"names":[],"mappings":"AAAA,0DAA0D;AAC1D,EAAE;AACF,8EAA8E;AAC9E,8EAA8E;AAC9E,+DAA+D;AAE/D,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAE1D,iFAAiF;AACjF,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,kCAAkC,CAAC;CAC1E,CAAA;AAKD;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAAiB;IACtD,MAAM,CAAC,YAAY,CACjB,cAAc,EACd;QACE,WAAW,EACT,qEAAqE;YACrE,yEAAyE;YACzE,4CAA4C;QAC9C,WAAW,EAAE,oBAAoB;KAClC,EACD,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;QACpB,OAAO,eAAe,CACpB,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EACpD,KAAK,CACN,CAAA;IACH,CAAC,CACF,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// Curated fee-rule vertical (task 2.1.1): five typed tools over the matcher
|
|
2
|
+
// fee-rule resource — create, list, get, update, delete. Fee rules use a HYBRID
|
|
3
|
+
// path: create/list are context-nested (/v1/contexts/{contextId}/fee-rules) and
|
|
4
|
+
// get/update/delete are flat (/v1/fee-rules/{feeRuleId}). Each tool shares the
|
|
5
|
+
// fail-closed relay (shared.ts) and the RFC 9457 → tool-error mapping
|
|
6
|
+
// (toToolError) with the generic surface, so curated and generic map matcher
|
|
7
|
+
// errors identically. No tool carries a tenant field.
|
|
8
|
+
import { registerFeeRuleCreateTool } from './create.js';
|
|
9
|
+
import { registerFeeRuleDeleteTool } from './delete.js';
|
|
10
|
+
import { registerFeeRuleGetTool } from './get.js';
|
|
11
|
+
import { registerFeeRuleListTool } from './list.js';
|
|
12
|
+
import { registerFeeRuleUpdateTool } from './update.js';
|
|
13
|
+
/** Register all five curated fee-rule tools on the given server. */
|
|
14
|
+
export function registerFeeRuleTools(server) {
|
|
15
|
+
registerFeeRuleCreateTool(server);
|
|
16
|
+
registerFeeRuleListTool(server);
|
|
17
|
+
registerFeeRuleGetTool(server);
|
|
18
|
+
registerFeeRuleUpdateTool(server);
|
|
19
|
+
registerFeeRuleDeleteTool(server);
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/fee-rule/index.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,gFAAgF;AAChF,gFAAgF;AAChF,+EAA+E;AAC/E,sEAAsE;AACtE,6EAA6E;AAC7E,sDAAsD;AAItD,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAA;AACvD,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAA;AACvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAA;AACjD,OAAO,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAA;AACnD,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAA;AAEvD,oEAAoE;AACpE,MAAM,UAAU,oBAAoB,CAAC,MAAiB;IACpD,yBAAyB,CAAC,MAAM,CAAC,CAAA;IACjC,uBAAuB,CAAC,MAAM,CAAC,CAAA;IAC/B,sBAAsB,CAAC,MAAM,CAAC,CAAA;IAC9B,yBAAyB,CAAC,MAAM,CAAC,CAAA;IACjC,yBAAyB,CAAC,MAAM,CAAC,CAAA;AACnC,CAAC"}
|