@dizzlkheinz/ynab-mcpb 0.18.3 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/CLAUDE.md +87 -8
- package/bin/ynab-mcp-server.cjs +2 -2
- package/bin/ynab-mcp-server.js +3 -3
- package/biome.json +39 -0
- package/dist/bundle/index.cjs +67 -67
- package/dist/index.d.ts +1 -1
- package/dist/index.js +27 -27
- package/dist/server/YNABMCPServer.d.ts +3 -4
- package/dist/server/YNABMCPServer.js +111 -116
- package/dist/server/budgetResolver.d.ts +6 -5
- package/dist/server/budgetResolver.js +46 -36
- package/dist/server/cacheKeys.js +6 -6
- package/dist/server/cacheManager.js +14 -11
- package/dist/server/completions.d.ts +2 -2
- package/dist/server/completions.js +20 -15
- package/dist/server/config.d.ts +10 -5
- package/dist/server/config.js +24 -7
- package/dist/server/deltaCache.d.ts +2 -2
- package/dist/server/deltaCache.js +22 -16
- package/dist/server/deltaCache.merge.d.ts +2 -2
- package/dist/server/diagnostics.d.ts +4 -4
- package/dist/server/diagnostics.js +38 -32
- package/dist/server/errorHandler.d.ts +5 -12
- package/dist/server/errorHandler.js +219 -217
- package/dist/server/prompts.d.ts +2 -2
- package/dist/server/prompts.js +45 -45
- package/dist/server/rateLimiter.js +4 -4
- package/dist/server/requestLogger.d.ts +1 -1
- package/dist/server/requestLogger.js +40 -35
- package/dist/server/resources.d.ts +3 -3
- package/dist/server/resources.js +55 -52
- package/dist/server/responseFormatter.js +6 -6
- package/dist/server/securityMiddleware.d.ts +2 -2
- package/dist/server/securityMiddleware.js +22 -20
- package/dist/server/serverKnowledgeStore.js +1 -1
- package/dist/server/toolRegistry.d.ts +3 -3
- package/dist/server/toolRegistry.js +47 -40
- package/dist/tools/__tests__/deltaTestUtils.d.ts +3 -3
- package/dist/tools/__tests__/deltaTestUtils.js +2 -2
- package/dist/tools/accountTools.d.ts +9 -8
- package/dist/tools/accountTools.js +47 -47
- package/dist/tools/adapters.d.ts +13 -8
- package/dist/tools/adapters.js +21 -11
- package/dist/tools/budgetTools.d.ts +8 -7
- package/dist/tools/budgetTools.js +22 -22
- package/dist/tools/categoryTools.d.ts +9 -8
- package/dist/tools/categoryTools.js +68 -59
- package/dist/tools/compareTransactions/formatter.d.ts +3 -3
- package/dist/tools/compareTransactions/formatter.js +9 -9
- package/dist/tools/compareTransactions/index.d.ts +6 -6
- package/dist/tools/compareTransactions/index.js +58 -43
- package/dist/tools/compareTransactions/matcher.d.ts +1 -1
- package/dist/tools/compareTransactions/matcher.js +28 -15
- package/dist/tools/compareTransactions/parser.d.ts +2 -2
- package/dist/tools/compareTransactions/parser.js +144 -138
- package/dist/tools/compareTransactions/types.d.ts +4 -4
- package/dist/tools/compareTransactions.d.ts +1 -1
- package/dist/tools/compareTransactions.js +1 -1
- package/dist/tools/deltaFetcher.d.ts +2 -2
- package/dist/tools/deltaFetcher.js +16 -15
- package/dist/tools/deltaSupport.d.ts +4 -4
- package/dist/tools/deltaSupport.js +35 -41
- package/dist/tools/exportTransactions.d.ts +5 -4
- package/dist/tools/exportTransactions.js +61 -59
- package/dist/tools/monthTools.d.ts +7 -6
- package/dist/tools/monthTools.js +31 -29
- package/dist/tools/payeeTools.d.ts +7 -6
- package/dist/tools/payeeTools.js +28 -28
- package/dist/tools/reconcileAdapter.d.ts +2 -2
- package/dist/tools/reconcileAdapter.js +21 -11
- package/dist/tools/reconciliation/analyzer.d.ts +4 -4
- package/dist/tools/reconciliation/analyzer.js +136 -57
- package/dist/tools/reconciliation/csvParser.d.ts +3 -3
- package/dist/tools/reconciliation/csvParser.js +128 -104
- package/dist/tools/reconciliation/executor.d.ts +4 -4
- package/dist/tools/reconciliation/executor.js +148 -109
- package/dist/tools/reconciliation/index.d.ts +10 -10
- package/dist/tools/reconciliation/index.js +96 -83
- package/dist/tools/reconciliation/matcher.d.ts +3 -3
- package/dist/tools/reconciliation/matcher.js +17 -16
- package/dist/tools/reconciliation/payeeNormalizer.js +19 -8
- package/dist/tools/reconciliation/recommendationEngine.d.ts +1 -1
- package/dist/tools/reconciliation/recommendationEngine.js +40 -40
- package/dist/tools/reconciliation/reportFormatter.d.ts +2 -2
- package/dist/tools/reconciliation/reportFormatter.js +79 -54
- package/dist/tools/reconciliation/signDetector.d.ts +1 -1
- package/dist/tools/reconciliation/types.d.ts +19 -16
- package/dist/tools/reconciliation/ynabAdapter.d.ts +2 -2
- package/dist/tools/schemas/common.d.ts +1 -1
- package/dist/tools/schemas/common.js +1 -1
- package/dist/tools/schemas/outputs/accountOutputs.d.ts +1 -1
- package/dist/tools/schemas/outputs/accountOutputs.js +24 -18
- package/dist/tools/schemas/outputs/budgetOutputs.d.ts +1 -1
- package/dist/tools/schemas/outputs/budgetOutputs.js +14 -11
- package/dist/tools/schemas/outputs/categoryOutputs.d.ts +1 -1
- package/dist/tools/schemas/outputs/categoryOutputs.js +49 -29
- package/dist/tools/schemas/outputs/comparisonOutputs.d.ts +1 -1
- package/dist/tools/schemas/outputs/comparisonOutputs.js +12 -12
- package/dist/tools/schemas/outputs/index.d.ts +14 -14
- package/dist/tools/schemas/outputs/index.js +14 -14
- package/dist/tools/schemas/outputs/monthOutputs.d.ts +1 -1
- package/dist/tools/schemas/outputs/monthOutputs.js +56 -41
- package/dist/tools/schemas/outputs/payeeOutputs.d.ts +1 -1
- package/dist/tools/schemas/outputs/payeeOutputs.js +10 -10
- package/dist/tools/schemas/outputs/reconciliationOutputs.d.ts +2 -2
- package/dist/tools/schemas/outputs/reconciliationOutputs.js +45 -45
- package/dist/tools/schemas/outputs/transactionMutationOutputs.d.ts +1 -1
- package/dist/tools/schemas/outputs/transactionMutationOutputs.js +28 -22
- package/dist/tools/schemas/outputs/transactionOutputs.d.ts +1 -1
- package/dist/tools/schemas/outputs/transactionOutputs.js +43 -35
- package/dist/tools/schemas/outputs/utilityOutputs.d.ts +1 -1
- package/dist/tools/schemas/outputs/utilityOutputs.js +5 -3
- package/dist/tools/schemas/shared/commonOutputs.d.ts +1 -1
- package/dist/tools/schemas/shared/commonOutputs.js +15 -9
- package/dist/tools/transactionReadTools.d.ts +11 -0
- package/dist/tools/transactionReadTools.js +202 -0
- package/dist/tools/transactionSchemas.d.ts +309 -0
- package/dist/tools/transactionSchemas.js +235 -0
- package/dist/tools/transactionTools.d.ts +6 -302
- package/dist/tools/transactionTools.js +7 -2054
- package/dist/tools/transactionUtils.d.ts +31 -0
- package/dist/tools/transactionUtils.js +364 -0
- package/dist/tools/transactionWriteTools.d.ts +20 -0
- package/dist/tools/transactionWriteTools.js +1342 -0
- package/dist/tools/utilityTools.d.ts +5 -4
- package/dist/tools/utilityTools.js +11 -11
- package/dist/types/index.d.ts +7 -7
- package/dist/types/index.js +6 -6
- package/dist/types/reconciliation.d.ts +1 -1
- package/dist/types/toolRegistration.d.ts +14 -12
- package/dist/utils/amountUtils.js +1 -1
- package/dist/utils/dateUtils.js +4 -4
- package/dist/utils/errors.d.ts +3 -3
- package/dist/utils/errors.js +4 -4
- package/dist/utils/money.d.ts +2 -2
- package/dist/utils/money.js +8 -8
- package/dist/utils/validationError.d.ts +1 -1
- package/dist/utils/validationError.js +1 -1
- package/docs/assets/examples/reconciliation-with-recommendations.json +66 -66
- package/docs/assets/schemas/reconciliation-v2.json +360 -336
- package/docs/plans/2025-12-25-transaction-tools-refactor-design.md +211 -0
- package/docs/plans/2025-12-25-transaction-tools-refactor.md +905 -0
- package/esbuild.config.mjs +53 -50
- package/meta.json +12548 -12548
- package/package.json +98 -109
- package/scripts/analyze-bundle.mjs +33 -30
- package/scripts/create-pr-description.js +169 -120
- package/scripts/run-all-tests.js +205 -0
- package/scripts/run-domain-integration-tests.js +28 -18
- package/scripts/run-generate-mcpb.js +19 -17
- package/scripts/run-throttled-integration-tests.js +92 -83
- package/scripts/test-delta-params.mjs +149 -120
- package/scripts/test-recommendations.ts +36 -32
- package/scripts/tmpTransaction.ts +80 -43
- package/scripts/validate-env.js +98 -91
- package/scripts/verify-build.js +78 -76
- package/src/__tests__/comprehensive.integration.test.ts +1281 -1154
- package/src/__tests__/performance.test.ts +723 -671
- package/src/__tests__/setup.ts +442 -395
- package/src/__tests__/smoke.e2e.test.ts +41 -39
- package/src/__tests__/testRunner.ts +314 -295
- package/src/__tests__/testUtils.ts +456 -364
- package/src/__tests__/tools/reconciliation/csvParser.integration.test.ts +109 -107
- package/src/__tests__/tools/reconciliation/real-world.integration.test.ts +41 -41
- package/src/index.ts +68 -59
- package/src/server/CLAUDE.md +480 -0
- package/src/server/YNABMCPServer.ts +821 -794
- package/src/server/__tests__/YNABMCPServer.integration.test.ts +929 -893
- package/src/server/__tests__/YNABMCPServer.test.ts +903 -899
- package/src/server/__tests__/budgetResolver.test.ts +466 -423
- package/src/server/__tests__/cacheManager.test.ts +891 -874
- package/src/server/__tests__/completions.integration.test.ts +115 -106
- package/src/server/__tests__/completions.test.ts +334 -313
- package/src/server/__tests__/config.test.ts +98 -86
- package/src/server/__tests__/deltaCache.merge.test.ts +774 -703
- package/src/server/__tests__/deltaCache.swr.test.ts +198 -153
- package/src/server/__tests__/deltaCache.test.ts +946 -759
- package/src/server/__tests__/diagnostics.test.ts +825 -792
- package/src/server/__tests__/errorHandler.integration.test.ts +512 -462
- package/src/server/__tests__/errorHandler.test.ts +402 -397
- package/src/server/__tests__/prompts.test.ts +424 -347
- package/src/server/__tests__/rateLimiter.test.ts +313 -309
- package/src/server/__tests__/requestLogger.test.ts +443 -403
- package/src/server/__tests__/resources.template.test.ts +196 -185
- package/src/server/__tests__/resources.test.ts +294 -288
- package/src/server/__tests__/security.integration.test.ts +487 -421
- package/src/server/__tests__/securityMiddleware.test.ts +519 -444
- package/src/server/__tests__/server-startup.integration.test.ts +509 -490
- package/src/server/__tests__/serverKnowledgeStore.test.ts +174 -173
- package/src/server/__tests__/toolRegistration.test.ts +239 -210
- package/src/server/__tests__/toolRegistry.test.ts +907 -845
- package/src/server/budgetResolver.ts +221 -181
- package/src/server/cacheKeys.ts +6 -6
- package/src/server/cacheManager.ts +498 -484
- package/src/server/completions.ts +267 -243
- package/src/server/config.ts +35 -14
- package/src/server/deltaCache.merge.ts +146 -128
- package/src/server/deltaCache.ts +352 -309
- package/src/server/diagnostics.ts +257 -242
- package/src/server/errorHandler.ts +747 -744
- package/src/server/prompts.ts +181 -176
- package/src/server/rateLimiter.ts +131 -129
- package/src/server/requestLogger.ts +350 -322
- package/src/server/resources.ts +442 -374
- package/src/server/responseFormatter.ts +41 -37
- package/src/server/securityMiddleware.ts +223 -205
- package/src/server/serverKnowledgeStore.ts +67 -67
- package/src/server/toolRegistry.ts +508 -474
- package/src/tools/CLAUDE.md +604 -0
- package/src/tools/__tests__/accountTools.delta.integration.test.ts +128 -111
- package/src/tools/__tests__/accountTools.integration.test.ts +129 -111
- package/src/tools/__tests__/accountTools.test.ts +685 -638
- package/src/tools/__tests__/adapters.test.ts +142 -108
- package/src/tools/__tests__/budgetTools.delta.integration.test.ts +73 -73
- package/src/tools/__tests__/budgetTools.integration.test.ts +132 -124
- package/src/tools/__tests__/budgetTools.test.ts +442 -413
- package/src/tools/__tests__/categoryTools.delta.integration.test.ts +76 -68
- package/src/tools/__tests__/categoryTools.integration.test.ts +314 -288
- package/src/tools/__tests__/categoryTools.test.ts +656 -625
- package/src/tools/__tests__/compareTransactions/formatter.test.ts +535 -462
- package/src/tools/__tests__/compareTransactions/index.test.ts +378 -358
- package/src/tools/__tests__/compareTransactions/matcher.test.ts +497 -398
- package/src/tools/__tests__/compareTransactions/parser.test.ts +765 -747
- package/src/tools/__tests__/compareTransactions.test.ts +352 -332
- package/src/tools/__tests__/compareTransactions.window.test.ts +150 -146
- package/src/tools/__tests__/deltaFetcher.scheduled.integration.test.ts +69 -65
- package/src/tools/__tests__/deltaFetcher.test.ts +325 -265
- package/src/tools/__tests__/deltaSupport.test.ts +211 -184
- package/src/tools/__tests__/deltaTestUtils.ts +37 -33
- package/src/tools/__tests__/exportTransactions.test.ts +205 -200
- package/src/tools/__tests__/monthTools.delta.integration.test.ts +68 -68
- package/src/tools/__tests__/monthTools.integration.test.ts +178 -166
- package/src/tools/__tests__/monthTools.test.ts +561 -512
- package/src/tools/__tests__/payeeTools.delta.integration.test.ts +68 -68
- package/src/tools/__tests__/payeeTools.integration.test.ts +158 -142
- package/src/tools/__tests__/payeeTools.test.ts +486 -434
- package/src/tools/__tests__/transactionSchemas.test.ts +1204 -0
- package/src/tools/__tests__/transactionTools.integration.test.ts +875 -825
- package/src/tools/__tests__/transactionTools.test.ts +4923 -4366
- package/src/tools/__tests__/transactionUtils.test.ts +1016 -0
- package/src/tools/__tests__/utilityTools.integration.test.ts +32 -32
- package/src/tools/__tests__/utilityTools.test.ts +68 -58
- package/src/tools/accountTools.ts +293 -271
- package/src/tools/adapters.ts +120 -63
- package/src/tools/budgetTools.ts +121 -116
- package/src/tools/categoryTools.ts +379 -339
- package/src/tools/compareTransactions/formatter.ts +131 -119
- package/src/tools/compareTransactions/index.ts +249 -214
- package/src/tools/compareTransactions/matcher.ts +259 -209
- package/src/tools/compareTransactions/parser.ts +517 -487
- package/src/tools/compareTransactions/types.ts +38 -38
- package/src/tools/compareTransactions.ts +1 -1
- package/src/tools/deltaFetcher.ts +281 -260
- package/src/tools/deltaSupport.ts +264 -259
- package/src/tools/exportTransactions.ts +230 -218
- package/src/tools/monthTools.ts +180 -165
- package/src/tools/payeeTools.ts +152 -140
- package/src/tools/reconcileAdapter.ts +297 -246
- package/src/tools/reconciliation/CLAUDE.md +506 -0
- package/src/tools/reconciliation/__tests__/adapter.causes.test.ts +135 -112
- package/src/tools/reconciliation/__tests__/adapter.test.ts +249 -227
- package/src/tools/reconciliation/__tests__/analyzer.test.ts +408 -335
- package/src/tools/reconciliation/__tests__/csvParser.test.ts +71 -69
- package/src/tools/reconciliation/__tests__/executor.integration.test.ts +348 -323
- package/src/tools/reconciliation/__tests__/executor.progress.test.ts +503 -457
- package/src/tools/reconciliation/__tests__/executor.test.ts +898 -831
- package/src/tools/reconciliation/__tests__/matcher.test.ts +667 -663
- package/src/tools/reconciliation/__tests__/payeeNormalizer.test.ts +296 -276
- package/src/tools/reconciliation/__tests__/recommendationEngine.integration.test.ts +692 -624
- package/src/tools/reconciliation/__tests__/recommendationEngine.test.ts +1008 -986
- package/src/tools/reconciliation/__tests__/reconciliation.delta.integration.test.ts +187 -146
- package/src/tools/reconciliation/__tests__/reportFormatter.test.ts +583 -530
- package/src/tools/reconciliation/__tests__/scenarios/adapterCurrency.scenario.test.ts +75 -71
- package/src/tools/reconciliation/__tests__/scenarios/extremes.scenario.test.ts +70 -58
- package/src/tools/reconciliation/__tests__/scenarios/repeatAmount.scenario.test.ts +102 -88
- package/src/tools/reconciliation/__tests__/schemaUrl.test.ts +58 -43
- package/src/tools/reconciliation/__tests__/signDetector.test.ts +209 -206
- package/src/tools/reconciliation/__tests__/ynabAdapter.test.ts +66 -60
- package/src/tools/reconciliation/analyzer.ts +582 -406
- package/src/tools/reconciliation/csvParser.ts +656 -609
- package/src/tools/reconciliation/executor.ts +1290 -1128
- package/src/tools/reconciliation/index.ts +580 -528
- package/src/tools/reconciliation/matcher.ts +256 -240
- package/src/tools/reconciliation/payeeNormalizer.ts +92 -78
- package/src/tools/reconciliation/recommendationEngine.ts +357 -345
- package/src/tools/reconciliation/reportFormatter.ts +349 -276
- package/src/tools/reconciliation/signDetector.ts +89 -83
- package/src/tools/reconciliation/types.ts +164 -153
- package/src/tools/reconciliation/ynabAdapter.ts +17 -15
- package/src/tools/schemas/CLAUDE.md +546 -0
- package/src/tools/schemas/common.ts +1 -1
- package/src/tools/schemas/outputs/__tests__/accountOutputs.test.ts +410 -409
- package/src/tools/schemas/outputs/__tests__/budgetOutputs.test.ts +305 -299
- package/src/tools/schemas/outputs/__tests__/categoryOutputs.test.ts +431 -430
- package/src/tools/schemas/outputs/__tests__/comparisonOutputs.test.ts +510 -495
- package/src/tools/schemas/outputs/__tests__/dateValidation.test.ts +179 -153
- package/src/tools/schemas/outputs/__tests__/discrepancyDirection.test.ts +293 -254
- package/src/tools/schemas/outputs/__tests__/monthOutputs.test.ts +457 -457
- package/src/tools/schemas/outputs/__tests__/payeeOutputs.test.ts +362 -356
- package/src/tools/schemas/outputs/__tests__/reconciliationOutputs.test.ts +402 -399
- package/src/tools/schemas/outputs/__tests__/transactionMutationSchemas.test.ts +225 -211
- package/src/tools/schemas/outputs/__tests__/transactionOutputs.test.ts +457 -454
- package/src/tools/schemas/outputs/__tests__/utilityOutputs.test.ts +316 -315
- package/src/tools/schemas/outputs/accountOutputs.ts +40 -34
- package/src/tools/schemas/outputs/budgetOutputs.ts +24 -19
- package/src/tools/schemas/outputs/categoryOutputs.ts +76 -56
- package/src/tools/schemas/outputs/comparisonOutputs.ts +192 -169
- package/src/tools/schemas/outputs/index.ts +163 -163
- package/src/tools/schemas/outputs/monthOutputs.ts +95 -80
- package/src/tools/schemas/outputs/payeeOutputs.ts +18 -18
- package/src/tools/schemas/outputs/reconciliationOutputs.ts +386 -373
- package/src/tools/schemas/outputs/transactionMutationOutputs.ts +259 -231
- package/src/tools/schemas/outputs/transactionOutputs.ts +81 -71
- package/src/tools/schemas/outputs/utilityOutputs.ts +90 -84
- package/src/tools/schemas/shared/commonOutputs.ts +27 -19
- package/src/tools/toolCategories.ts +114 -114
- package/src/tools/transactionReadTools.ts +327 -0
- package/src/tools/transactionSchemas.ts +484 -0
- package/src/tools/transactionTools.ts +107 -2990
- package/src/tools/transactionUtils.ts +621 -0
- package/src/tools/transactionWriteTools.ts +2110 -0
- package/src/tools/utilityTools.ts +46 -41
- package/src/types/CLAUDE.md +477 -0
- package/src/types/__tests__/index.test.ts +51 -51
- package/src/types/index.ts +43 -39
- package/src/types/integration-tests.d.ts +26 -26
- package/src/types/reconciliation.ts +29 -29
- package/src/types/toolAnnotations.ts +30 -30
- package/src/types/toolRegistration.ts +43 -32
- package/src/utils/CLAUDE.md +508 -0
- package/src/utils/__tests__/dateUtils.test.ts +174 -168
- package/src/utils/__tests__/money.test.ts +193 -187
- package/src/utils/amountUtils.ts +5 -5
- package/src/utils/baseError.ts +5 -5
- package/src/utils/dateUtils.ts +29 -26
- package/src/utils/errors.ts +14 -14
- package/src/utils/money.ts +66 -52
- package/src/utils/validationError.ts +1 -1
- package/tsconfig.json +29 -29
- package/tsconfig.prod.json +16 -16
- package/vitest-reporters/split-json-reporter.ts +247 -204
- package/vitest.config.ts +99 -95
- package/.prettierignore +0 -10
- package/.prettierrc.json +0 -10
- package/eslint.config.js +0 -49
|
@@ -0,0 +1,484 @@
|
|
|
1
|
+
import type * as ynab from "ynab";
|
|
2
|
+
import { z } from "zod/v4";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Transaction Schemas and Types
|
|
6
|
+
*
|
|
7
|
+
* This module contains all Zod schemas and TypeScript types for transaction-related tools.
|
|
8
|
+
* Extracted from transactionTools.ts for better code organization.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
// ============================================================================
|
|
12
|
+
// List Transactions
|
|
13
|
+
// ============================================================================
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Schema for ynab:list_transactions tool parameters
|
|
17
|
+
*/
|
|
18
|
+
export const ListTransactionsSchema = z
|
|
19
|
+
.object({
|
|
20
|
+
budget_id: z.string().min(1, "Budget ID is required"),
|
|
21
|
+
account_id: z.string().optional(),
|
|
22
|
+
category_id: z.string().optional(),
|
|
23
|
+
since_date: z
|
|
24
|
+
.string()
|
|
25
|
+
.regex(/^\d{4}-\d{2}-\d{2}$/, "Date must be in ISO format (YYYY-MM-DD)")
|
|
26
|
+
.optional(),
|
|
27
|
+
type: z.enum(["uncategorized", "unapproved"]).optional(),
|
|
28
|
+
})
|
|
29
|
+
.strict();
|
|
30
|
+
|
|
31
|
+
export type ListTransactionsParams = z.infer<typeof ListTransactionsSchema>;
|
|
32
|
+
|
|
33
|
+
// ============================================================================
|
|
34
|
+
// Get Transaction
|
|
35
|
+
// ============================================================================
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Schema for ynab:get_transaction tool parameters
|
|
39
|
+
*/
|
|
40
|
+
export const GetTransactionSchema = z
|
|
41
|
+
.object({
|
|
42
|
+
budget_id: z.string().min(1, "Budget ID is required"),
|
|
43
|
+
transaction_id: z.string().min(1, "Transaction ID is required"),
|
|
44
|
+
})
|
|
45
|
+
.strict();
|
|
46
|
+
|
|
47
|
+
export type GetTransactionParams = z.infer<typeof GetTransactionSchema>;
|
|
48
|
+
|
|
49
|
+
// ============================================================================
|
|
50
|
+
// Create Transaction
|
|
51
|
+
// ============================================================================
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Schema for ynab:create_transaction tool parameters
|
|
55
|
+
*/
|
|
56
|
+
export const CreateTransactionSchema = z
|
|
57
|
+
.object({
|
|
58
|
+
budget_id: z.string().min(1, "Budget ID is required"),
|
|
59
|
+
account_id: z.string().min(1, "Account ID is required"),
|
|
60
|
+
amount: z.number().int("Amount must be an integer in milliunits"),
|
|
61
|
+
date: z
|
|
62
|
+
.string()
|
|
63
|
+
.regex(/^\d{4}-\d{2}-\d{2}$/, "Date must be in ISO format (YYYY-MM-DD)"),
|
|
64
|
+
payee_name: z.string().optional(),
|
|
65
|
+
payee_id: z.string().optional(),
|
|
66
|
+
category_id: z.string().optional(),
|
|
67
|
+
memo: z.string().optional(),
|
|
68
|
+
cleared: z.enum(["cleared", "uncleared", "reconciled"]).optional(),
|
|
69
|
+
approved: z.boolean().optional(),
|
|
70
|
+
flag_color: z
|
|
71
|
+
.enum(["red", "orange", "yellow", "green", "blue", "purple"])
|
|
72
|
+
.optional(),
|
|
73
|
+
import_id: z.string().min(1, "Import ID cannot be empty").optional(),
|
|
74
|
+
dry_run: z.boolean().optional(),
|
|
75
|
+
subtransactions: z
|
|
76
|
+
.array(
|
|
77
|
+
z
|
|
78
|
+
.object({
|
|
79
|
+
amount: z
|
|
80
|
+
.number()
|
|
81
|
+
.int("Subtransaction amount must be an integer in milliunits"),
|
|
82
|
+
payee_name: z.string().optional(),
|
|
83
|
+
payee_id: z.string().optional(),
|
|
84
|
+
category_id: z.string().optional(),
|
|
85
|
+
memo: z.string().optional(),
|
|
86
|
+
})
|
|
87
|
+
.strict(),
|
|
88
|
+
)
|
|
89
|
+
.min(1, "At least one subtransaction is required when provided")
|
|
90
|
+
.optional(),
|
|
91
|
+
})
|
|
92
|
+
.strict()
|
|
93
|
+
.superRefine((data, ctx) => {
|
|
94
|
+
if (data.subtransactions && data.subtransactions.length > 0) {
|
|
95
|
+
const total = data.subtransactions.reduce(
|
|
96
|
+
(sum, sub) => sum + sub.amount,
|
|
97
|
+
0,
|
|
98
|
+
);
|
|
99
|
+
if (total !== data.amount) {
|
|
100
|
+
ctx.addIssue({
|
|
101
|
+
code: z.ZodIssueCode.custom,
|
|
102
|
+
message: "Amount must equal the sum of subtransaction amounts",
|
|
103
|
+
path: ["amount"],
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
export type CreateTransactionParams = z.infer<typeof CreateTransactionSchema>;
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Schema for subtransaction input
|
|
113
|
+
*/
|
|
114
|
+
export interface SubtransactionInput {
|
|
115
|
+
amount: number;
|
|
116
|
+
payee_name?: string;
|
|
117
|
+
payee_id?: string;
|
|
118
|
+
category_id?: string;
|
|
119
|
+
memo?: string;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// ============================================================================
|
|
123
|
+
// Create Transactions (Bulk)
|
|
124
|
+
// ============================================================================
|
|
125
|
+
|
|
126
|
+
const BulkTransactionInputSchemaBase = CreateTransactionSchema.pick({
|
|
127
|
+
account_id: true,
|
|
128
|
+
amount: true,
|
|
129
|
+
date: true,
|
|
130
|
+
payee_name: true,
|
|
131
|
+
payee_id: true,
|
|
132
|
+
category_id: true,
|
|
133
|
+
memo: true,
|
|
134
|
+
cleared: true,
|
|
135
|
+
approved: true,
|
|
136
|
+
flag_color: true,
|
|
137
|
+
import_id: true,
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
export type BulkTransactionInput = Omit<
|
|
141
|
+
CreateTransactionParams,
|
|
142
|
+
"budget_id" | "dry_run" | "subtransactions"
|
|
143
|
+
>;
|
|
144
|
+
|
|
145
|
+
// Schema for bulk transaction creation - subtransactions are not supported
|
|
146
|
+
// The .strict() modifier automatically rejects any fields not in the schema
|
|
147
|
+
const BulkTransactionInputSchema = BulkTransactionInputSchemaBase.strict();
|
|
148
|
+
|
|
149
|
+
export const CreateTransactionsSchema = z
|
|
150
|
+
.object({
|
|
151
|
+
budget_id: z.string().min(1, "Budget ID is required"),
|
|
152
|
+
transactions: z
|
|
153
|
+
.array(BulkTransactionInputSchema)
|
|
154
|
+
.min(1, "At least one transaction is required")
|
|
155
|
+
.max(100, "A maximum of 100 transactions may be created at once"),
|
|
156
|
+
dry_run: z.boolean().optional(),
|
|
157
|
+
})
|
|
158
|
+
.strict();
|
|
159
|
+
|
|
160
|
+
export type CreateTransactionsParams = z.infer<typeof CreateTransactionsSchema>;
|
|
161
|
+
|
|
162
|
+
export interface BulkTransactionResult {
|
|
163
|
+
request_index: number;
|
|
164
|
+
status: "created" | "duplicate" | "failed";
|
|
165
|
+
transaction_id?: string | undefined;
|
|
166
|
+
correlation_key: string;
|
|
167
|
+
error_code?: string | undefined;
|
|
168
|
+
error?: string | undefined;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export interface BulkCreateResponse {
|
|
172
|
+
success: boolean;
|
|
173
|
+
server_knowledge?: number;
|
|
174
|
+
summary: {
|
|
175
|
+
total_requested: number;
|
|
176
|
+
created: number;
|
|
177
|
+
duplicates: number;
|
|
178
|
+
failed: number;
|
|
179
|
+
};
|
|
180
|
+
results: BulkTransactionResult[];
|
|
181
|
+
transactions?: ynab.TransactionDetail[];
|
|
182
|
+
duplicate_import_ids?: string[];
|
|
183
|
+
message?: string;
|
|
184
|
+
mode?: "full" | "summary" | "ids_only";
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// ============================================================================
|
|
188
|
+
// Create Receipt Split Transaction
|
|
189
|
+
// ============================================================================
|
|
190
|
+
|
|
191
|
+
const ReceiptSplitItemSchema = z
|
|
192
|
+
.object({
|
|
193
|
+
name: z.string().min(1, "Item name is required"),
|
|
194
|
+
amount: z.number().finite("Item amount must be a finite number"),
|
|
195
|
+
quantity: z
|
|
196
|
+
.number()
|
|
197
|
+
.finite("Quantity must be a finite number")
|
|
198
|
+
.positive("Quantity must be greater than zero")
|
|
199
|
+
.optional(),
|
|
200
|
+
memo: z.string().optional(),
|
|
201
|
+
})
|
|
202
|
+
.strict();
|
|
203
|
+
|
|
204
|
+
const ReceiptSplitCategorySchema = z
|
|
205
|
+
.object({
|
|
206
|
+
category_id: z.string().min(1, "Category ID is required"),
|
|
207
|
+
category_name: z.string().optional(),
|
|
208
|
+
items: z
|
|
209
|
+
.array(ReceiptSplitItemSchema)
|
|
210
|
+
.min(1, "Each category must include at least one item"),
|
|
211
|
+
})
|
|
212
|
+
.strict();
|
|
213
|
+
|
|
214
|
+
export const CreateReceiptSplitTransactionSchema = z
|
|
215
|
+
.object({
|
|
216
|
+
budget_id: z.string().min(1, "Budget ID is required"),
|
|
217
|
+
account_id: z.string().min(1, "Account ID is required"),
|
|
218
|
+
payee_name: z.string().min(1, "Payee name is required"),
|
|
219
|
+
date: z
|
|
220
|
+
.string()
|
|
221
|
+
.regex(
|
|
222
|
+
/^[0-9]{4}-[0-9]{2}-[0-9]{2}$/,
|
|
223
|
+
"Date must be in ISO format (YYYY-MM-DD)",
|
|
224
|
+
)
|
|
225
|
+
.optional(),
|
|
226
|
+
memo: z.string().optional(),
|
|
227
|
+
receipt_subtotal: z
|
|
228
|
+
.number()
|
|
229
|
+
.finite("Receipt subtotal must be a finite number")
|
|
230
|
+
.refine((value) => value >= 0, "Receipt subtotal must be zero or greater")
|
|
231
|
+
.optional(),
|
|
232
|
+
receipt_tax: z.number().finite("Receipt tax must be a finite number"),
|
|
233
|
+
receipt_total: z
|
|
234
|
+
.number()
|
|
235
|
+
.finite("Receipt total must be a finite number")
|
|
236
|
+
.refine((value) => value > 0, "Receipt total must be greater than zero"),
|
|
237
|
+
categories: z
|
|
238
|
+
.array(ReceiptSplitCategorySchema)
|
|
239
|
+
.min(
|
|
240
|
+
1,
|
|
241
|
+
"At least one categorized group is required to create a split transaction",
|
|
242
|
+
),
|
|
243
|
+
cleared: z.enum(["cleared", "uncleared", "reconciled"]).optional(),
|
|
244
|
+
approved: z.boolean().optional(),
|
|
245
|
+
flag_color: z
|
|
246
|
+
.enum(["red", "orange", "yellow", "green", "blue", "purple"])
|
|
247
|
+
.optional(),
|
|
248
|
+
dry_run: z.boolean().optional(),
|
|
249
|
+
})
|
|
250
|
+
.strict()
|
|
251
|
+
.superRefine((data, ctx) => {
|
|
252
|
+
const itemsSubtotal = data.categories
|
|
253
|
+
.flatMap((category) => category.items)
|
|
254
|
+
.reduce((sum, item) => sum + item.amount, 0);
|
|
255
|
+
|
|
256
|
+
if (data.receipt_subtotal !== undefined) {
|
|
257
|
+
const delta = Math.abs(data.receipt_subtotal - itemsSubtotal);
|
|
258
|
+
if (delta > 0.01) {
|
|
259
|
+
ctx.addIssue({
|
|
260
|
+
code: z.ZodIssueCode.custom,
|
|
261
|
+
message: `Receipt subtotal (${data.receipt_subtotal.toFixed(2)}) does not match categorized items total (${itemsSubtotal.toFixed(2)})`,
|
|
262
|
+
path: ["receipt_subtotal"],
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
const expectedTotal = itemsSubtotal + data.receipt_tax;
|
|
268
|
+
const deltaTotal = Math.abs(expectedTotal - data.receipt_total);
|
|
269
|
+
if (deltaTotal > 0.01) {
|
|
270
|
+
ctx.addIssue({
|
|
271
|
+
code: z.ZodIssueCode.custom,
|
|
272
|
+
message: `Receipt total (${data.receipt_total.toFixed(2)}) does not match subtotal plus tax (${expectedTotal.toFixed(2)})`,
|
|
273
|
+
path: ["receipt_total"],
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
export type CreateReceiptSplitTransactionParams = z.infer<
|
|
279
|
+
typeof CreateReceiptSplitTransactionSchema
|
|
280
|
+
>;
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Interface for receipt category calculation
|
|
284
|
+
*/
|
|
285
|
+
export interface ReceiptCategoryCalculation {
|
|
286
|
+
category_id: string;
|
|
287
|
+
category_name: string | undefined;
|
|
288
|
+
subtotal_milliunits: number;
|
|
289
|
+
tax_milliunits: number;
|
|
290
|
+
items: {
|
|
291
|
+
name: string;
|
|
292
|
+
amount_milliunits: number;
|
|
293
|
+
quantity: number | undefined;
|
|
294
|
+
memo: string | undefined;
|
|
295
|
+
}[];
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// ============================================================================
|
|
299
|
+
// Update Transaction
|
|
300
|
+
// ============================================================================
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Schema for ynab:update_transaction tool parameters
|
|
304
|
+
*/
|
|
305
|
+
export const UpdateTransactionSchema = z
|
|
306
|
+
.object({
|
|
307
|
+
budget_id: z.string().min(1, "Budget ID is required"),
|
|
308
|
+
transaction_id: z.string().min(1, "Transaction ID is required"),
|
|
309
|
+
account_id: z.string().optional(),
|
|
310
|
+
amount: z
|
|
311
|
+
.number()
|
|
312
|
+
.int("Amount must be an integer in milliunits")
|
|
313
|
+
.optional(),
|
|
314
|
+
date: z
|
|
315
|
+
.string()
|
|
316
|
+
.regex(/^\d{4}-\d{2}-\d{2}$/, "Date must be in ISO format (YYYY-MM-DD)")
|
|
317
|
+
.optional(),
|
|
318
|
+
payee_name: z.string().optional(),
|
|
319
|
+
payee_id: z.string().optional(),
|
|
320
|
+
category_id: z.string().optional(),
|
|
321
|
+
memo: z.string().optional(),
|
|
322
|
+
cleared: z.enum(["cleared", "uncleared", "reconciled"]).optional(),
|
|
323
|
+
approved: z.boolean().optional(),
|
|
324
|
+
flag_color: z
|
|
325
|
+
.enum(["red", "orange", "yellow", "green", "blue", "purple"])
|
|
326
|
+
.optional(),
|
|
327
|
+
dry_run: z.boolean().optional(),
|
|
328
|
+
})
|
|
329
|
+
.strict();
|
|
330
|
+
|
|
331
|
+
export type UpdateTransactionParams = z.infer<typeof UpdateTransactionSchema>;
|
|
332
|
+
|
|
333
|
+
// ============================================================================
|
|
334
|
+
// Update Transactions (Bulk)
|
|
335
|
+
// ============================================================================
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* Schema for bulk transaction updates - each item in the array
|
|
339
|
+
* Note: account_id is intentionally excluded as account moves are not supported in bulk updates
|
|
340
|
+
*/
|
|
341
|
+
const BulkUpdateTransactionInputSchema = z
|
|
342
|
+
.object({
|
|
343
|
+
id: z.string().min(1, "Transaction ID is required"),
|
|
344
|
+
amount: z
|
|
345
|
+
.number()
|
|
346
|
+
.int("Amount must be an integer in milliunits")
|
|
347
|
+
.optional(),
|
|
348
|
+
date: z
|
|
349
|
+
.string()
|
|
350
|
+
.regex(/^\d{4}-\d{2}-\d{2}$/, "Date must be in ISO format (YYYY-MM-DD)")
|
|
351
|
+
.optional(),
|
|
352
|
+
payee_name: z.string().optional(),
|
|
353
|
+
payee_id: z.string().optional(),
|
|
354
|
+
category_id: z.string().optional(),
|
|
355
|
+
memo: z.string().optional(),
|
|
356
|
+
cleared: z.enum(["cleared", "uncleared", "reconciled"]).optional(),
|
|
357
|
+
approved: z.boolean().optional(),
|
|
358
|
+
flag_color: z
|
|
359
|
+
.enum(["red", "orange", "yellow", "green", "blue", "purple"])
|
|
360
|
+
.optional(),
|
|
361
|
+
// Metadata fields for cache invalidation
|
|
362
|
+
original_account_id: z.string().optional(),
|
|
363
|
+
original_date: z
|
|
364
|
+
.string()
|
|
365
|
+
.regex(/^\d{4}-\d{2}-\d{2}$/, "Date must be in ISO format (YYYY-MM-DD)")
|
|
366
|
+
.optional(),
|
|
367
|
+
})
|
|
368
|
+
.strict();
|
|
369
|
+
|
|
370
|
+
export type BulkUpdateTransactionInput = z.infer<
|
|
371
|
+
typeof BulkUpdateTransactionInputSchema
|
|
372
|
+
>;
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* Schema for ynab:update_transactions tool parameters
|
|
376
|
+
*/
|
|
377
|
+
export const UpdateTransactionsSchema = z
|
|
378
|
+
.object({
|
|
379
|
+
budget_id: z.string().min(1, "Budget ID is required"),
|
|
380
|
+
transactions: z
|
|
381
|
+
.array(BulkUpdateTransactionInputSchema)
|
|
382
|
+
.min(1, "At least one transaction is required")
|
|
383
|
+
.max(100, "A maximum of 100 transactions may be updated at once"),
|
|
384
|
+
dry_run: z.boolean().optional(),
|
|
385
|
+
})
|
|
386
|
+
.strict();
|
|
387
|
+
|
|
388
|
+
export type UpdateTransactionsParams = z.infer<typeof UpdateTransactionsSchema>;
|
|
389
|
+
|
|
390
|
+
export interface BulkUpdateResult {
|
|
391
|
+
request_index: number;
|
|
392
|
+
status: "updated" | "failed";
|
|
393
|
+
transaction_id: string;
|
|
394
|
+
correlation_key: string;
|
|
395
|
+
error_code?: string;
|
|
396
|
+
error?: string;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
export interface BulkUpdateResponse {
|
|
400
|
+
success: boolean;
|
|
401
|
+
server_knowledge?: number;
|
|
402
|
+
summary: {
|
|
403
|
+
total_requested: number;
|
|
404
|
+
updated: number;
|
|
405
|
+
failed: number;
|
|
406
|
+
};
|
|
407
|
+
results: BulkUpdateResult[];
|
|
408
|
+
transactions?: ynab.TransactionDetail[];
|
|
409
|
+
message?: string;
|
|
410
|
+
mode?: "full" | "summary" | "ids_only";
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
// ============================================================================
|
|
414
|
+
// Delete Transaction
|
|
415
|
+
// ============================================================================
|
|
416
|
+
|
|
417
|
+
/**
|
|
418
|
+
* Schema for ynab:delete_transaction tool parameters
|
|
419
|
+
*/
|
|
420
|
+
export const DeleteTransactionSchema = z
|
|
421
|
+
.object({
|
|
422
|
+
budget_id: z.string().min(1, "Budget ID is required"),
|
|
423
|
+
transaction_id: z.string().min(1, "Transaction ID is required"),
|
|
424
|
+
dry_run: z.boolean().optional(),
|
|
425
|
+
})
|
|
426
|
+
.strict();
|
|
427
|
+
|
|
428
|
+
export type DeleteTransactionParams = z.infer<typeof DeleteTransactionSchema>;
|
|
429
|
+
|
|
430
|
+
// ============================================================================
|
|
431
|
+
// Correlation & Utility Types
|
|
432
|
+
// ============================================================================
|
|
433
|
+
|
|
434
|
+
/**
|
|
435
|
+
* Type for correlation payload used in bulk operations
|
|
436
|
+
*/
|
|
437
|
+
export interface CorrelationPayload {
|
|
438
|
+
account_id?: string;
|
|
439
|
+
date?: string;
|
|
440
|
+
amount?: number;
|
|
441
|
+
payee_id?: string | null;
|
|
442
|
+
payee_name?: string | null;
|
|
443
|
+
category_id?: string | null;
|
|
444
|
+
memo?: string | null;
|
|
445
|
+
cleared?: ynab.TransactionClearedStatus;
|
|
446
|
+
approved?: boolean;
|
|
447
|
+
flag_color?: ynab.TransactionFlagColor | null;
|
|
448
|
+
import_id?: string | null;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
/**
|
|
452
|
+
* Interface for correlation payload input (with optional fields)
|
|
453
|
+
*/
|
|
454
|
+
export interface CorrelationPayloadInput {
|
|
455
|
+
account_id?: string | undefined;
|
|
456
|
+
date?: string | undefined;
|
|
457
|
+
amount?: number | undefined;
|
|
458
|
+
payee_id?: string | null | undefined;
|
|
459
|
+
payee_name?: string | null | undefined;
|
|
460
|
+
category_id?: string | null | undefined;
|
|
461
|
+
memo?: string | null | undefined;
|
|
462
|
+
cleared?: ynab.TransactionClearedStatus | undefined;
|
|
463
|
+
approved?: boolean | undefined;
|
|
464
|
+
flag_color?: ynab.TransactionFlagColor | null | undefined;
|
|
465
|
+
import_id?: string | null | undefined;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
/**
|
|
469
|
+
* Interface for category source (used in cache invalidation)
|
|
470
|
+
*/
|
|
471
|
+
export interface CategorySource {
|
|
472
|
+
category_id?: string | null;
|
|
473
|
+
subtransactions?: { category_id?: string | null }[] | null | undefined;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* Interface for transaction cache invalidation options
|
|
478
|
+
*/
|
|
479
|
+
export interface TransactionCacheInvalidationOptions {
|
|
480
|
+
affectedCategoryIds?: Set<string>;
|
|
481
|
+
invalidateAllCategories?: boolean;
|
|
482
|
+
accountTotalsChanged?: boolean;
|
|
483
|
+
invalidateMonths?: boolean;
|
|
484
|
+
}
|