@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.
Files changed (220) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +281 -0
  3. package/dist/auth/request-token.js +117 -0
  4. package/dist/auth/request-token.js.map +1 -0
  5. package/dist/config.js +95 -0
  6. package/dist/config.js.map +1 -0
  7. package/dist/matcher/client.js +168 -0
  8. package/dist/matcher/client.js.map +1 -0
  9. package/dist/observability/otel.js +223 -0
  10. package/dist/observability/otel.js.map +1 -0
  11. package/dist/server.js +245 -0
  12. package/dist/server.js.map +1 -0
  13. package/dist/spec/curated-operations.js +145 -0
  14. package/dist/spec/curated-operations.js.map +1 -0
  15. package/dist/spec/index.js +155 -0
  16. package/dist/spec/index.js.map +1 -0
  17. package/dist/spec/load.js +76 -0
  18. package/dist/spec/load.js.map +1 -0
  19. package/dist/spec/openapi.yaml +15217 -0
  20. package/dist/tools/context/create.js +100 -0
  21. package/dist/tools/context/create.js.map +1 -0
  22. package/dist/tools/context/get.js +31 -0
  23. package/dist/tools/context/get.js.map +1 -0
  24. package/dist/tools/context/index.js +21 -0
  25. package/dist/tools/context/index.js.map +1 -0
  26. package/dist/tools/context/list.js +78 -0
  27. package/dist/tools/context/list.js.map +1 -0
  28. package/dist/tools/context/shared.js +61 -0
  29. package/dist/tools/context/shared.js.map +1 -0
  30. package/dist/tools/context/update.js +105 -0
  31. package/dist/tools/context/update.js.map +1 -0
  32. package/dist/tools/dashboard/aggregates.js +34 -0
  33. package/dist/tools/dashboard/aggregates.js.map +1 -0
  34. package/dist/tools/dashboard/cash-impact.js +36 -0
  35. package/dist/tools/dashboard/cash-impact.js.map +1 -0
  36. package/dist/tools/dashboard/index.js +27 -0
  37. package/dist/tools/dashboard/index.js.map +1 -0
  38. package/dist/tools/dashboard/match-rate.js +35 -0
  39. package/dist/tools/dashboard/match-rate.js.map +1 -0
  40. package/dist/tools/dashboard/metrics.js +36 -0
  41. package/dist/tools/dashboard/metrics.js.map +1 -0
  42. package/dist/tools/dashboard/shared.js +122 -0
  43. package/dist/tools/dashboard/shared.js.map +1 -0
  44. package/dist/tools/dashboard/sla.js +33 -0
  45. package/dist/tools/dashboard/sla.js.map +1 -0
  46. package/dist/tools/dashboard/source-breakdown.js +36 -0
  47. package/dist/tools/dashboard/source-breakdown.js.map +1 -0
  48. package/dist/tools/dashboard/volume.js +35 -0
  49. package/dist/tools/dashboard/volume.js.map +1 -0
  50. package/dist/tools/dispute/close.js +49 -0
  51. package/dist/tools/dispute/close.js.map +1 -0
  52. package/dist/tools/dispute/get.js +27 -0
  53. package/dist/tools/dispute/get.js.map +1 -0
  54. package/dist/tools/dispute/index.js +17 -0
  55. package/dist/tools/dispute/index.js.map +1 -0
  56. package/dist/tools/dispute/list.js +137 -0
  57. package/dist/tools/dispute/list.js.map +1 -0
  58. package/dist/tools/dispute/shared.js +66 -0
  59. package/dist/tools/dispute/shared.js.map +1 -0
  60. package/dist/tools/dispute/submit-evidence.js +58 -0
  61. package/dist/tools/dispute/submit-evidence.js.map +1 -0
  62. package/dist/tools/exception/add-comment.js +50 -0
  63. package/dist/tools/exception/add-comment.js.map +1 -0
  64. package/dist/tools/exception/adjust-entry.js +71 -0
  65. package/dist/tools/exception/adjust-entry.js.map +1 -0
  66. package/dist/tools/exception/bulk-assign.js +47 -0
  67. package/dist/tools/exception/bulk-assign.js.map +1 -0
  68. package/dist/tools/exception/bulk-dispatch.js +69 -0
  69. package/dist/tools/exception/bulk-dispatch.js.map +1 -0
  70. package/dist/tools/exception/bulk-resolve.js +64 -0
  71. package/dist/tools/exception/bulk-resolve.js.map +1 -0
  72. package/dist/tools/exception/delete-comment.js +40 -0
  73. package/dist/tools/exception/delete-comment.js.map +1 -0
  74. package/dist/tools/exception/dispatch.js +64 -0
  75. package/dist/tools/exception/dispatch.js.map +1 -0
  76. package/dist/tools/exception/force-match.js +55 -0
  77. package/dist/tools/exception/force-match.js.map +1 -0
  78. package/dist/tools/exception/get.js +34 -0
  79. package/dist/tools/exception/get.js.map +1 -0
  80. package/dist/tools/exception/history.js +61 -0
  81. package/dist/tools/exception/history.js.map +1 -0
  82. package/dist/tools/exception/index.js +39 -0
  83. package/dist/tools/exception/index.js.map +1 -0
  84. package/dist/tools/exception/list-comments.js +35 -0
  85. package/dist/tools/exception/list-comments.js.map +1 -0
  86. package/dist/tools/exception/list.js +169 -0
  87. package/dist/tools/exception/list.js.map +1 -0
  88. package/dist/tools/exception/open-dispute.js +53 -0
  89. package/dist/tools/exception/open-dispute.js.map +1 -0
  90. package/dist/tools/exception/shared.js +98 -0
  91. package/dist/tools/exception/shared.js.map +1 -0
  92. package/dist/tools/fee-rule/create.js +106 -0
  93. package/dist/tools/fee-rule/create.js.map +1 -0
  94. package/dist/tools/fee-rule/delete.js +27 -0
  95. package/dist/tools/fee-rule/delete.js.map +1 -0
  96. package/dist/tools/fee-rule/get.js +27 -0
  97. package/dist/tools/fee-rule/get.js.map +1 -0
  98. package/dist/tools/fee-rule/index.js +21 -0
  99. package/dist/tools/fee-rule/index.js.map +1 -0
  100. package/dist/tools/fee-rule/list.js +64 -0
  101. package/dist/tools/fee-rule/list.js.map +1 -0
  102. package/dist/tools/fee-rule/shared.js +67 -0
  103. package/dist/tools/fee-rule/shared.js.map +1 -0
  104. package/dist/tools/fee-rule/update.js +70 -0
  105. package/dist/tools/fee-rule/update.js.map +1 -0
  106. package/dist/tools/fee-schedule/create.js +105 -0
  107. package/dist/tools/fee-schedule/create.js.map +1 -0
  108. package/dist/tools/fee-schedule/delete.js +32 -0
  109. package/dist/tools/fee-schedule/delete.js.map +1 -0
  110. package/dist/tools/fee-schedule/get.js +30 -0
  111. package/dist/tools/fee-schedule/get.js.map +1 -0
  112. package/dist/tools/fee-schedule/index.js +22 -0
  113. package/dist/tools/fee-schedule/index.js.map +1 -0
  114. package/dist/tools/fee-schedule/list.js +56 -0
  115. package/dist/tools/fee-schedule/list.js.map +1 -0
  116. package/dist/tools/fee-schedule/shared.js +58 -0
  117. package/dist/tools/fee-schedule/shared.js.map +1 -0
  118. package/dist/tools/fee-schedule/simulate.js +54 -0
  119. package/dist/tools/fee-schedule/simulate.js.map +1 -0
  120. package/dist/tools/fee-schedule/update.js +69 -0
  121. package/dist/tools/fee-schedule/update.js.map +1 -0
  122. package/dist/tools/generic/describe-operation.js +157 -0
  123. package/dist/tools/generic/describe-operation.js.map +1 -0
  124. package/dist/tools/generic/invoke.js +343 -0
  125. package/dist/tools/generic/invoke.js.map +1 -0
  126. package/dist/tools/generic/list-operations.js +73 -0
  127. package/dist/tools/generic/list-operations.js.map +1 -0
  128. package/dist/tools/ingestion/index.js +29 -0
  129. package/dist/tools/ingestion/index.js.map +1 -0
  130. package/dist/tools/ingestion/job-errors-list.js +45 -0
  131. package/dist/tools/ingestion/job-errors-list.js.map +1 -0
  132. package/dist/tools/ingestion/job-get.js +42 -0
  133. package/dist/tools/ingestion/job-get.js.map +1 -0
  134. package/dist/tools/ingestion/job-transactions-list.js +93 -0
  135. package/dist/tools/ingestion/job-transactions-list.js.map +1 -0
  136. package/dist/tools/ingestion/jobs-list.js +89 -0
  137. package/dist/tools/ingestion/jobs-list.js.map +1 -0
  138. package/dist/tools/ingestion/shared.js +84 -0
  139. package/dist/tools/ingestion/shared.js.map +1 -0
  140. package/dist/tools/ingestion/transaction-ignore.js +51 -0
  141. package/dist/tools/ingestion/transaction-ignore.js.map +1 -0
  142. package/dist/tools/ingestion/transactions-search.js +143 -0
  143. package/dist/tools/ingestion/transactions-search.js.map +1 -0
  144. package/dist/tools/match-rule/create.js +64 -0
  145. package/dist/tools/match-rule/create.js.map +1 -0
  146. package/dist/tools/match-rule/delete.js +35 -0
  147. package/dist/tools/match-rule/delete.js.map +1 -0
  148. package/dist/tools/match-rule/get.js +32 -0
  149. package/dist/tools/match-rule/get.js.map +1 -0
  150. package/dist/tools/match-rule/index.js +22 -0
  151. package/dist/tools/match-rule/index.js.map +1 -0
  152. package/dist/tools/match-rule/list.js +72 -0
  153. package/dist/tools/match-rule/list.js.map +1 -0
  154. package/dist/tools/match-rule/reorder.js +45 -0
  155. package/dist/tools/match-rule/reorder.js.map +1 -0
  156. package/dist/tools/match-rule/shared.js +71 -0
  157. package/dist/tools/match-rule/shared.js.map +1 -0
  158. package/dist/tools/match-rule/update.js +68 -0
  159. package/dist/tools/match-rule/update.js.map +1 -0
  160. package/dist/tools/matching/get.js +48 -0
  161. package/dist/tools/matching/get.js.map +1 -0
  162. package/dist/tools/matching/groups.js +98 -0
  163. package/dist/tools/matching/groups.js.map +1 -0
  164. package/dist/tools/matching/index.js +19 -0
  165. package/dist/tools/matching/index.js.map +1 -0
  166. package/dist/tools/matching/list.js +76 -0
  167. package/dist/tools/matching/list.js.map +1 -0
  168. package/dist/tools/matching/shared.js +77 -0
  169. package/dist/tools/matching/shared.js.map +1 -0
  170. package/dist/tools/matching/start.js +55 -0
  171. package/dist/tools/matching/start.js.map +1 -0
  172. package/dist/tools/report/count-exceptions.js +45 -0
  173. package/dist/tools/report/count-exceptions.js.map +1 -0
  174. package/dist/tools/report/count-matched.js +46 -0
  175. package/dist/tools/report/count-matched.js.map +1 -0
  176. package/dist/tools/report/count-transactions.js +44 -0
  177. package/dist/tools/report/count-transactions.js.map +1 -0
  178. package/dist/tools/report/count-unmatched.js +44 -0
  179. package/dist/tools/report/count-unmatched.js.map +1 -0
  180. package/dist/tools/report/export-exceptions.js +46 -0
  181. package/dist/tools/report/export-exceptions.js.map +1 -0
  182. package/dist/tools/report/export-matched.js +47 -0
  183. package/dist/tools/report/export-matched.js.map +1 -0
  184. package/dist/tools/report/export-summary.js +47 -0
  185. package/dist/tools/report/export-summary.js.map +1 -0
  186. package/dist/tools/report/export-unmatched.js +47 -0
  187. package/dist/tools/report/export-unmatched.js.map +1 -0
  188. package/dist/tools/report/export-variance.js +46 -0
  189. package/dist/tools/report/export-variance.js.map +1 -0
  190. package/dist/tools/report/index.js +40 -0
  191. package/dist/tools/report/index.js.map +1 -0
  192. package/dist/tools/report/matched.js +44 -0
  193. package/dist/tools/report/matched.js.map +1 -0
  194. package/dist/tools/report/shared.js +176 -0
  195. package/dist/tools/report/shared.js.map +1 -0
  196. package/dist/tools/report/summary.js +41 -0
  197. package/dist/tools/report/summary.js.map +1 -0
  198. package/dist/tools/report/unmatched.js +44 -0
  199. package/dist/tools/report/unmatched.js.map +1 -0
  200. package/dist/tools/report/variance.js +44 -0
  201. package/dist/tools/report/variance.js.map +1 -0
  202. package/dist/tools/source/create.js +84 -0
  203. package/dist/tools/source/create.js.map +1 -0
  204. package/dist/tools/source/get.js +41 -0
  205. package/dist/tools/source/get.js.map +1 -0
  206. package/dist/tools/source/index.js +22 -0
  207. package/dist/tools/source/index.js.map +1 -0
  208. package/dist/tools/source/list.js +72 -0
  209. package/dist/tools/source/list.js.map +1 -0
  210. package/dist/tools/source/shared.js +63 -0
  211. package/dist/tools/source/shared.js.map +1 -0
  212. package/dist/tools/source/update.js +73 -0
  213. package/dist/tools/source/update.js.map +1 -0
  214. package/dist/tools/tool-error.js +74 -0
  215. package/dist/tools/tool-error.js.map +1 -0
  216. package/dist/transport/body-limit.js +82 -0
  217. package/dist/transport/body-limit.js.map +1 -0
  218. package/dist/transport/http.js +154 -0
  219. package/dist/transport/http.js.map +1 -0
  220. package/package.json +68 -0
@@ -0,0 +1,143 @@
1
+ // `ingestion_transactions_search` — curated GET
2
+ // /v1/imports/contexts/{contextId}/transactions/search.
3
+ //
4
+ // Searches a context's transactions by free text, amount range, date range,
5
+ // reference, currency, source, and status. Unlike the cursor-paginated job/
6
+ // transaction lists, this endpoint is OFFSET-paginated (limit + offset) and the
7
+ // response carries a total count — re-call with a bumped offset to page. Amounts
8
+ // are decimal STRINGS to preserve precision. Every knob is optional; only
9
+ // contextId (path) is required. No tenant field is accepted — matcher scopes the
10
+ // search to the relayed token's tenant.
11
+ import { z } from 'zod';
12
+ import { contextTransactionsSearchPath, dispatchIngestion } from './shared.js';
13
+ /** Transaction statuses the search filter accepts (spec enum). */
14
+ export const TRANSACTION_STATUSES = [
15
+ 'UNMATCHED',
16
+ 'MATCHED',
17
+ 'IGNORED',
18
+ 'PENDING_REVIEW',
19
+ ];
20
+ /** Zod raw shape for `ingestion_transactions_search` input — contextId path + filters + offset pagination. */
21
+ export const searchTransactionsInputShape = {
22
+ contextId: z
23
+ .string()
24
+ .min(1)
25
+ .describe('The reconciliation context id (UUID) to search within. Routing path ' +
26
+ 'param, not a tenant field.'),
27
+ q: z
28
+ .string()
29
+ .optional()
30
+ .describe('Free text search across external ID and description.'),
31
+ amount_min: z
32
+ .string()
33
+ .optional()
34
+ .describe('Minimum transaction amount, as a decimal STRING, e.g. "100.00" (a ' +
35
+ 'string, not a number, to preserve precision).'),
36
+ amount_max: z
37
+ .string()
38
+ .optional()
39
+ .describe('Maximum transaction amount, as a decimal STRING, e.g. "5000.00" (a ' +
40
+ 'string, not a number, to preserve precision).'),
41
+ date_from: z
42
+ .string()
43
+ .optional()
44
+ .describe('Start date filter (RFC 3339), e.g. "2025-01-01T00:00:00Z".'),
45
+ date_to: z
46
+ .string()
47
+ .optional()
48
+ .describe('End date filter (RFC 3339), e.g. "2025-01-31T23:59:59Z".'),
49
+ reference: z
50
+ .string()
51
+ .optional()
52
+ .describe('Exact external ID match.'),
53
+ currency: z
54
+ .string()
55
+ .optional()
56
+ .describe('Currency code filter (ISO 4217), e.g. "USD".'),
57
+ source_id: z
58
+ .string()
59
+ .optional()
60
+ .describe('Filter to a single source by id (UUID).'),
61
+ status: z
62
+ .enum(TRANSACTION_STATUSES)
63
+ .optional()
64
+ .describe('Transaction status filter (UNMATCHED|MATCHED|IGNORED|PENDING_REVIEW).'),
65
+ limit: z
66
+ .number()
67
+ .int()
68
+ .min(1)
69
+ .max(50)
70
+ .optional()
71
+ .describe('Maximum number of records to return (1–50, default 20).'),
72
+ offset: z
73
+ .number()
74
+ .int()
75
+ .min(0)
76
+ .optional()
77
+ .describe('Number of records to skip (>= 0, default 0). This endpoint is ' +
78
+ 'OFFSET-paginated — re-call with a bumped offset to page forward.'),
79
+ };
80
+ /** Build the search query, omitting unset knobs so the request stays minimal. */
81
+ function buildSearchQuery(args) {
82
+ const query = {};
83
+ if (args.q !== undefined) {
84
+ query.q = args.q;
85
+ }
86
+ if (args.amount_min !== undefined) {
87
+ query.amount_min = args.amount_min;
88
+ }
89
+ if (args.amount_max !== undefined) {
90
+ query.amount_max = args.amount_max;
91
+ }
92
+ if (args.date_from !== undefined) {
93
+ query.date_from = args.date_from;
94
+ }
95
+ if (args.date_to !== undefined) {
96
+ query.date_to = args.date_to;
97
+ }
98
+ if (args.reference !== undefined) {
99
+ query.reference = args.reference;
100
+ }
101
+ if (args.currency !== undefined) {
102
+ query.currency = args.currency;
103
+ }
104
+ if (args.source_id !== undefined) {
105
+ query.source_id = args.source_id;
106
+ }
107
+ if (args.status !== undefined) {
108
+ query.status = args.status;
109
+ }
110
+ if (args.limit !== undefined) {
111
+ query.limit = args.limit;
112
+ }
113
+ if (args.offset !== undefined) {
114
+ query.offset = args.offset;
115
+ }
116
+ return Object.keys(query).length > 0 ? query : undefined;
117
+ }
118
+ /**
119
+ * Register `ingestion_transactions_search`. Passes every filter plus limit/
120
+ * offset through and returns matcher's { items, total, ... } envelope verbatim;
121
+ * a matcher error surfaces via the shared toToolError.
122
+ */
123
+ export function registerIngestionTransactionsSearchTool(server) {
124
+ server.registerTool('ingestion_transactions_search', {
125
+ description: "Search a context's transactions (OFFSET-paginated, with a total " +
126
+ 'count). Provide contextId (UUID path param — not a tenant field) and ' +
127
+ 'any of: q (free text), amount_min/amount_max (decimal strings), ' +
128
+ 'date_from/date_to (RFC 3339), reference (exact external ID), currency ' +
129
+ '(ISO 4217), source_id (UUID), status ' +
130
+ '(UNMATCHED|MATCHED|IGNORED|PENDING_REVIEW), limit (1–50), and offset ' +
131
+ '(>= 0). Paginate by re-calling with a bumped offset. No tenant field is ' +
132
+ 'accepted.',
133
+ inputSchema: searchTransactionsInputShape,
134
+ }, async (args, extra) => {
135
+ const query = buildSearchQuery(args);
136
+ return dispatchIngestion({
137
+ method: 'GET',
138
+ path: contextTransactionsSearchPath(args.contextId),
139
+ ...(query !== undefined ? { query } : {}),
140
+ }, extra);
141
+ });
142
+ }
143
+ //# sourceMappingURL=transactions-search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transactions-search.js","sourceRoot":"","sources":["../../../src/tools/ingestion/transactions-search.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ // `match_rule_create` — curated POST /v1/contexts/{contextId}/rules.
2
+ //
3
+ // A typed, richly-described front door to defining a match rule within a
4
+ // reconciliation context, mirroring the spec's CreateMatchRuleRequest. The Zod
5
+ // schema models the required scalars (priority, type) and the documented type
6
+ // enum so an operator-driving LLM gets the shape and the semantics up front; the
7
+ // `config` object is type-specific and is modeled as a permissive open record
8
+ // (per the established pattern) — matcher's server-side validation + the returned
9
+ // RFC 9457 problem are the authoritative per-type check, so we do not duplicate
10
+ // it here.
11
+ //
12
+ // `contextId` is a routing path param, not a tenant field. No tenant field
13
+ // exists in the schema: the rule is created for the tenant of the relayed bearer
14
+ // token, and matcher validates that the context belongs to that tenant.
15
+ import { z } from 'zod';
16
+ import { contextRulesPath, dispatchMatchRule } from './shared.js';
17
+ /** Matching strategy. EXACT / TOLERANCE / DATE_LAG — there is no FUZZY. */
18
+ export const MATCH_RULE_TYPES = ['EXACT', 'TOLERANCE', 'DATE_LAG'];
19
+ /** Zod raw shape for `match_rule_create` input — mirrors CreateMatchRuleRequest. */
20
+ export const createMatchRuleInputShape = {
21
+ contextId: z
22
+ .string()
23
+ .min(1)
24
+ .describe('The reconciliation context id (UUID) the rule belongs to. Routing path ' +
25
+ 'param, not a tenant field — matcher validates the context is yours.'),
26
+ priority: z
27
+ .number()
28
+ .int()
29
+ .min(1)
30
+ .max(1000)
31
+ .describe('Execution priority (1–1000); lower numbers run first. Must be unique ' +
32
+ 'within the context.'),
33
+ type: z
34
+ .enum(MATCH_RULE_TYPES)
35
+ .describe('Matching strategy. EXACT requires identical field values; TOLERANCE ' +
36
+ 'allows configured numeric slack; DATE_LAG allows a configured date ' +
37
+ 'offset between sides.'),
38
+ config: z
39
+ .record(z.string(), z.unknown())
40
+ .describe('Rule-specific configuration object (matched fields and tolerance/lag ' +
41
+ 'parameters). Its shape depends on `type` and is validated server-side. ' +
42
+ 'EXACT: {"fields":["amount","reference"]}. TOLERANCE: ' +
43
+ '{"fields":["amount"],"toleranceAbs":"0.01"} or "tolerancePct". ' +
44
+ 'DATE_LAG: {"fields":["date"],"maxLagDays":2}.'),
45
+ };
46
+ /**
47
+ * Register `match_rule_create`. Splits the routing `contextId` (path) from the
48
+ * body fields and dispatches the POST through the shared fail-closed relay; a
49
+ * matcher error surfaces via the shared toToolError (same shape as matcher_invoke).
50
+ */
51
+ export function registerMatchRuleCreateTool(server) {
52
+ server.registerTool('match_rule_create', {
53
+ description: 'Create a match rule within a reconciliation context. Provide contextId ' +
54
+ '(UUID path), priority (1–1000, unique within the context), type ' +
55
+ '(EXACT|TOLERANCE|DATE_LAG), and config (a type-specific object validated ' +
56
+ 'server-side). No tenant field is accepted — the rule is created for your ' +
57
+ "token's tenant. Returns the created rule, or a structured RFC 9457 error.",
58
+ inputSchema: createMatchRuleInputShape,
59
+ }, async (args, extra) => {
60
+ const { contextId, ...body } = args;
61
+ return dispatchMatchRule({ method: 'POST', path: contextRulesPath(contextId), body }, extra);
62
+ });
63
+ }
64
+ //# sourceMappingURL=create.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.js","sourceRoot":"","sources":["../../../src/tools/match-rule/create.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,EAAE;AACF,yEAAyE;AACzE,+EAA+E;AAC/E,8EAA8E;AAC9E,iFAAiF;AACjF,8EAA8E;AAC9E,kFAAkF;AAClF,gFAAgF;AAChF,WAAW;AACX,EAAE;AACF,2EAA2E;AAC3E,iFAAiF;AACjF,wEAAwE;AAExE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAEjE,2EAA2E;AAC3E,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,OAAO,EAAE,WAAW,EAAE,UAAU,CAAU,CAAA;AAE3E,oFAAoF;AACpF,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACvC,SAAS,EAAE,CAAC;SACT,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,CACP,yEAAyE;QACvE,qEAAqE,CACxE;IACH,QAAQ,EAAE,CAAC;SACR,MAAM,EAAE;SACR,GAAG,EAAE;SACL,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,IAAI,CAAC;SACT,QAAQ,CACP,uEAAuE;QACrE,qBAAqB,CACxB;IACH,IAAI,EAAE,CAAC;SACJ,IAAI,CAAC,gBAAgB,CAAC;SACtB,QAAQ,CACP,sEAAsE;QACpE,qEAAqE;QACrE,uBAAuB,CAC1B;IACH,MAAM,EAAE,CAAC;SACN,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;SAC/B,QAAQ,CACP,uEAAuE;QACrE,yEAAyE;QACzE,uDAAuD;QACvD,iEAAiE;QACjE,+CAA+C,CAClD;CACJ,CAAA;AAOD;;;;GAIG;AACH,MAAM,UAAU,2BAA2B,CAAC,MAAiB;IAC3D,MAAM,CAAC,YAAY,CACjB,mBAAmB,EACnB;QACE,WAAW,EACT,yEAAyE;YACzE,kEAAkE;YAClE,2EAA2E;YAC3E,2EAA2E;YAC3E,2EAA2E;QAC7E,WAAW,EAAE,yBAAyB;KACvC,EACD,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;QACpB,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI,CAAA;QACnC,OAAO,iBAAiB,CACtB,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,EAC3D,KAAK,CACN,CAAA;IACH,CAAC,CACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,35 @@
1
+ // `match_rule_delete` — curated DELETE /v1/contexts/{contextId}/rules/{ruleId}.
2
+ //
3
+ // Removes a match rule by id within a context. A successful delete returns 204
4
+ // (no content), which the relay renders as null. Both contextId and ruleId are
5
+ // UUID path params; no tenant field is accepted (matcher scopes to the relayed
6
+ // token's tenant via the context).
7
+ import { z } from 'zod';
8
+ import { contextRulePath, dispatchMatchRule } from './shared.js';
9
+ /** Zod raw shape for `match_rule_delete` input — context id + rule id (both path). */
10
+ export const deleteMatchRuleInputShape = {
11
+ contextId: z
12
+ .string()
13
+ .min(1)
14
+ .describe('The reconciliation context id (UUID). Routing path param, not a tenant field.'),
15
+ ruleId: z.string().min(1).describe('The match rule id (UUID) to delete.'),
16
+ };
17
+ /**
18
+ * Register `match_rule_delete`. Substitutes both ids into the path and dispatches
19
+ * a DELETE through the shared fail-closed relay; any matcher error surfaces via
20
+ * the shared toToolError.
21
+ */
22
+ export function registerMatchRuleDeleteTool(server) {
23
+ server.registerTool('match_rule_delete', {
24
+ description: 'Delete a match rule by id (UUID) within a context (UUID). The rule and ' +
25
+ "its context must belong to your token's tenant (no tenant field is " +
26
+ 'accepted). Returns no content on success, or a structured RFC 9457 error.',
27
+ inputSchema: deleteMatchRuleInputShape,
28
+ }, async (args, extra) => {
29
+ return dispatchMatchRule({
30
+ method: 'DELETE',
31
+ path: contextRulePath(args.contextId, args.ruleId),
32
+ }, extra);
33
+ });
34
+ }
35
+ //# sourceMappingURL=delete.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delete.js","sourceRoot":"","sources":["../../../src/tools/match-rule/delete.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,EAAE;AACF,+EAA+E;AAC/E,+EAA+E;AAC/E,+EAA+E;AAC/E,mCAAmC;AAEnC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAEhE,sFAAsF;AACtF,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACvC,SAAS,EAAE,CAAC;SACT,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,CACP,+EAA+E,CAChF;IACH,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,qCAAqC,CAAC;CAC1E,CAAA;AAOD;;;;GAIG;AACH,MAAM,UAAU,2BAA2B,CAAC,MAAiB;IAC3D,MAAM,CAAC,YAAY,CACjB,mBAAmB,EACnB;QACE,WAAW,EACT,yEAAyE;YACzE,qEAAqE;YACrE,2EAA2E;QAC7E,WAAW,EAAE,yBAAyB;KACvC,EACD,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;QACpB,OAAO,iBAAiB,CACtB;YACE,MAAM,EAAE,QAAQ;YAChB,IAAI,EAAE,eAAe,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC;SACnD,EACD,KAAK,CACN,CAAA;IACH,CAAC,CACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,32 @@
1
+ // `match_rule_get` — curated GET /v1/contexts/{contextId}/rules/{ruleId}.
2
+ //
3
+ // Reads one match rule by id within a context. Both contextId and ruleId are
4
+ // path params (UUIDs). The rule must belong to a context owned by the relayed
5
+ // token's tenant — matcher enforces that; no tenant field is accepted.
6
+ import { z } from 'zod';
7
+ import { contextRulePath, dispatchMatchRule } from './shared.js';
8
+ /** Zod raw shape for `match_rule_get` input — context id + rule id (both path). */
9
+ export const getMatchRuleInputShape = {
10
+ contextId: z
11
+ .string()
12
+ .min(1)
13
+ .describe('The reconciliation context id (UUID). Routing path param, not a tenant field.'),
14
+ ruleId: z.string().min(1).describe('The match rule id (UUID) to fetch.'),
15
+ };
16
+ /**
17
+ * Register `match_rule_get`. Substitutes both ids into the path and dispatches a
18
+ * GET through the shared fail-closed relay; a matcher error (e.g. 404) surfaces
19
+ * via the shared toToolError.
20
+ */
21
+ export function registerMatchRuleGetTool(server) {
22
+ server.registerTool('match_rule_get', {
23
+ description: 'Fetch a single match rule by id (UUID) within a context (UUID). Both ' +
24
+ 'the rule and its context must belong to your token. Returns the rule, ' +
25
+ 'or a structured RFC 9457 error (e.g. 404 if it does not exist or is not ' +
26
+ 'yours).',
27
+ inputSchema: getMatchRuleInputShape,
28
+ }, async (args, extra) => {
29
+ return dispatchMatchRule({ method: 'GET', path: contextRulePath(args.contextId, args.ruleId) }, extra);
30
+ });
31
+ }
32
+ //# sourceMappingURL=get.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get.js","sourceRoot":"","sources":["../../../src/tools/match-rule/get.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,EAAE;AACF,6EAA6E;AAC7E,8EAA8E;AAC9E,uEAAuE;AAEvE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAEhE,mFAAmF;AACnF,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,SAAS,EAAE,CAAC;SACT,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,CACP,+EAA+E,CAChF;IACH,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,oCAAoC,CAAC;CACzE,CAAA;AAOD;;;;GAIG;AACH,MAAM,UAAU,wBAAwB,CAAC,MAAiB;IACxD,MAAM,CAAC,YAAY,CACjB,gBAAgB,EAChB;QACE,WAAW,EACT,uEAAuE;YACvE,wEAAwE;YACxE,0EAA0E;YAC1E,SAAS;QACX,WAAW,EAAE,sBAAsB;KACpC,EACD,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;QACpB,OAAO,iBAAiB,CACtB,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,eAAe,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,EACrE,KAAK,CACN,CAAA;IACH,CAAC,CACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,22 @@
1
+ // Curated match-rule vertical (task 2.1.2): six typed tools over the matcher
2
+ // match-rule resource — create, list, get, update, delete, reorder. All ops are
3
+ // fully context-nested (/v1/contexts/{contextId}/rules[...]). Each tool shares
4
+ // the fail-closed relay (shared.ts) and the RFC 9457 → tool-error mapping
5
+ // (toToolError) with the generic surface, so curated and generic map matcher
6
+ // errors identically. No tool carries a tenant field.
7
+ import { registerMatchRuleCreateTool } from './create.js';
8
+ import { registerMatchRuleDeleteTool } from './delete.js';
9
+ import { registerMatchRuleGetTool } from './get.js';
10
+ import { registerMatchRuleListTool } from './list.js';
11
+ import { registerMatchRuleReorderTool } from './reorder.js';
12
+ import { registerMatchRuleUpdateTool } from './update.js';
13
+ /** Register all six curated match-rule tools on the given server. */
14
+ export function registerMatchRuleTools(server) {
15
+ registerMatchRuleCreateTool(server);
16
+ registerMatchRuleListTool(server);
17
+ registerMatchRuleGetTool(server);
18
+ registerMatchRuleUpdateTool(server);
19
+ registerMatchRuleDeleteTool(server);
20
+ registerMatchRuleReorderTool(server);
21
+ }
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/match-rule/index.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,gFAAgF;AAChF,+EAA+E;AAC/E,0EAA0E;AAC1E,6EAA6E;AAC7E,sDAAsD;AAItD,OAAO,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAA;AACzD,OAAO,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAA;AACzD,OAAO,EAAE,wBAAwB,EAAE,MAAM,UAAU,CAAA;AACnD,OAAO,EAAE,yBAAyB,EAAE,MAAM,WAAW,CAAA;AACrD,OAAO,EAAE,4BAA4B,EAAE,MAAM,cAAc,CAAA;AAC3D,OAAO,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAA;AAEzD,qEAAqE;AACrE,MAAM,UAAU,sBAAsB,CAAC,MAAiB;IACtD,2BAA2B,CAAC,MAAM,CAAC,CAAA;IACnC,yBAAyB,CAAC,MAAM,CAAC,CAAA;IACjC,wBAAwB,CAAC,MAAM,CAAC,CAAA;IAChC,2BAA2B,CAAC,MAAM,CAAC,CAAA;IACnC,2BAA2B,CAAC,MAAM,CAAC,CAAA;IACnC,4BAA4B,CAAC,MAAM,CAAC,CAAA;AACtC,CAAC"}
@@ -0,0 +1,72 @@
1
+ // `match_rule_list` — curated GET /v1/contexts/{contextId}/rules.
2
+ //
3
+ // Cursor-paginated list of a context's match rules, with an optional `type`
4
+ // filter. limit/cursor/type pass through untouched and matcher's
5
+ // { items, nextCursor, ... } envelope is returned as-is — no auto-pagination
6
+ // (the model re-calls with the returned cursor). The list is implicitly
7
+ // tenant-scoped by the relayed token; `contextId` is a routing path param and no
8
+ // tenant field is accepted.
9
+ import { z } from 'zod';
10
+ import { MATCH_RULE_TYPES } from './create.js';
11
+ import { contextRulesPath, dispatchMatchRule } from './shared.js';
12
+ /** Zod raw shape for `match_rule_list` input — context, optional type filter, pagination. */
13
+ export const listMatchRulesInputShape = {
14
+ contextId: z
15
+ .string()
16
+ .min(1)
17
+ .describe('The reconciliation context id (UUID) whose rules to list. Routing path ' +
18
+ 'param, not a tenant field.'),
19
+ type: z
20
+ .enum(MATCH_RULE_TYPES)
21
+ .optional()
22
+ .describe('Optional filter by rule type (EXACT|TOLERANCE|DATE_LAG). Omit to list all.'),
23
+ limit: z
24
+ .number()
25
+ .int()
26
+ .min(1)
27
+ .max(200)
28
+ .optional()
29
+ .describe('Maximum number of records to return (1–200, default 20).'),
30
+ cursor: z
31
+ .string()
32
+ .optional()
33
+ .describe('Opaque pagination cursor from a prior response. Re-call with the ' +
34
+ 'returned nextCursor to page forward (there is no auto-pagination).'),
35
+ };
36
+ /** Build the list query, omitting unset knobs so the request stays minimal. */
37
+ function buildListQuery(args) {
38
+ const query = {};
39
+ if (args.type !== undefined) {
40
+ query.type = args.type;
41
+ }
42
+ if (args.limit !== undefined) {
43
+ query.limit = args.limit;
44
+ }
45
+ if (args.cursor !== undefined) {
46
+ query.cursor = args.cursor;
47
+ }
48
+ return Object.keys(query).length > 0 ? query : undefined;
49
+ }
50
+ /**
51
+ * Register `match_rule_list`. Passes type/limit/cursor through and returns
52
+ * matcher's pagination envelope verbatim; a matcher error surfaces via the
53
+ * shared toToolError.
54
+ */
55
+ export function registerMatchRuleListTool(server) {
56
+ server.registerTool('match_rule_list', {
57
+ description: 'List the match rules of a reconciliation context (cursor-paginated). ' +
58
+ 'Provide contextId (UUID path); optionally filter by type ' +
59
+ '(EXACT|TOLERANCE|DATE_LAG) and pass limit (1–200) and/or cursor. The ' +
60
+ 'response carries { items, nextCursor } — paginate by re-calling with the ' +
61
+ 'returned nextCursor. No tenant field is accepted.',
62
+ inputSchema: listMatchRulesInputShape,
63
+ }, async (args, extra) => {
64
+ const query = buildListQuery(args);
65
+ return dispatchMatchRule({
66
+ method: 'GET',
67
+ path: contextRulesPath(args.contextId),
68
+ ...(query !== undefined ? { query } : {}),
69
+ }, extra);
70
+ });
71
+ }
72
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/tools/match-rule/list.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,EAAE;AACF,4EAA4E;AAC5E,iEAAiE;AACjE,6EAA6E;AAC7E,wEAAwE;AACxE,iFAAiF;AACjF,4BAA4B;AAE5B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAKvB,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAC9C,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAEjE,6FAA6F;AAC7F,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC,SAAS,EAAE,CAAC;SACT,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,CACP,yEAAyE;QACvE,4BAA4B,CAC/B;IACH,IAAI,EAAE,CAAC;SACJ,IAAI,CAAC,gBAAgB,CAAC;SACtB,QAAQ,EAAE;SACV,QAAQ,CACP,4EAA4E,CAC7E;IACH,KAAK,EAAE,CAAC;SACL,MAAM,EAAE;SACR,GAAG,EAAE;SACL,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,GAAG,CAAC;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,0DAA0D,CAAC;IACvE,MAAM,EAAE,CAAC;SACN,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CACP,mEAAmE;QACjE,oEAAoE,CACvE;CACJ,CAAA;AAOD,+EAA+E;AAC/E,SAAS,cAAc,CAAC,IAAyB;IAC/C,MAAM,KAAK,GAAoC,EAAE,CAAA;IACjD,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC5B,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAA;IACxB,CAAC;IACD,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAC7B,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAA;IAC1B,CAAC;IACD,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC9B,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;IAC5B,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAA;AAC1D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,yBAAyB,CAAC,MAAiB;IACzD,MAAM,CAAC,YAAY,CACjB,iBAAiB,EACjB;QACE,WAAW,EACT,uEAAuE;YACvE,2DAA2D;YAC3D,uEAAuE;YACvE,2EAA2E;YAC3E,mDAAmD;QACrD,WAAW,EAAE,wBAAwB;KACtC,EACD,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;QACpB,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,CAAA;QAClC,OAAO,iBAAiB,CACtB;YACE,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,gBAAgB,CAAC,IAAI,CAAC,SAAS,CAAC;YACtC,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC1C,EACD,KAAK,CACN,CAAA;IACH,CAAC,CACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,45 @@
1
+ // `match_rule_reorder` — curated POST /v1/contexts/{contextId}/rules/reorder.
2
+ //
3
+ // A custom action (not CRUD): re-prioritizes a context's match rules in one
4
+ // shot. The body carries an ordered `ruleIds` array — each rule's new priority
5
+ // is its position in that list (first = highest priority / runs first). Returns
6
+ // 204 (no content), which the relay renders as null. `contextId` is a routing
7
+ // path param; no tenant field is accepted.
8
+ import { z } from 'zod';
9
+ import { contextRulesReorderPath, dispatchMatchRule } from './shared.js';
10
+ /** Zod raw shape for `match_rule_reorder` input — context (path) + ordered ruleIds. */
11
+ export const reorderMatchRulesInputShape = {
12
+ contextId: z
13
+ .string()
14
+ .min(1)
15
+ .describe('The reconciliation context id (UUID) whose rules to reorder. Routing path ' +
16
+ 'param, not a tenant field.'),
17
+ ruleIds: z
18
+ .array(z.string().min(1))
19
+ .min(1)
20
+ .max(100)
21
+ .describe('Ordered list of match rule UUIDs (1–100). Each rule’s new priority is ' +
22
+ 'its position in this list: the first id runs first. Include every rule ' +
23
+ 'you intend to reorder.'),
24
+ };
25
+ /**
26
+ * Register `match_rule_reorder`. Splits the routing `contextId` (path) from the
27
+ * `ruleIds` body and dispatches the POST through the shared fail-closed relay; a
28
+ * matcher error surfaces via the shared toToolError.
29
+ */
30
+ export function registerMatchRuleReorderTool(server) {
31
+ server.registerTool('match_rule_reorder', {
32
+ description: 'Reorder the match rules of a reconciliation context. Provide contextId ' +
33
+ '(UUID path) and ruleIds, an ordered array of rule UUIDs whose position ' +
34
+ 'becomes the new priority (first = runs first). No tenant field is ' +
35
+ 'accepted. Returns no content on success, or a structured RFC 9457 error.',
36
+ inputSchema: reorderMatchRulesInputShape,
37
+ }, async (args, extra) => {
38
+ return dispatchMatchRule({
39
+ method: 'POST',
40
+ path: contextRulesReorderPath(args.contextId),
41
+ body: { ruleIds: args.ruleIds },
42
+ }, extra);
43
+ });
44
+ }
45
+ //# sourceMappingURL=reorder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reorder.js","sourceRoot":"","sources":["../../../src/tools/match-rule/reorder.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,EAAE;AACF,4EAA4E;AAC5E,+EAA+E;AAC/E,gFAAgF;AAChF,8EAA8E;AAC9E,2CAA2C;AAE3C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB,OAAO,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAExE,uFAAuF;AACvF,MAAM,CAAC,MAAM,2BAA2B,GAAG;IACzC,SAAS,EAAE,CAAC;SACT,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,CACP,4EAA4E;QAC1E,4BAA4B,CAC/B;IACH,OAAO,EAAE,CAAC;SACP,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;SACxB,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,GAAG,CAAC;SACR,QAAQ,CACP,wEAAwE;QACtE,yEAAyE;QACzE,wBAAwB,CAC3B;CACJ,CAAA;AAOD;;;;GAIG;AACH,MAAM,UAAU,4BAA4B,CAAC,MAAiB;IAC5D,MAAM,CAAC,YAAY,CACjB,oBAAoB,EACpB;QACE,WAAW,EACT,yEAAyE;YACzE,yEAAyE;YACzE,oEAAoE;YACpE,0EAA0E;QAC5E,WAAW,EAAE,2BAA2B;KACzC,EACD,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;QACpB,OAAO,iBAAiB,CACtB;YACE,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,uBAAuB,CAAC,IAAI,CAAC,SAAS,CAAC;YAC7C,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE;SAChC,EACD,KAAK,CACN,CAAA;IACH,CAAC,CACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,71 @@
1
+ // Shared plumbing for the curated match-rule tools.
2
+ //
3
+ // Match rules are fully context-nested: every op lives under
4
+ // /v1/contexts/{contextId}/rules (list/create), .../rules/{ruleId}
5
+ // (get/update/delete), and .../rules/reorder (the custom reorder action). This
6
+ // module factors the path construction and the relay/error-mapping boilerplate
7
+ // exactly once so the six tools stay thin — they only "build the request".
8
+ //
9
+ // The relay shape is identical to the fee-schedule vertical (task 1.3.2): fail
10
+ // closed via requireMatcherClient, dispatch one assembled MatcherRequest, then
11
+ // return matcher's JSON on success or the SHARED toToolError on a
12
+ // MatcherApiError. Curated and generic surfaces therefore map matcher errors
13
+ // through the same path.
14
+ //
15
+ // Security: the bearer token is never read here directly — requireMatcherClient
16
+ // owns the request-scoped relay and fails closed when no usable credential was
17
+ // provided. No tenant identifier is ever read or injected (matcher derives
18
+ // tenant from the relayed JWT); no match-rule tool input carries one. The
19
+ // `contextId` segment is a routing path param — matcher validates that the
20
+ // context belongs to the token's tenant.
21
+ import { requireMatcherClient, UnauthenticatedError, } from '../../auth/request-token.js';
22
+ import { isMatcherApiError, toToolError } from '../tool-error.js';
23
+ /** Path for the match-rule collection under a context (list + create). */
24
+ export function contextRulesPath(contextId) {
25
+ return `/v1/contexts/${encodeURIComponent(contextId)}/rules`;
26
+ }
27
+ /** Path for a single match rule under a context (get + update + delete). */
28
+ export function contextRulePath(contextId, ruleId) {
29
+ return `${contextRulesPath(contextId)}/${encodeURIComponent(ruleId)}`;
30
+ }
31
+ /** Path for the reorder action under a context's match rules. */
32
+ export function contextRulesReorderPath(contextId) {
33
+ return `${contextRulesPath(contextId)}/reorder`;
34
+ }
35
+ /**
36
+ * Run one assembled request through the relay: fail-closed auth, dispatch, and
37
+ * RFC 9457 → tool-error mapping — identical to the generic invoke's dispatch so
38
+ * both surfaces produce the same structured error shape.
39
+ *
40
+ * `clientFor` is injectable for tests; production callers pass nothing and get
41
+ * the request-scoped, fail-closed `requireMatcherClient`.
42
+ */
43
+ export async function dispatchMatchRule(request, extra, clientFor = requireMatcherClient) {
44
+ let client;
45
+ try {
46
+ // Fail-closed on a missing / empty / non-Bearer credential.
47
+ client = clientFor(extra);
48
+ }
49
+ catch (err) {
50
+ if (err instanceof UnauthenticatedError) {
51
+ return { isError: true, content: [{ type: 'text', text: err.message }] };
52
+ }
53
+ throw err;
54
+ }
55
+ try {
56
+ const result = await client.request(request);
57
+ // Success → matcher's JSON returned as-is (incl. pagination envelopes and
58
+ // 204 → null for delete / reorder).
59
+ return { content: [{ type: 'text', text: JSON.stringify(result ?? null) }] };
60
+ }
61
+ catch (err) {
62
+ // RFC 9457 problem → the SHARED structured tool error (status/title/detail/
63
+ // code preserved). A non-matcher error is a bug, not a matcher failure, and
64
+ // is re-thrown rather than masqueraded as one.
65
+ if (isMatcherApiError(err)) {
66
+ return toToolError(err);
67
+ }
68
+ throw err;
69
+ }
70
+ }
71
+ //# sourceMappingURL=shared.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../src/tools/match-rule/shared.ts"],"names":[],"mappings":"AAAA,oDAAoD;AACpD,EAAE;AACF,6DAA6D;AAC7D,mEAAmE;AACnE,+EAA+E;AAC/E,+EAA+E;AAC/E,2EAA2E;AAC3E,EAAE;AACF,+EAA+E;AAC/E,+EAA+E;AAC/E,kEAAkE;AAClE,6EAA6E;AAC7E,yBAAyB;AACzB,EAAE;AACF,gFAAgF;AAChF,+EAA+E;AAC/E,2EAA2E;AAC3E,0EAA0E;AAC1E,2EAA2E;AAC3E,yCAAyC;AAIzC,OAAO,EACL,oBAAoB,EACpB,oBAAoB,GAErB,MAAM,6BAA6B,CAAA;AAEpC,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAEjE,0EAA0E;AAC1E,MAAM,UAAU,gBAAgB,CAAC,SAAiB;IAChD,OAAO,gBAAgB,kBAAkB,CAAC,SAAS,CAAC,QAAQ,CAAA;AAC9D,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,eAAe,CAAC,SAAiB,EAAE,MAAc;IAC/D,OAAO,GAAG,gBAAgB,CAAC,SAAS,CAAC,IAAI,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAA;AACvE,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,uBAAuB,CAAC,SAAiB;IACvD,OAAO,GAAG,gBAAgB,CAAC,SAAS,CAAC,UAAU,CAAA;AACjD,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,OAAuB,EACvB,KAAmC,EACnC,YAAyD,oBAAoB;IAE7E,IAAI,MAAqB,CAAA;IACzB,IAAI,CAAC;QACH,4DAA4D;QAC5D,MAAM,GAAG,SAAS,CAAC,KAAK,CAAC,CAAA;IAC3B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,oBAAoB,EAAE,CAAC;YACxC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,EAAE,CAAA;QAC1E,CAAC;QACD,MAAM,GAAG,CAAA;IACX,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;QAC5C,0EAA0E;QAC1E,oCAAoC;QACpC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,IAAI,IAAI,CAAC,EAAE,CAAC,EAAE,CAAA;IAC9E,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,4EAA4E;QAC5E,4EAA4E;QAC5E,+CAA+C;QAC/C,IAAI,iBAAiB,CAAC,GAAG,CAAC,EAAE,CAAC;YAC3B,OAAO,WAAW,CAAC,GAAG,CAAC,CAAA;QACzB,CAAC;QACD,MAAM,GAAG,CAAA;IACX,CAAC;AACH,CAAC"}
@@ -0,0 +1,68 @@
1
+ // `match_rule_update` — curated PATCH /v1/contexts/{contextId}/rules/{ruleId}.
2
+ //
3
+ // Partial update of a match rule, mirroring the spec's UpdateMatchRuleRequest.
4
+ // All body fields are optional (PATCH semantics): priority, type, config. Both
5
+ // contextId and ruleId are UUID path params; no tenant field is accepted
6
+ // (matcher scopes to the relayed token's tenant via the context).
7
+ import { z } from 'zod';
8
+ import { MATCH_RULE_TYPES } from './create.js';
9
+ import { contextRulePath, dispatchMatchRule } from './shared.js';
10
+ /** Zod raw shape for `match_rule_update` input — ids (path) + optional fields. */
11
+ export const updateMatchRuleInputShape = {
12
+ contextId: z
13
+ .string()
14
+ .min(1)
15
+ .describe('The reconciliation context id (UUID). Routing path param, not a tenant field.'),
16
+ ruleId: z.string().min(1).describe('The match rule id (UUID) to update.'),
17
+ priority: z
18
+ .number()
19
+ .int()
20
+ .min(1)
21
+ .max(1000)
22
+ .optional()
23
+ .describe('New execution priority (1–1000); lower runs first. Must remain unique ' +
24
+ 'within the context.'),
25
+ type: z
26
+ .enum(MATCH_RULE_TYPES)
27
+ .optional()
28
+ .describe('New matching strategy (EXACT|TOLERANCE|DATE_LAG). Changing type usually ' +
29
+ 'requires a matching `config` change.'),
30
+ config: z
31
+ .record(z.string(), z.unknown())
32
+ .optional()
33
+ .describe('New rule-specific configuration object (matched fields and tolerance/lag ' +
34
+ 'parameters). Shape depends on `type`; validated server-side.'),
35
+ };
36
+ /**
37
+ * Build the PATCH body from the input minus the path-only `contextId`/`ruleId`.
38
+ * Only the fields the caller actually set are sent — matcher treats absent
39
+ * fields as unchanged.
40
+ */
41
+ export function buildUpdateBody(args) {
42
+ const { contextId: _contextId, ruleId: _ruleId, ...body } = args;
43
+ void _contextId;
44
+ void _ruleId;
45
+ return body;
46
+ }
47
+ /**
48
+ * Register `match_rule_update`. Splits the ids (path) from the body fields and
49
+ * dispatches a PATCH through the shared fail-closed relay; a matcher error
50
+ * surfaces via the shared toToolError.
51
+ */
52
+ export function registerMatchRuleUpdateTool(server) {
53
+ server.registerTool('match_rule_update', {
54
+ description: 'Update a match rule by id (UUID) within a context (UUID). All fields are ' +
55
+ 'optional (PATCH): priority (1–1000, unique), type ' +
56
+ '(EXACT|TOLERANCE|DATE_LAG), config (type-specific, validated server-side). ' +
57
+ 'No tenant field is accepted. Returns the updated rule, or a structured ' +
58
+ 'RFC 9457 error.',
59
+ inputSchema: updateMatchRuleInputShape,
60
+ }, async (args, extra) => {
61
+ return dispatchMatchRule({
62
+ method: 'PATCH',
63
+ path: contextRulePath(args.contextId, args.ruleId),
64
+ body: buildUpdateBody(args),
65
+ }, extra);
66
+ });
67
+ }
68
+ //# sourceMappingURL=update.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.js","sourceRoot":"","sources":["../../../src/tools/match-rule/update.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,EAAE;AACF,+EAA+E;AAC/E,+EAA+E;AAC/E,yEAAyE;AACzE,kEAAkE;AAElE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAC9C,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAEhE,kFAAkF;AAClF,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACvC,SAAS,EAAE,CAAC;SACT,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,CACP,+EAA+E,CAChF;IACH,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,qCAAqC,CAAC;IACzE,QAAQ,EAAE,CAAC;SACR,MAAM,EAAE;SACR,GAAG,EAAE;SACL,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,IAAI,CAAC;SACT,QAAQ,EAAE;SACV,QAAQ,CACP,wEAAwE;QACtE,qBAAqB,CACxB;IACH,IAAI,EAAE,CAAC;SACJ,IAAI,CAAC,gBAAgB,CAAC;SACtB,QAAQ,EAAE;SACV,QAAQ,CACP,0EAA0E;QACxE,sCAAsC,CACzC;IACH,MAAM,EAAE,CAAC;SACN,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;SAC/B,QAAQ,EAAE;SACV,QAAQ,CACP,2EAA2E;QACzE,8DAA8D,CACjE;CACJ,CAAA;AAOD;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAC7B,IAA0B;IAE1B,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI,CAAA;IAChE,KAAK,UAAU,CAAA;IACf,KAAK,OAAO,CAAA;IACZ,OAAO,IAAI,CAAA;AACb,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,2BAA2B,CAAC,MAAiB;IAC3D,MAAM,CAAC,YAAY,CACjB,mBAAmB,EACnB;QACE,WAAW,EACT,2EAA2E;YAC3E,oDAAoD;YACpD,6EAA6E;YAC7E,yEAAyE;YACzE,iBAAiB;QACnB,WAAW,EAAE,yBAAyB;KACvC,EACD,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;QACpB,OAAO,iBAAiB,CACtB;YACE,MAAM,EAAE,OAAO;YACf,IAAI,EAAE,eAAe,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC;YAClD,IAAI,EAAE,eAAe,CAAC,IAAI,CAAC;SAC5B,EACD,KAAK,CACN,CAAA;IACH,CAAC,CACF,CAAA;AACH,CAAC"}