@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,46 @@
1
+ // `report_export_exceptions` — curated GET
2
+ // /v1/reports/contexts/{contextId}/exceptions/export.
3
+ //
4
+ // Synchronously exports the exceptions report as a single base64-encoded file
5
+ // (CSV or PDF) for the given date window. This is an HTTP GET — the date filter
6
+ // and the csv|pdf format are query params, not a POST body. matcher returns the
7
+ // file as a base64 STRING inline in the JSON response; the dispatch passes it
8
+ // through verbatim (it is NOT decoded here — the caller decodes it). The export
9
+ // is implicitly tenant-scoped by the relayed token; contextId is a routing path
10
+ // param, not a tenant field, and no tenant field is accepted.
11
+ import { z } from 'zod';
12
+ import { buildReportExportQuery, contextReportPath, dispatchReport, reportFilterInputShape, reportFormatInputShape, } from './shared.js';
13
+ /** Zod raw shape for `report_export_exceptions` input — contextId path + filter + format. */
14
+ export const exportExceptionsInputShape = {
15
+ contextId: z
16
+ .string()
17
+ .min(1)
18
+ .describe('The reconciliation context id (UUID) whose exceptions to export. ' +
19
+ 'Routing path param, not a tenant field.'),
20
+ ...reportFilterInputShape,
21
+ ...reportFormatInputShape,
22
+ };
23
+ /**
24
+ * Register `report_export_exceptions`. Passes the date filter + format through
25
+ * and returns matcher's base64 file string verbatim (the caller decodes it); a
26
+ * matcher error surfaces via the shared toToolError.
27
+ */
28
+ export function registerReportExportExceptionsTool(server) {
29
+ server.registerTool('report_export_exceptions', {
30
+ description: 'Export the exceptions report for a context within a date window as a ' +
31
+ 'CSV or PDF file. Pass contextId (UUID path param — not a tenant field), ' +
32
+ 'and optionally date_from/date_to (YYYY-MM-DD, window ≤ 90 days), ' +
33
+ 'source_id, and format (csv|pdf, default csv). The result is a ' +
34
+ 'base64-encoded string — decode it to recover the file bytes. No tenant ' +
35
+ 'field is accepted.',
36
+ inputSchema: exportExceptionsInputShape,
37
+ }, async (args, extra) => {
38
+ const query = buildReportExportQuery(args);
39
+ return dispatchReport({
40
+ method: 'GET',
41
+ path: contextReportPath(args.contextId, 'exceptions/export'),
42
+ ...(query !== undefined ? { query } : {}),
43
+ }, extra);
44
+ });
45
+ }
46
+ //# sourceMappingURL=export-exceptions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export-exceptions.js","sourceRoot":"","sources":["../../../src/tools/report/export-exceptions.ts"],"names":[],"mappings":"AAAA,2CAA2C;AAC3C,sDAAsD;AACtD,EAAE;AACF,8EAA8E;AAC9E,gFAAgF;AAChF,gFAAgF;AAChF,8EAA8E;AAC9E,gFAAgF;AAChF,gFAAgF;AAChF,8DAA8D;AAE9D,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB,OAAO,EACL,sBAAsB,EACtB,iBAAiB,EACjB,cAAc,EACd,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,aAAa,CAAA;AAEpB,6FAA6F;AAC7F,MAAM,CAAC,MAAM,0BAA0B,GAAG;IACxC,SAAS,EAAE,CAAC;SACT,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,CACP,mEAAmE;QACjE,yCAAyC,CAC5C;IACH,GAAG,sBAAsB;IACzB,GAAG,sBAAsB;CAC1B,CAAA;AAOD;;;;GAIG;AACH,MAAM,UAAU,kCAAkC,CAAC,MAAiB;IAClE,MAAM,CAAC,YAAY,CACjB,0BAA0B,EAC1B;QACE,WAAW,EACT,uEAAuE;YACvE,0EAA0E;YAC1E,mEAAmE;YACnE,gEAAgE;YAChE,yEAAyE;YACzE,oBAAoB;QACtB,WAAW,EAAE,0BAA0B;KACxC,EACD,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;QACpB,MAAM,KAAK,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAA;QAC1C,OAAO,cAAc,CACnB;YACE,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,iBAAiB,CAAC,IAAI,CAAC,SAAS,EAAE,mBAAmB,CAAC;YAC5D,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,47 @@
1
+ // `report_export_matched` — curated GET
2
+ // /v1/reports/contexts/{contextId}/matched/export.
3
+ //
4
+ // Synchronously exports the matched-transactions report as a single
5
+ // base64-encoded file (CSV or PDF) for the given date window. This is an HTTP
6
+ // GET — the date filter and the csv|pdf format are query params, not a POST
7
+ // body. matcher returns the file as a base64 STRING inline in the JSON
8
+ // response; the dispatch passes it through verbatim (it is NOT decoded here —
9
+ // the caller decodes it). The export is implicitly tenant-scoped by the relayed
10
+ // token; contextId is a routing path param, not a tenant field, and no tenant
11
+ // field is accepted.
12
+ import { z } from 'zod';
13
+ import { buildReportExportQuery, contextReportPath, dispatchReport, reportFilterInputShape, reportFormatInputShape, } from './shared.js';
14
+ /** Zod raw shape for `report_export_matched` input — contextId path + filter + format. */
15
+ export const exportMatchedInputShape = {
16
+ contextId: z
17
+ .string()
18
+ .min(1)
19
+ .describe('The reconciliation context id (UUID) whose matched transactions to ' +
20
+ 'export. Routing path param, not a tenant field.'),
21
+ ...reportFilterInputShape,
22
+ ...reportFormatInputShape,
23
+ };
24
+ /**
25
+ * Register `report_export_matched`. Passes the date filter + format through and
26
+ * returns matcher's base64 file string verbatim (the caller decodes it); a
27
+ * matcher error surfaces via the shared toToolError.
28
+ */
29
+ export function registerReportExportMatchedTool(server) {
30
+ server.registerTool('report_export_matched', {
31
+ description: 'Export the matched-transactions report for a context within a date ' +
32
+ 'window as a CSV or PDF file. Pass contextId (UUID path param — not a ' +
33
+ 'tenant field), and optionally date_from/date_to (YYYY-MM-DD, window ≤ ' +
34
+ '90 days), source_id, and format (csv|pdf, default csv). The result is a ' +
35
+ 'base64-encoded string — decode it to recover the file bytes. No tenant ' +
36
+ 'field is accepted.',
37
+ inputSchema: exportMatchedInputShape,
38
+ }, async (args, extra) => {
39
+ const query = buildReportExportQuery(args);
40
+ return dispatchReport({
41
+ method: 'GET',
42
+ path: contextReportPath(args.contextId, 'matched/export'),
43
+ ...(query !== undefined ? { query } : {}),
44
+ }, extra);
45
+ });
46
+ }
47
+ //# sourceMappingURL=export-matched.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export-matched.js","sourceRoot":"","sources":["../../../src/tools/report/export-matched.ts"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,mDAAmD;AACnD,EAAE;AACF,oEAAoE;AACpE,8EAA8E;AAC9E,4EAA4E;AAC5E,uEAAuE;AACvE,8EAA8E;AAC9E,gFAAgF;AAChF,8EAA8E;AAC9E,qBAAqB;AAErB,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB,OAAO,EACL,sBAAsB,EACtB,iBAAiB,EACjB,cAAc,EACd,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,aAAa,CAAA;AAEpB,0FAA0F;AAC1F,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,SAAS,EAAE,CAAC;SACT,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,CACP,qEAAqE;QACnE,iDAAiD,CACpD;IACH,GAAG,sBAAsB;IACzB,GAAG,sBAAsB;CAC1B,CAAA;AAOD;;;;GAIG;AACH,MAAM,UAAU,+BAA+B,CAAC,MAAiB;IAC/D,MAAM,CAAC,YAAY,CACjB,uBAAuB,EACvB;QACE,WAAW,EACT,qEAAqE;YACrE,uEAAuE;YACvE,wEAAwE;YACxE,0EAA0E;YAC1E,yEAAyE;YACzE,oBAAoB;QACtB,WAAW,EAAE,uBAAuB;KACrC,EACD,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;QACpB,MAAM,KAAK,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAA;QAC1C,OAAO,cAAc,CACnB;YACE,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,iBAAiB,CAAC,IAAI,CAAC,SAAS,EAAE,gBAAgB,CAAC;YACzD,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,47 @@
1
+ // `report_export_summary` — curated GET
2
+ // /v1/reports/contexts/{contextId}/summary/export.
3
+ //
4
+ // Synchronously exports the reconciliation summary report as a single
5
+ // base64-encoded file (CSV or PDF) for the given date window. This is an HTTP
6
+ // GET — the date filter and the csv|pdf format are query params, not a POST
7
+ // body. matcher returns the file as a base64 STRING inline in the JSON
8
+ // response; the dispatch passes it through verbatim (it is NOT decoded here —
9
+ // the caller decodes it). The export is implicitly tenant-scoped by the relayed
10
+ // token; contextId is a routing path param, not a tenant field, and no tenant
11
+ // field is accepted.
12
+ import { z } from 'zod';
13
+ import { buildReportExportQuery, contextReportPath, dispatchReport, reportFilterInputShape, reportFormatInputShape, } from './shared.js';
14
+ /** Zod raw shape for `report_export_summary` input — contextId path + filter + format. */
15
+ export const exportSummaryInputShape = {
16
+ contextId: z
17
+ .string()
18
+ .min(1)
19
+ .describe('The reconciliation context id (UUID) to export the summary for. Routing ' +
20
+ 'path param, not a tenant field.'),
21
+ ...reportFilterInputShape,
22
+ ...reportFormatInputShape,
23
+ };
24
+ /**
25
+ * Register `report_export_summary`. Passes the date filter + format through and
26
+ * returns matcher's base64 file string verbatim (the caller decodes it); a
27
+ * matcher error surfaces via the shared toToolError.
28
+ */
29
+ export function registerReportExportSummaryTool(server) {
30
+ server.registerTool('report_export_summary', {
31
+ description: 'Export the reconciliation summary report for a context within a date ' +
32
+ 'window as a CSV or PDF file. Pass contextId (UUID path param — not a ' +
33
+ 'tenant field), and optionally date_from/date_to (YYYY-MM-DD, window ≤ ' +
34
+ '90 days), source_id, and format (csv|pdf, default csv). The result is a ' +
35
+ 'base64-encoded string — decode it to recover the file bytes. No tenant ' +
36
+ 'field is accepted.',
37
+ inputSchema: exportSummaryInputShape,
38
+ }, async (args, extra) => {
39
+ const query = buildReportExportQuery(args);
40
+ return dispatchReport({
41
+ method: 'GET',
42
+ path: contextReportPath(args.contextId, 'summary/export'),
43
+ ...(query !== undefined ? { query } : {}),
44
+ }, extra);
45
+ });
46
+ }
47
+ //# sourceMappingURL=export-summary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export-summary.js","sourceRoot":"","sources":["../../../src/tools/report/export-summary.ts"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,mDAAmD;AACnD,EAAE;AACF,sEAAsE;AACtE,8EAA8E;AAC9E,4EAA4E;AAC5E,uEAAuE;AACvE,8EAA8E;AAC9E,gFAAgF;AAChF,8EAA8E;AAC9E,qBAAqB;AAErB,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB,OAAO,EACL,sBAAsB,EACtB,iBAAiB,EACjB,cAAc,EACd,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,aAAa,CAAA;AAEpB,0FAA0F;AAC1F,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,SAAS,EAAE,CAAC;SACT,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,CACP,0EAA0E;QACxE,iCAAiC,CACpC;IACH,GAAG,sBAAsB;IACzB,GAAG,sBAAsB;CAC1B,CAAA;AAOD;;;;GAIG;AACH,MAAM,UAAU,+BAA+B,CAAC,MAAiB;IAC/D,MAAM,CAAC,YAAY,CACjB,uBAAuB,EACvB;QACE,WAAW,EACT,uEAAuE;YACvE,uEAAuE;YACvE,wEAAwE;YACxE,0EAA0E;YAC1E,yEAAyE;YACzE,oBAAoB;QACtB,WAAW,EAAE,uBAAuB;KACrC,EACD,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;QACpB,MAAM,KAAK,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAA;QAC1C,OAAO,cAAc,CACnB;YACE,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,iBAAiB,CAAC,IAAI,CAAC,SAAS,EAAE,gBAAgB,CAAC;YACzD,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,47 @@
1
+ // `report_export_unmatched` — curated GET
2
+ // /v1/reports/contexts/{contextId}/unmatched/export.
3
+ //
4
+ // Synchronously exports the unmatched-transactions report as a single
5
+ // base64-encoded file (CSV or PDF) for the given date window. This is an HTTP
6
+ // GET — the date filter and the csv|pdf format are query params, not a POST
7
+ // body. matcher returns the file as a base64 STRING inline in the JSON
8
+ // response; the dispatch passes it through verbatim (it is NOT decoded here —
9
+ // the caller decodes it). The export is implicitly tenant-scoped by the relayed
10
+ // token; contextId is a routing path param, not a tenant field, and no tenant
11
+ // field is accepted.
12
+ import { z } from 'zod';
13
+ import { buildReportExportQuery, contextReportPath, dispatchReport, reportFilterInputShape, reportFormatInputShape, } from './shared.js';
14
+ /** Zod raw shape for `report_export_unmatched` input — contextId path + filter + format. */
15
+ export const exportUnmatchedInputShape = {
16
+ contextId: z
17
+ .string()
18
+ .min(1)
19
+ .describe('The reconciliation context id (UUID) whose unmatched transactions to ' +
20
+ 'export. Routing path param, not a tenant field.'),
21
+ ...reportFilterInputShape,
22
+ ...reportFormatInputShape,
23
+ };
24
+ /**
25
+ * Register `report_export_unmatched`. Passes the date filter + format through
26
+ * and returns matcher's base64 file string verbatim (the caller decodes it); a
27
+ * matcher error surfaces via the shared toToolError.
28
+ */
29
+ export function registerReportExportUnmatchedTool(server) {
30
+ server.registerTool('report_export_unmatched', {
31
+ description: 'Export the unmatched-transactions report for a context within a date ' +
32
+ 'window as a CSV or PDF file. Pass contextId (UUID path param — not a ' +
33
+ 'tenant field), and optionally date_from/date_to (YYYY-MM-DD, window ≤ ' +
34
+ '90 days), source_id, and format (csv|pdf, default csv). The result is a ' +
35
+ 'base64-encoded string — decode it to recover the file bytes. No tenant ' +
36
+ 'field is accepted.',
37
+ inputSchema: exportUnmatchedInputShape,
38
+ }, async (args, extra) => {
39
+ const query = buildReportExportQuery(args);
40
+ return dispatchReport({
41
+ method: 'GET',
42
+ path: contextReportPath(args.contextId, 'unmatched/export'),
43
+ ...(query !== undefined ? { query } : {}),
44
+ }, extra);
45
+ });
46
+ }
47
+ //# sourceMappingURL=export-unmatched.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export-unmatched.js","sourceRoot":"","sources":["../../../src/tools/report/export-unmatched.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAC1C,qDAAqD;AACrD,EAAE;AACF,sEAAsE;AACtE,8EAA8E;AAC9E,4EAA4E;AAC5E,uEAAuE;AACvE,8EAA8E;AAC9E,gFAAgF;AAChF,8EAA8E;AAC9E,qBAAqB;AAErB,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB,OAAO,EACL,sBAAsB,EACtB,iBAAiB,EACjB,cAAc,EACd,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,aAAa,CAAA;AAEpB,4FAA4F;AAC5F,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACvC,SAAS,EAAE,CAAC;SACT,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,CACP,uEAAuE;QACrE,iDAAiD,CACpD;IACH,GAAG,sBAAsB;IACzB,GAAG,sBAAsB;CAC1B,CAAA;AAOD;;;;GAIG;AACH,MAAM,UAAU,iCAAiC,CAAC,MAAiB;IACjE,MAAM,CAAC,YAAY,CACjB,yBAAyB,EACzB;QACE,WAAW,EACT,uEAAuE;YACvE,uEAAuE;YACvE,wEAAwE;YACxE,0EAA0E;YAC1E,yEAAyE;YACzE,oBAAoB;QACtB,WAAW,EAAE,yBAAyB;KACvC,EACD,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;QACpB,MAAM,KAAK,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAA;QAC1C,OAAO,cAAc,CACnB;YACE,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,iBAAiB,CAAC,IAAI,CAAC,SAAS,EAAE,kBAAkB,CAAC;YAC3D,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,46 @@
1
+ // `report_export_variance` — curated GET
2
+ // /v1/reports/contexts/{contextId}/variance/export.
3
+ //
4
+ // Synchronously exports the variance analysis report as a single base64-encoded
5
+ // file (CSV or PDF) for the given date window. This is an HTTP GET — the date
6
+ // filter and the csv|pdf format are query params, not a POST body. matcher
7
+ // returns the file as a base64 STRING inline in the JSON response; the dispatch
8
+ // passes it through verbatim (it is NOT decoded here — the caller decodes it).
9
+ // The export is implicitly tenant-scoped by the relayed token; contextId is a
10
+ // routing path param, not a tenant field, and no tenant field is accepted.
11
+ import { z } from 'zod';
12
+ import { buildReportExportQuery, contextReportPath, dispatchReport, reportFilterInputShape, reportFormatInputShape, } from './shared.js';
13
+ /** Zod raw shape for `report_export_variance` input — contextId path + filter + format. */
14
+ export const exportVarianceInputShape = {
15
+ contextId: z
16
+ .string()
17
+ .min(1)
18
+ .describe('The reconciliation context id (UUID) whose variance rows to export. ' +
19
+ 'Routing path param, not a tenant field.'),
20
+ ...reportFilterInputShape,
21
+ ...reportFormatInputShape,
22
+ };
23
+ /**
24
+ * Register `report_export_variance`. Passes the date filter + format through and
25
+ * returns matcher's base64 file string verbatim (the caller decodes it); a
26
+ * matcher error surfaces via the shared toToolError.
27
+ */
28
+ export function registerReportExportVarianceTool(server) {
29
+ server.registerTool('report_export_variance', {
30
+ description: 'Export the variance analysis report for a context within a date ' +
31
+ 'window as a CSV or PDF file. Pass contextId (UUID path param — not a ' +
32
+ 'tenant field), and optionally date_from/date_to (YYYY-MM-DD, window ≤ ' +
33
+ '90 days), source_id, and format (csv|pdf, default csv). The result is a ' +
34
+ 'base64-encoded string — decode it to recover the file bytes. No tenant ' +
35
+ 'field is accepted.',
36
+ inputSchema: exportVarianceInputShape,
37
+ }, async (args, extra) => {
38
+ const query = buildReportExportQuery(args);
39
+ return dispatchReport({
40
+ method: 'GET',
41
+ path: contextReportPath(args.contextId, 'variance/export'),
42
+ ...(query !== undefined ? { query } : {}),
43
+ }, extra);
44
+ });
45
+ }
46
+ //# sourceMappingURL=export-variance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export-variance.js","sourceRoot":"","sources":["../../../src/tools/report/export-variance.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,oDAAoD;AACpD,EAAE;AACF,gFAAgF;AAChF,8EAA8E;AAC9E,2EAA2E;AAC3E,gFAAgF;AAChF,+EAA+E;AAC/E,8EAA8E;AAC9E,2EAA2E;AAE3E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB,OAAO,EACL,sBAAsB,EACtB,iBAAiB,EACjB,cAAc,EACd,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,aAAa,CAAA;AAEpB,2FAA2F;AAC3F,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC,SAAS,EAAE,CAAC;SACT,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,CACP,sEAAsE;QACpE,yCAAyC,CAC5C;IACH,GAAG,sBAAsB;IACzB,GAAG,sBAAsB;CAC1B,CAAA;AAOD;;;;GAIG;AACH,MAAM,UAAU,gCAAgC,CAAC,MAAiB;IAChE,MAAM,CAAC,YAAY,CACjB,wBAAwB,EACxB;QACE,WAAW,EACT,kEAAkE;YAClE,uEAAuE;YACvE,wEAAwE;YACxE,0EAA0E;YAC1E,yEAAyE;YACzE,oBAAoB;QACtB,WAAW,EAAE,wBAAwB;KACtC,EACD,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;QACpB,MAAM,KAAK,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAA;QAC1C,OAAO,cAAc,CACnB;YACE,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,iBAAiB,CAAC,IAAI,CAAC,SAAS,EAAE,iBAAiB,CAAC;YAC1D,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,40 @@
1
+ // Curated report vertical: thirteen typed tools over the matcher synchronous
2
+ // reporting surface — the three paginated reads (matched/unmatched/variance),
3
+ // the summary read, the four counts (exceptions/matched/unmatched/transactions),
4
+ // and the five base64 exports (exceptions/matched/summary/unmatched/variance).
5
+ // Every op is a context-nested HTTP GET under /v1/reports/contexts/{contextId}.
6
+ // Each tool shares the fail-closed relay (shared.ts) and the RFC 9457 →
7
+ // tool-error mapping (toToolError) with the generic surface, so curated and
8
+ // generic map matcher errors identically. No tool carries a tenant field;
9
+ // contextId is a routing path param matcher validates against the relayed
10
+ // token's tenant.
11
+ import { registerReportCountExceptionsTool } from './count-exceptions.js';
12
+ import { registerReportCountMatchedTool } from './count-matched.js';
13
+ import { registerReportCountTransactionsTool } from './count-transactions.js';
14
+ import { registerReportCountUnmatchedTool } from './count-unmatched.js';
15
+ import { registerReportExportExceptionsTool } from './export-exceptions.js';
16
+ import { registerReportExportMatchedTool } from './export-matched.js';
17
+ import { registerReportExportSummaryTool } from './export-summary.js';
18
+ import { registerReportExportUnmatchedTool } from './export-unmatched.js';
19
+ import { registerReportExportVarianceTool } from './export-variance.js';
20
+ import { registerReportMatchedTool } from './matched.js';
21
+ import { registerReportSummaryTool } from './summary.js';
22
+ import { registerReportUnmatchedTool } from './unmatched.js';
23
+ import { registerReportVarianceTool } from './variance.js';
24
+ /** Register all thirteen curated report tools on the given server. */
25
+ export function registerReportTools(server) {
26
+ registerReportMatchedTool(server);
27
+ registerReportUnmatchedTool(server);
28
+ registerReportVarianceTool(server);
29
+ registerReportSummaryTool(server);
30
+ registerReportCountExceptionsTool(server);
31
+ registerReportCountMatchedTool(server);
32
+ registerReportCountUnmatchedTool(server);
33
+ registerReportCountTransactionsTool(server);
34
+ registerReportExportExceptionsTool(server);
35
+ registerReportExportMatchedTool(server);
36
+ registerReportExportSummaryTool(server);
37
+ registerReportExportUnmatchedTool(server);
38
+ registerReportExportVarianceTool(server);
39
+ }
40
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/report/index.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,8EAA8E;AAC9E,iFAAiF;AACjF,+EAA+E;AAC/E,gFAAgF;AAChF,wEAAwE;AACxE,4EAA4E;AAC5E,0EAA0E;AAC1E,0EAA0E;AAC1E,kBAAkB;AAIlB,OAAO,EAAE,iCAAiC,EAAE,MAAM,uBAAuB,CAAA;AACzE,OAAO,EAAE,8BAA8B,EAAE,MAAM,oBAAoB,CAAA;AACnE,OAAO,EAAE,mCAAmC,EAAE,MAAM,yBAAyB,CAAA;AAC7E,OAAO,EAAE,gCAAgC,EAAE,MAAM,sBAAsB,CAAA;AACvE,OAAO,EAAE,kCAAkC,EAAE,MAAM,wBAAwB,CAAA;AAC3E,OAAO,EAAE,+BAA+B,EAAE,MAAM,qBAAqB,CAAA;AACrE,OAAO,EAAE,+BAA+B,EAAE,MAAM,qBAAqB,CAAA;AACrE,OAAO,EAAE,iCAAiC,EAAE,MAAM,uBAAuB,CAAA;AACzE,OAAO,EAAE,gCAAgC,EAAE,MAAM,sBAAsB,CAAA;AACvE,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAA;AACxD,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAA;AACxD,OAAO,EAAE,2BAA2B,EAAE,MAAM,gBAAgB,CAAA;AAC5D,OAAO,EAAE,0BAA0B,EAAE,MAAM,eAAe,CAAA;AAE1D,sEAAsE;AACtE,MAAM,UAAU,mBAAmB,CAAC,MAAiB;IACnD,yBAAyB,CAAC,MAAM,CAAC,CAAA;IACjC,2BAA2B,CAAC,MAAM,CAAC,CAAA;IACnC,0BAA0B,CAAC,MAAM,CAAC,CAAA;IAClC,yBAAyB,CAAC,MAAM,CAAC,CAAA;IACjC,iCAAiC,CAAC,MAAM,CAAC,CAAA;IACzC,8BAA8B,CAAC,MAAM,CAAC,CAAA;IACtC,gCAAgC,CAAC,MAAM,CAAC,CAAA;IACxC,mCAAmC,CAAC,MAAM,CAAC,CAAA;IAC3C,kCAAkC,CAAC,MAAM,CAAC,CAAA;IAC1C,+BAA+B,CAAC,MAAM,CAAC,CAAA;IACvC,+BAA+B,CAAC,MAAM,CAAC,CAAA;IACvC,iCAAiC,CAAC,MAAM,CAAC,CAAA;IACzC,gCAAgC,CAAC,MAAM,CAAC,CAAA;AAC1C,CAAC"}
@@ -0,0 +1,44 @@
1
+ // `report_matched` — curated GET /v1/reports/contexts/{contextId}/matched.
2
+ //
3
+ // Cursor-paginated matched transactions for a context within a date window.
4
+ // date_from/date_to/source_id filter and cursor/limit/sort_order page; matcher's
5
+ // { items, nextCursor } envelope is returned as-is — no auto-pagination (the
6
+ // model re-calls with the returned cursor). The report is implicitly
7
+ // tenant-scoped by the relayed token; contextId is a routing path param, not a
8
+ // tenant field, and no tenant field is accepted.
9
+ import { z } from 'zod';
10
+ import { buildReportPaginatedQuery, contextReportPath, dispatchReport, reportFilterInputShape, reportPaginationInputShape, } from './shared.js';
11
+ /** Zod raw shape for `report_matched` input — contextId path + filter + pagination. */
12
+ export const matchedReportInputShape = {
13
+ contextId: z
14
+ .string()
15
+ .min(1)
16
+ .describe('The reconciliation context id (UUID) whose matched transactions to ' +
17
+ 'report. Routing path param, not a tenant field.'),
18
+ ...reportFilterInputShape,
19
+ ...reportPaginationInputShape,
20
+ };
21
+ /**
22
+ * Register `report_matched`. Passes the date filter + pagination through and
23
+ * returns matcher's pagination envelope verbatim; a matcher error surfaces via
24
+ * the shared toToolError.
25
+ */
26
+ export function registerReportMatchedTool(server) {
27
+ server.registerTool('report_matched', {
28
+ description: 'List matched transactions for a context within a date window ' +
29
+ '(cursor-paginated). Pass contextId (UUID path param — not a tenant ' +
30
+ 'field), and optionally date_from/date_to (YYYY-MM-DD, window ≤ 90 ' +
31
+ 'days), source_id, limit (1–200), sort_order (asc|desc), and/or cursor. ' +
32
+ 'The response carries { items, nextCursor } — paginate by re-calling ' +
33
+ 'with the returned nextCursor. No tenant field is accepted.',
34
+ inputSchema: matchedReportInputShape,
35
+ }, async (args, extra) => {
36
+ const query = buildReportPaginatedQuery(args);
37
+ return dispatchReport({
38
+ method: 'GET',
39
+ path: contextReportPath(args.contextId, 'matched'),
40
+ ...(query !== undefined ? { query } : {}),
41
+ }, extra);
42
+ });
43
+ }
44
+ //# sourceMappingURL=matched.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"matched.js","sourceRoot":"","sources":["../../../src/tools/report/matched.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,EAAE;AACF,4EAA4E;AAC5E,iFAAiF;AACjF,6EAA6E;AAC7E,qEAAqE;AACrE,+EAA+E;AAC/E,iDAAiD;AAEjD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB,OAAO,EACL,yBAAyB,EACzB,iBAAiB,EACjB,cAAc,EACd,sBAAsB,EACtB,0BAA0B,GAC3B,MAAM,aAAa,CAAA;AAEpB,uFAAuF;AACvF,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,SAAS,EAAE,CAAC;SACT,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,CACP,qEAAqE;QACnE,iDAAiD,CACpD;IACH,GAAG,sBAAsB;IACzB,GAAG,0BAA0B;CAC9B,CAAA;AAOD;;;;GAIG;AACH,MAAM,UAAU,yBAAyB,CAAC,MAAiB;IACzD,MAAM,CAAC,YAAY,CACjB,gBAAgB,EAChB;QACE,WAAW,EACT,+DAA+D;YAC/D,qEAAqE;YACrE,oEAAoE;YACpE,yEAAyE;YACzE,sEAAsE;YACtE,4DAA4D;QAC9D,WAAW,EAAE,uBAAuB;KACrC,EACD,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;QACpB,MAAM,KAAK,GAAG,yBAAyB,CAAC,IAAI,CAAC,CAAA;QAC7C,OAAO,cAAc,CACnB;YACE,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,iBAAiB,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC;YAClD,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,176 @@
1
+ // Shared plumbing for the curated report tools.
2
+ //
3
+ // Reports are synchronous, read-only analytics over a reconciliation context.
4
+ // EVERY report op is fully context-nested under /v1/reports/contexts/{contextId}
5
+ // and is an HTTP GET — including the exports, which take their knobs as query
6
+ // params (not a POST body). The thirteen ops fall into three response shapes:
7
+ // - paginated lists (matched/unmatched/variance): the common date filter plus
8
+ // cursor/limit/sort_order, returning a { items, nextCursor } envelope;
9
+ // - the summary read and the four count ops: the common date filter only;
10
+ // - the five exports: the common date filter plus a csv|pdf format, returning
11
+ // a base64 STRING the caller must decode.
12
+ //
13
+ // This module factors the path builder, the three reusable query builders, and
14
+ // the relay/error-mapping boilerplate exactly once so the thirteen tools stay
15
+ // thin (just "name the suffix + pick the query builder"). The relay shape is
16
+ // identical to the source / fee-schedule / match-rule verticals so curated and
17
+ // generic surfaces map matcher errors through the same path (toToolError).
18
+ //
19
+ // Security: the bearer token is never read here directly — requireMatcherClient
20
+ // owns the request-scoped relay and fails closed when no usable credential was
21
+ // provided. No tenant identifier is ever read or injected (matcher derives
22
+ // tenant from the relayed JWT); no report tool input carries one. The
23
+ // `contextId` segment is a routing path param — matcher validates that the
24
+ // context belongs to the token's tenant.
25
+ import { z } from 'zod';
26
+ import { requireMatcherClient, UnauthenticatedError, } from '../../auth/request-token.js';
27
+ import { isMatcherApiError, toToolError } from '../tool-error.js';
28
+ /** Sort-order enum shared by the paginated report ops (created_at asc|desc). */
29
+ export const REPORT_SORT_ORDERS = ['asc', 'desc'];
30
+ /** Export-format enum shared by the five export ops (csv|pdf). */
31
+ export const REPORT_EXPORT_FORMATS = ['csv', 'pdf'];
32
+ /**
33
+ * Build a report path under a context, e.g.
34
+ * `/v1/reports/contexts/<id>/matched` or `.../matches/count`. The caller passes
35
+ * the suffix verbatim (the spec's count path for matched is `matches/count`, not
36
+ * `matched/count` — that asymmetry is encoded by each op, not hidden here). Only
37
+ * the contextId is URL-encoded; the suffix is a fixed literal owned by the op.
38
+ */
39
+ export function contextReportPath(contextId, suffix) {
40
+ return `/v1/reports/contexts/${encodeURIComponent(contextId)}/${suffix}`;
41
+ }
42
+ /**
43
+ * The common date-window + source filter every report op accepts. Factored as a
44
+ * raw-shape fragment so each op's inputSchema spreads it in and stays focused on
45
+ * what is unique to that op. No tenant field — matcher scopes to the token.
46
+ */
47
+ export const reportFilterInputShape = {
48
+ date_from: z
49
+ .string()
50
+ .optional()
51
+ .describe('Start date (YYYY-MM-DD), inclusive. Optional: defaults to 30 days before ' +
52
+ 'date_to. The window may not exceed 90 days.'),
53
+ date_to: z
54
+ .string()
55
+ .optional()
56
+ .describe('End date (YYYY-MM-DD), inclusive. Optional: defaults to tomorrow (UTC). ' +
57
+ 'The window may not exceed 90 days.'),
58
+ source_id: z
59
+ .string()
60
+ .optional()
61
+ .describe('Optional source id (UUID) filter.'),
62
+ };
63
+ /** The pagination + sort knobs the three "get report" list ops add on top. */
64
+ export const reportPaginationInputShape = {
65
+ cursor: z
66
+ .string()
67
+ .optional()
68
+ .describe('Opaque pagination cursor from a prior response. Re-call with the ' +
69
+ 'returned nextCursor to page forward (there is no auto-pagination).'),
70
+ limit: z
71
+ .number()
72
+ .int()
73
+ .min(1)
74
+ .max(200)
75
+ .optional()
76
+ .describe('Maximum number of records to return (1–200, default 20).'),
77
+ sort_order: z
78
+ .enum(REPORT_SORT_ORDERS)
79
+ .optional()
80
+ .describe('Sort order for created_at (asc|desc, default desc).'),
81
+ };
82
+ /** The export-format knob the five export ops add on top of the date filter. */
83
+ export const reportFormatInputShape = {
84
+ format: z
85
+ .enum(REPORT_EXPORT_FORMATS)
86
+ .optional()
87
+ .describe('Export format (csv|pdf, default csv).'),
88
+ };
89
+ /** Append the date-window + source filter, omitting unset knobs. */
90
+ function appendReportFilter(query, args) {
91
+ if (args.date_from !== undefined) {
92
+ query.date_from = args.date_from;
93
+ }
94
+ if (args.date_to !== undefined) {
95
+ query.date_to = args.date_to;
96
+ }
97
+ if (args.source_id !== undefined) {
98
+ query.source_id = args.source_id;
99
+ }
100
+ }
101
+ /**
102
+ * Build the query for a count or summary op: the date filter only. Returns
103
+ * undefined when nothing is set so the request URL stays bare.
104
+ */
105
+ export function buildReportFilterQuery(args) {
106
+ const query = {};
107
+ appendReportFilter(query, args);
108
+ return Object.keys(query).length > 0 ? query : undefined;
109
+ }
110
+ /**
111
+ * Build the query for a paginated "get report" op: the date filter plus
112
+ * cursor/limit/sort_order. Returns undefined when nothing is set.
113
+ */
114
+ export function buildReportPaginatedQuery(args) {
115
+ const query = {};
116
+ appendReportFilter(query, args);
117
+ if (args.cursor !== undefined) {
118
+ query.cursor = args.cursor;
119
+ }
120
+ if (args.limit !== undefined) {
121
+ query.limit = args.limit;
122
+ }
123
+ if (args.sort_order !== undefined) {
124
+ query.sort_order = args.sort_order;
125
+ }
126
+ return Object.keys(query).length > 0 ? query : undefined;
127
+ }
128
+ /**
129
+ * Build the query for an export op: the date filter plus the csv|pdf format.
130
+ * Returns undefined when nothing is set.
131
+ */
132
+ export function buildReportExportQuery(args) {
133
+ const query = {};
134
+ appendReportFilter(query, args);
135
+ if (args.format !== undefined) {
136
+ query.format = args.format;
137
+ }
138
+ return Object.keys(query).length > 0 ? query : undefined;
139
+ }
140
+ /**
141
+ * Run one assembled request through the relay: fail-closed auth, dispatch, and
142
+ * RFC 9457 → tool-error mapping — identical to the generic invoke's dispatch so
143
+ * both surfaces produce the same structured error shape.
144
+ *
145
+ * `clientFor` is injectable for tests; production callers pass nothing and get
146
+ * the request-scoped, fail-closed `requireMatcherClient`.
147
+ */
148
+ export async function dispatchReport(request, extra, clientFor = requireMatcherClient) {
149
+ let client;
150
+ try {
151
+ // Fail-closed on a missing / empty / non-Bearer credential.
152
+ client = clientFor(extra);
153
+ }
154
+ catch (err) {
155
+ if (err instanceof UnauthenticatedError) {
156
+ return { isError: true, content: [{ type: 'text', text: err.message }] };
157
+ }
158
+ throw err;
159
+ }
160
+ try {
161
+ const result = await client.request(request);
162
+ // Success → matcher's JSON returned as-is. Exports return a base64 STRING
163
+ // here verbatim (the caller decodes it); a 204/empty body → null.
164
+ return { content: [{ type: 'text', text: JSON.stringify(result ?? null) }] };
165
+ }
166
+ catch (err) {
167
+ // RFC 9457 problem → the SHARED structured tool error (status/title/detail/
168
+ // code preserved). A non-matcher error is a bug, not a matcher failure, and
169
+ // is re-thrown rather than masqueraded as one.
170
+ if (isMatcherApiError(err)) {
171
+ return toToolError(err);
172
+ }
173
+ throw err;
174
+ }
175
+ }
176
+ //# sourceMappingURL=shared.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../src/tools/report/shared.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ // `report_summary` — curated GET /v1/reports/contexts/{contextId}/summary.
2
+ //
3
+ // Aggregated summary statistics for a context within a date window. Takes only
4
+ // the common date filter (date_from/date_to/source_id) — no pagination — and
5
+ // returns matcher's SummaryReportResponse as-is. The report is implicitly
6
+ // tenant-scoped by the relayed token; contextId is a routing path param, not a
7
+ // tenant field, and no tenant field is accepted.
8
+ import { z } from 'zod';
9
+ import { buildReportFilterQuery, contextReportPath, dispatchReport, reportFilterInputShape, } from './shared.js';
10
+ /** Zod raw shape for `report_summary` input — contextId path + date filter. */
11
+ export const summaryReportInputShape = {
12
+ contextId: z
13
+ .string()
14
+ .min(1)
15
+ .describe('The reconciliation context id (UUID) to summarize. Routing path param, ' +
16
+ 'not a tenant field.'),
17
+ ...reportFilterInputShape,
18
+ };
19
+ /**
20
+ * Register `report_summary`. Passes the date filter through and returns
21
+ * matcher's aggregated summary verbatim; a matcher error surfaces via the
22
+ * shared toToolError.
23
+ */
24
+ export function registerReportSummaryTool(server) {
25
+ server.registerTool('report_summary', {
26
+ description: 'Get aggregated reconciliation summary statistics for a context within ' +
27
+ 'a date window. Pass contextId (UUID path param — not a tenant field), ' +
28
+ 'and optionally date_from/date_to (YYYY-MM-DD, window ≤ 90 days) and ' +
29
+ 'source_id. Returns the summary totals, or a structured RFC 9457 error. ' +
30
+ 'No tenant field is accepted.',
31
+ inputSchema: summaryReportInputShape,
32
+ }, async (args, extra) => {
33
+ const query = buildReportFilterQuery(args);
34
+ return dispatchReport({
35
+ method: 'GET',
36
+ path: contextReportPath(args.contextId, 'summary'),
37
+ ...(query !== undefined ? { query } : {}),
38
+ }, extra);
39
+ });
40
+ }
41
+ //# sourceMappingURL=summary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summary.js","sourceRoot":"","sources":["../../../src/tools/report/summary.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,EAAE;AACF,+EAA+E;AAC/E,6EAA6E;AAC7E,0EAA0E;AAC1E,+EAA+E;AAC/E,iDAAiD;AAEjD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB,OAAO,EACL,sBAAsB,EACtB,iBAAiB,EACjB,cAAc,EACd,sBAAsB,GACvB,MAAM,aAAa,CAAA;AAEpB,+EAA+E;AAC/E,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,SAAS,EAAE,CAAC;SACT,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,CACP,yEAAyE;QACvE,qBAAqB,CACxB;IACH,GAAG,sBAAsB;CAC1B,CAAA;AAOD;;;;GAIG;AACH,MAAM,UAAU,yBAAyB,CAAC,MAAiB;IACzD,MAAM,CAAC,YAAY,CACjB,gBAAgB,EAChB;QACE,WAAW,EACT,wEAAwE;YACxE,wEAAwE;YACxE,sEAAsE;YACtE,yEAAyE;YACzE,8BAA8B;QAChC,WAAW,EAAE,uBAAuB;KACrC,EACD,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;QACpB,MAAM,KAAK,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAA;QAC1C,OAAO,cAAc,CACnB;YACE,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,iBAAiB,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC;YAClD,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,44 @@
1
+ // `report_unmatched` — curated GET /v1/reports/contexts/{contextId}/unmatched.
2
+ //
3
+ // Cursor-paginated unmatched transactions for a context within a date window.
4
+ // date_from/date_to/source_id filter and cursor/limit/sort_order page; matcher's
5
+ // { items, nextCursor } envelope is returned as-is — no auto-pagination (the
6
+ // model re-calls with the returned cursor). The report is implicitly
7
+ // tenant-scoped by the relayed token; contextId is a routing path param, not a
8
+ // tenant field, and no tenant field is accepted.
9
+ import { z } from 'zod';
10
+ import { buildReportPaginatedQuery, contextReportPath, dispatchReport, reportFilterInputShape, reportPaginationInputShape, } from './shared.js';
11
+ /** Zod raw shape for `report_unmatched` input — contextId path + filter + pagination. */
12
+ export const unmatchedReportInputShape = {
13
+ contextId: z
14
+ .string()
15
+ .min(1)
16
+ .describe('The reconciliation context id (UUID) whose unmatched transactions to ' +
17
+ 'report. Routing path param, not a tenant field.'),
18
+ ...reportFilterInputShape,
19
+ ...reportPaginationInputShape,
20
+ };
21
+ /**
22
+ * Register `report_unmatched`. Passes the date filter + pagination through and
23
+ * returns matcher's pagination envelope verbatim; a matcher error surfaces via
24
+ * the shared toToolError.
25
+ */
26
+ export function registerReportUnmatchedTool(server) {
27
+ server.registerTool('report_unmatched', {
28
+ description: 'List unmatched transactions for a context within a date window ' +
29
+ '(cursor-paginated). Pass contextId (UUID path param — not a tenant ' +
30
+ 'field), and optionally date_from/date_to (YYYY-MM-DD, window ≤ 90 ' +
31
+ 'days), source_id, limit (1–200), sort_order (asc|desc), and/or cursor. ' +
32
+ 'The response carries { items, nextCursor } — paginate by re-calling ' +
33
+ 'with the returned nextCursor. No tenant field is accepted.',
34
+ inputSchema: unmatchedReportInputShape,
35
+ }, async (args, extra) => {
36
+ const query = buildReportPaginatedQuery(args);
37
+ return dispatchReport({
38
+ method: 'GET',
39
+ path: contextReportPath(args.contextId, 'unmatched'),
40
+ ...(query !== undefined ? { query } : {}),
41
+ }, extra);
42
+ });
43
+ }
44
+ //# sourceMappingURL=unmatched.js.map