@accounter/server 0.0.8-alpha-20251102200443-d7162b8ce1dfc629b8b454df17dcec9ed005a052 → 0.0.8-alpha-20251103003648-f6467c8cb9c739ec4439c260bccc7325f6a761ae
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 +47 -7
- package/dist/green-invoice-graphql/src/mesh-artifacts/index.d.ts +7 -7
- package/dist/server/src/__generated__/types.d.ts +77 -0
- package/dist/server/src/__generated__/types.js.map +1 -1
- package/dist/server/src/modules/charges-matcher/__generated__/types.d.ts +68 -0
- package/dist/server/src/modules/charges-matcher/__generated__/types.js +7 -0
- package/dist/server/src/modules/charges-matcher/__generated__/types.js.map +1 -0
- package/dist/server/src/modules/charges-matcher/__tests__/amount-confidence.test.d.ts +1 -0
- package/dist/server/src/modules/charges-matcher/__tests__/amount-confidence.test.js +218 -0
- package/dist/server/src/modules/charges-matcher/__tests__/amount-confidence.test.js.map +1 -0
- package/dist/server/src/modules/charges-matcher/__tests__/auto-match-integration.test.d.ts +1 -0
- package/dist/server/src/modules/charges-matcher/__tests__/auto-match-integration.test.js +645 -0
- package/dist/server/src/modules/charges-matcher/__tests__/auto-match-integration.test.js.map +1 -0
- package/dist/server/src/modules/charges-matcher/__tests__/auto-match.test.d.ts +1 -0
- package/dist/server/src/modules/charges-matcher/__tests__/auto-match.test.js +530 -0
- package/dist/server/src/modules/charges-matcher/__tests__/auto-match.test.js.map +1 -0
- package/dist/server/src/modules/charges-matcher/__tests__/business-confidence.test.d.ts +1 -0
- package/dist/server/src/modules/charges-matcher/__tests__/business-confidence.test.js +143 -0
- package/dist/server/src/modules/charges-matcher/__tests__/business-confidence.test.js.map +1 -0
- package/dist/server/src/modules/charges-matcher/__tests__/candidate-filter.test.d.ts +1 -0
- package/dist/server/src/modules/charges-matcher/__tests__/candidate-filter.test.js +186 -0
- package/dist/server/src/modules/charges-matcher/__tests__/candidate-filter.test.js.map +1 -0
- package/dist/server/src/modules/charges-matcher/__tests__/charge-validator.test.d.ts +1 -0
- package/dist/server/src/modules/charges-matcher/__tests__/charge-validator.test.js +301 -0
- package/dist/server/src/modules/charges-matcher/__tests__/charge-validator.test.js.map +1 -0
- package/dist/server/src/modules/charges-matcher/__tests__/currency-confidence.test.d.ts +1 -0
- package/dist/server/src/modules/charges-matcher/__tests__/currency-confidence.test.js +127 -0
- package/dist/server/src/modules/charges-matcher/__tests__/currency-confidence.test.js.map +1 -0
- package/dist/server/src/modules/charges-matcher/__tests__/date-confidence.test.d.ts +1 -0
- package/dist/server/src/modules/charges-matcher/__tests__/date-confidence.test.js +246 -0
- package/dist/server/src/modules/charges-matcher/__tests__/date-confidence.test.js.map +1 -0
- package/dist/server/src/modules/charges-matcher/__tests__/document-aggregator.test.d.ts +1 -0
- package/dist/server/src/modules/charges-matcher/__tests__/document-aggregator.test.js +475 -0
- package/dist/server/src/modules/charges-matcher/__tests__/document-aggregator.test.js.map +1 -0
- package/dist/server/src/modules/charges-matcher/__tests__/document-amount.test.d.ts +1 -0
- package/dist/server/src/modules/charges-matcher/__tests__/document-amount.test.js +287 -0
- package/dist/server/src/modules/charges-matcher/__tests__/document-amount.test.js.map +1 -0
- package/dist/server/src/modules/charges-matcher/__tests__/document-business.test.d.ts +1 -0
- package/dist/server/src/modules/charges-matcher/__tests__/document-business.test.js +151 -0
- package/dist/server/src/modules/charges-matcher/__tests__/document-business.test.js.map +1 -0
- package/dist/server/src/modules/charges-matcher/__tests__/match-scorer.test.d.ts +1 -0
- package/dist/server/src/modules/charges-matcher/__tests__/match-scorer.test.js +550 -0
- package/dist/server/src/modules/charges-matcher/__tests__/match-scorer.test.js.map +1 -0
- package/dist/server/src/modules/charges-matcher/__tests__/overall-confidence.test.d.ts +1 -0
- package/dist/server/src/modules/charges-matcher/__tests__/overall-confidence.test.js +410 -0
- package/dist/server/src/modules/charges-matcher/__tests__/overall-confidence.test.js.map +1 -0
- package/dist/server/src/modules/charges-matcher/__tests__/single-match-integration.test.d.ts +1 -0
- package/dist/server/src/modules/charges-matcher/__tests__/single-match-integration.test.js +504 -0
- package/dist/server/src/modules/charges-matcher/__tests__/single-match-integration.test.js.map +1 -0
- package/dist/server/src/modules/charges-matcher/__tests__/single-match.test.d.ts +1 -0
- package/dist/server/src/modules/charges-matcher/__tests__/single-match.test.js +483 -0
- package/dist/server/src/modules/charges-matcher/__tests__/single-match.test.js.map +1 -0
- package/dist/server/src/modules/charges-matcher/__tests__/test-helpers.d.ts +46 -0
- package/dist/server/src/modules/charges-matcher/__tests__/test-helpers.js +143 -0
- package/dist/server/src/modules/charges-matcher/__tests__/test-helpers.js.map +1 -0
- package/dist/server/src/modules/charges-matcher/__tests__/test-infrastructure.spec.d.ts +1 -0
- package/dist/server/src/modules/charges-matcher/__tests__/test-infrastructure.spec.js +137 -0
- package/dist/server/src/modules/charges-matcher/__tests__/test-infrastructure.spec.js.map +1 -0
- package/dist/server/src/modules/charges-matcher/__tests__/transaction-aggregator.test.d.ts +1 -0
- package/dist/server/src/modules/charges-matcher/__tests__/transaction-aggregator.test.js +415 -0
- package/dist/server/src/modules/charges-matcher/__tests__/transaction-aggregator.test.js.map +1 -0
- package/dist/server/src/modules/charges-matcher/helpers/amount-confidence.helper.d.ts +7 -0
- package/dist/server/src/modules/charges-matcher/helpers/amount-confidence.helper.js +70 -0
- package/dist/server/src/modules/charges-matcher/helpers/amount-confidence.helper.js.map +1 -0
- package/dist/server/src/modules/charges-matcher/helpers/business-confidence.helper.d.ts +7 -0
- package/dist/server/src/modules/charges-matcher/helpers/business-confidence.helper.js +19 -0
- package/dist/server/src/modules/charges-matcher/helpers/business-confidence.helper.js.map +1 -0
- package/dist/server/src/modules/charges-matcher/helpers/candidate-filter.helper.d.ts +24 -0
- package/dist/server/src/modules/charges-matcher/helpers/candidate-filter.helper.js +45 -0
- package/dist/server/src/modules/charges-matcher/helpers/candidate-filter.helper.js.map +1 -0
- package/dist/server/src/modules/charges-matcher/helpers/charge-validator.helper.d.ts +33 -0
- package/dist/server/src/modules/charges-matcher/helpers/charge-validator.helper.js +65 -0
- package/dist/server/src/modules/charges-matcher/helpers/charge-validator.helper.js.map +1 -0
- package/dist/server/src/modules/charges-matcher/helpers/currency-confidence.helper.d.ts +7 -0
- package/dist/server/src/modules/charges-matcher/helpers/currency-confidence.helper.js +18 -0
- package/dist/server/src/modules/charges-matcher/helpers/currency-confidence.helper.js.map +1 -0
- package/dist/server/src/modules/charges-matcher/helpers/date-confidence.helper.d.ts +7 -0
- package/dist/server/src/modules/charges-matcher/helpers/date-confidence.helper.js +35 -0
- package/dist/server/src/modules/charges-matcher/helpers/date-confidence.helper.js.map +1 -0
- package/dist/server/src/modules/charges-matcher/helpers/document-amount.helper.d.ts +49 -0
- package/dist/server/src/modules/charges-matcher/helpers/document-amount.helper.js +58 -0
- package/dist/server/src/modules/charges-matcher/helpers/document-amount.helper.js.map +1 -0
- package/dist/server/src/modules/charges-matcher/helpers/document-business.helper.d.ts +13 -0
- package/dist/server/src/modules/charges-matcher/helpers/document-business.helper.js +37 -0
- package/dist/server/src/modules/charges-matcher/helpers/document-business.helper.js.map +1 -0
- package/dist/server/src/modules/charges-matcher/helpers/overall-confidence.helper.d.ts +42 -0
- package/dist/server/src/modules/charges-matcher/helpers/overall-confidence.helper.js +77 -0
- package/dist/server/src/modules/charges-matcher/helpers/overall-confidence.helper.js.map +1 -0
- package/dist/server/src/modules/charges-matcher/index.d.ts +3 -0
- package/dist/server/src/modules/charges-matcher/index.js +15 -0
- package/dist/server/src/modules/charges-matcher/index.js.map +1 -0
- package/dist/server/src/modules/charges-matcher/providers/auto-match.provider.d.ts +48 -0
- package/dist/server/src/modules/charges-matcher/providers/auto-match.provider.js +133 -0
- package/dist/server/src/modules/charges-matcher/providers/auto-match.provider.js.map +1 -0
- package/dist/server/src/modules/charges-matcher/providers/charges-matcher.provider.d.ts +38 -0
- package/dist/server/src/modules/charges-matcher/providers/charges-matcher.provider.js +248 -0
- package/dist/server/src/modules/charges-matcher/providers/charges-matcher.provider.js.map +1 -0
- package/dist/server/src/modules/charges-matcher/providers/document-aggregator.d.ts +61 -0
- package/dist/server/src/modules/charges-matcher/providers/document-aggregator.js +153 -0
- package/dist/server/src/modules/charges-matcher/providers/document-aggregator.js.map +1 -0
- package/dist/server/src/modules/charges-matcher/providers/match-scorer.provider.d.ts +25 -0
- package/dist/server/src/modules/charges-matcher/providers/match-scorer.provider.js +114 -0
- package/dist/server/src/modules/charges-matcher/providers/match-scorer.provider.js.map +1 -0
- package/dist/server/src/modules/charges-matcher/providers/single-match.provider.d.ts +39 -0
- package/dist/server/src/modules/charges-matcher/providers/single-match.provider.js +189 -0
- package/dist/server/src/modules/charges-matcher/providers/single-match.provider.js.map +1 -0
- package/dist/server/src/modules/charges-matcher/providers/transaction-aggregator.d.ts +54 -0
- package/dist/server/src/modules/charges-matcher/providers/transaction-aggregator.js +93 -0
- package/dist/server/src/modules/charges-matcher/providers/transaction-aggregator.js.map +1 -0
- package/dist/server/src/modules/charges-matcher/resolvers/auto-match-charges.resolver.d.ts +2 -0
- package/dist/server/src/modules/charges-matcher/resolvers/auto-match-charges.resolver.js +22 -0
- package/dist/server/src/modules/charges-matcher/resolvers/auto-match-charges.resolver.js.map +1 -0
- package/dist/server/src/modules/charges-matcher/resolvers/find-charge-matches.resolver.d.ts +2 -0
- package/dist/server/src/modules/charges-matcher/resolvers/find-charge-matches.resolver.js +24 -0
- package/dist/server/src/modules/charges-matcher/resolvers/find-charge-matches.resolver.js.map +1 -0
- package/dist/server/src/modules/charges-matcher/resolvers/index.d.ts +2 -0
- package/dist/server/src/modules/charges-matcher/resolvers/index.js +11 -0
- package/dist/server/src/modules/charges-matcher/resolvers/index.js.map +1 -0
- package/dist/server/src/modules/charges-matcher/typeDefs/charges-matcher.graphql.d.ts +2 -0
- package/dist/server/src/modules/charges-matcher/typeDefs/charges-matcher.graphql.js +47 -0
- package/dist/server/src/modules/charges-matcher/typeDefs/charges-matcher.graphql.js.map +1 -0
- package/dist/server/src/modules/charges-matcher/types.d.ts +179 -0
- package/dist/server/src/modules/charges-matcher/types.js +14 -0
- package/dist/server/src/modules/charges-matcher/types.js.map +1 -0
- package/dist/server/src/modules/documents/resolvers/document-suggestions.resolver.js +2 -2
- package/dist/server/src/modules/documents/resolvers/document-suggestions.resolver.js.map +1 -1
- package/dist/server/src/modules/green-invoice/helpers/contract-to-draft.helper.js +1 -1
- package/dist/server/src/modules/green-invoice/helpers/contract-to-draft.helper.js.map +1 -1
- package/dist/server/src/modules/green-invoice/helpers/green-invoice.helper.d.ts +1 -1
- package/dist/server/src/modules/green-invoice/helpers/green-invoice.helper.js +1 -1
- package/dist/server/src/modules/green-invoice/helpers/green-invoice.helper.js.map +1 -1
- package/dist/server/src/modules-app.js +2 -0
- package/dist/server/src/modules-app.js.map +1 -1
- package/dist/server/src/shared/types/index.d.ts +1 -1
- package/package.json +4 -4
- package/src/__generated__/types.ts +87 -0
- package/src/modules/charges-matcher/README.md +279 -0
- package/src/modules/charges-matcher/__generated__/types.ts +71 -0
- package/src/modules/charges-matcher/__tests__/amount-confidence.test.ts +260 -0
- package/src/modules/charges-matcher/__tests__/auto-match-integration.test.ts +714 -0
- package/src/modules/charges-matcher/__tests__/auto-match.test.ts +621 -0
- package/src/modules/charges-matcher/__tests__/business-confidence.test.ts +177 -0
- package/src/modules/charges-matcher/__tests__/candidate-filter.test.ts +238 -0
- package/src/modules/charges-matcher/__tests__/charge-validator.test.ts +374 -0
- package/src/modules/charges-matcher/__tests__/currency-confidence.test.ts +164 -0
- package/src/modules/charges-matcher/__tests__/date-confidence.test.ts +291 -0
- package/src/modules/charges-matcher/__tests__/document-aggregator.test.ts +614 -0
- package/src/modules/charges-matcher/__tests__/document-amount.test.ts +352 -0
- package/src/modules/charges-matcher/__tests__/document-business.test.ts +192 -0
- package/src/modules/charges-matcher/__tests__/match-scorer.test.ts +659 -0
- package/src/modules/charges-matcher/__tests__/overall-confidence.test.ts +502 -0
- package/src/modules/charges-matcher/__tests__/single-match-integration.test.ts +556 -0
- package/src/modules/charges-matcher/__tests__/single-match.test.ts +608 -0
- package/src/modules/charges-matcher/__tests__/test-helpers.ts +174 -0
- package/src/modules/charges-matcher/__tests__/test-infrastructure.spec.ts +177 -0
- package/src/modules/charges-matcher/__tests__/transaction-aggregator.test.ts +547 -0
- package/src/modules/charges-matcher/documentation/README.md +331 -0
- package/src/modules/charges-matcher/documentation/SPEC.md +1503 -0
- package/src/modules/charges-matcher/documentation/TODO.md +799 -0
- package/src/modules/charges-matcher/helpers/amount-confidence.helper.ts +88 -0
- package/src/modules/charges-matcher/helpers/business-confidence.helper.ts +23 -0
- package/src/modules/charges-matcher/helpers/candidate-filter.helper.ts +56 -0
- package/src/modules/charges-matcher/helpers/charge-validator.helper.ts +100 -0
- package/src/modules/charges-matcher/helpers/currency-confidence.helper.ts +22 -0
- package/src/modules/charges-matcher/helpers/date-confidence.helper.ts +41 -0
- package/src/modules/charges-matcher/helpers/document-amount.helper.ts +77 -0
- package/src/modules/charges-matcher/helpers/document-business.helper.ts +54 -0
- package/src/modules/charges-matcher/helpers/overall-confidence.helper.ts +90 -0
- package/src/modules/charges-matcher/index.ts +17 -0
- package/src/modules/charges-matcher/providers/auto-match.provider.ts +176 -0
- package/src/modules/charges-matcher/providers/charges-matcher.provider.ts +322 -0
- package/src/modules/charges-matcher/providers/document-aggregator.ts +211 -0
- package/src/modules/charges-matcher/providers/match-scorer.provider.ts +154 -0
- package/src/modules/charges-matcher/providers/single-match.provider.ts +252 -0
- package/src/modules/charges-matcher/providers/transaction-aggregator.ts +131 -0
- package/src/modules/charges-matcher/resolvers/auto-match-charges.resolver.ts +23 -0
- package/src/modules/charges-matcher/resolvers/find-charge-matches.resolver.ts +25 -0
- package/src/modules/charges-matcher/resolvers/index.ts +12 -0
- package/src/modules/charges-matcher/typeDefs/charges-matcher.graphql.ts +47 -0
- package/src/modules/charges-matcher/types.ts +200 -0
- package/src/modules/documents/resolvers/document-suggestions.resolver.ts +2 -2
- package/src/modules/green-invoice/helpers/contract-to-draft.helper.ts +1 -1
- package/src/modules/green-invoice/helpers/green-invoice.helper.ts +1 -1
- package/src/modules-app.ts +2 -0
- package/src/shared/types/index.ts +1 -1
|
@@ -323,6 +323,19 @@ export type AuditOpinionType =
|
|
|
323
323
|
/** Unqualified opinion with other emphases (בנוסח אחיד עם הפניות תשומת לב אחרת) */
|
|
324
324
|
| 'UNQUALIFIED_WITH_OTHER_EMPHASES';
|
|
325
325
|
|
|
326
|
+
/** Result of the auto-match operation */
|
|
327
|
+
export type AutoMatchChargesResult = {
|
|
328
|
+
readonly __typename?: 'AutoMatchChargesResult';
|
|
329
|
+
/** Array of error messages encountered during the operation */
|
|
330
|
+
readonly errors: ReadonlyArray<Scalars['String']['output']>;
|
|
331
|
+
/** Array of charges that were merged, with their confidence scores */
|
|
332
|
+
readonly mergedCharges: ReadonlyArray<MergedCharge>;
|
|
333
|
+
/** Array of charge UUIDs that had multiple high-confidence matches and were skipped */
|
|
334
|
+
readonly skippedCharges: ReadonlyArray<Scalars['UUID']['output']>;
|
|
335
|
+
/** Total number of charges that were successfully matched and merged */
|
|
336
|
+
readonly totalMatches: Scalars['Int']['output'];
|
|
337
|
+
};
|
|
338
|
+
|
|
326
339
|
/** transactions for balance report */
|
|
327
340
|
export type BalanceTransactions = {
|
|
328
341
|
readonly __typename?: 'BalanceTransactions';
|
|
@@ -860,6 +873,22 @@ export type ChargeFilterType =
|
|
|
860
873
|
| 'EXPENSE'
|
|
861
874
|
| 'INCOME';
|
|
862
875
|
|
|
876
|
+
/** A single charge match with its confidence score */
|
|
877
|
+
export type ChargeMatch = {
|
|
878
|
+
readonly __typename?: 'ChargeMatch';
|
|
879
|
+
/** UUID of the matched charge */
|
|
880
|
+
readonly chargeId: Scalars['UUID']['output'];
|
|
881
|
+
/** Confidence score between 0.00 and 1.00 */
|
|
882
|
+
readonly confidenceScore: Scalars['Float']['output'];
|
|
883
|
+
};
|
|
884
|
+
|
|
885
|
+
/** Result of finding matches for a single charge */
|
|
886
|
+
export type ChargeMatchesResult = {
|
|
887
|
+
readonly __typename?: 'ChargeMatchesResult';
|
|
888
|
+
/** Array of up to 5 matches, ordered by confidence score (highest first) */
|
|
889
|
+
readonly matches: ReadonlyArray<ChargeMatch>;
|
|
890
|
+
};
|
|
891
|
+
|
|
863
892
|
/** represent charge's metadata */
|
|
864
893
|
export type ChargeMetadata = {
|
|
865
894
|
readonly __typename?: 'ChargeMetadata';
|
|
@@ -2549,6 +2578,15 @@ export type MergeChargesByTransactionReferenceResult = {
|
|
|
2549
2578
|
readonly success: Scalars['Boolean']['output'];
|
|
2550
2579
|
};
|
|
2551
2580
|
|
|
2581
|
+
/** A charge that was successfully merged during auto-match */
|
|
2582
|
+
export type MergedCharge = {
|
|
2583
|
+
readonly __typename?: 'MergedCharge';
|
|
2584
|
+
/** UUID of the deleted/merged-away charge */
|
|
2585
|
+
readonly chargeId: Scalars['UUID']['output'];
|
|
2586
|
+
/** Confidence score that triggered the merge */
|
|
2587
|
+
readonly confidenceScore: Scalars['Float']['output'];
|
|
2588
|
+
};
|
|
2589
|
+
|
|
2552
2590
|
/** a misc expense */
|
|
2553
2591
|
export type MiscExpense = {
|
|
2554
2592
|
readonly __typename?: 'MiscExpense';
|
|
@@ -2609,6 +2647,8 @@ export type Mutation = {
|
|
|
2609
2647
|
readonly addDeelContract: Scalars['Boolean']['output'];
|
|
2610
2648
|
readonly addSortCode: Scalars['Boolean']['output'];
|
|
2611
2649
|
readonly addTag: Scalars['Boolean']['output'];
|
|
2650
|
+
/** Automatically match all unmatched charges above the confidence threshold */
|
|
2651
|
+
readonly autoMatchCharges: AutoMatchChargesResult;
|
|
2612
2652
|
readonly batchGenerateBusinessesOutOfTransactions: ReadonlyArray<Business>;
|
|
2613
2653
|
readonly batchUpdateCharges: BatchUpdateChargesResult;
|
|
2614
2654
|
readonly batchUploadDocuments: ReadonlyArray<UploadDocumentResult>;
|
|
@@ -3570,6 +3610,8 @@ export type Query = {
|
|
|
3570
3610
|
/** get exchage rates by date */
|
|
3571
3611
|
readonly exchangeRates?: Maybe<ExchangeRates>;
|
|
3572
3612
|
readonly financialEntity: FinancialEntity;
|
|
3613
|
+
/** Find potential matches for a single unmatched charge */
|
|
3614
|
+
readonly findChargeMatches: ChargeMatchesResult;
|
|
3573
3615
|
readonly gmailListenerStatus: Scalars['Boolean']['output'];
|
|
3574
3616
|
readonly greenInvoiceClient: GreenInvoiceClient;
|
|
3575
3617
|
readonly incomeExpenseChart: IncomeExpenseChart;
|
|
@@ -3816,6 +3858,12 @@ export type QueryFinancialEntityArgs = {
|
|
|
3816
3858
|
};
|
|
3817
3859
|
|
|
3818
3860
|
|
|
3861
|
+
/** query root */
|
|
3862
|
+
export type QueryFindChargeMatchesArgs = {
|
|
3863
|
+
chargeId: Scalars['UUID']['input'];
|
|
3864
|
+
};
|
|
3865
|
+
|
|
3866
|
+
|
|
3819
3867
|
/** query root */
|
|
3820
3868
|
export type QueryGreenInvoiceClientArgs = {
|
|
3821
3869
|
clientId: Scalars['UUID']['input'];
|
|
@@ -5060,6 +5108,7 @@ export type ResolversTypes = {
|
|
|
5060
5108
|
AnnualId: ResolverTypeWrapper<AnnualId>;
|
|
5061
5109
|
AnnualIdInput: AnnualIdInput;
|
|
5062
5110
|
AuditOpinionType: AuditOpinionType;
|
|
5111
|
+
AutoMatchChargesResult: ResolverTypeWrapper<AutoMatchChargesResult>;
|
|
5063
5112
|
BalanceTransactions: ResolverTypeWrapper<IGetNormalizedBalanceTransactionsResult>;
|
|
5064
5113
|
BankDeposit: ResolverTypeWrapper<Omit<BankDeposit, 'transactions'> & { transactions: ReadonlyArray<ResolversTypes['Transaction']> }>;
|
|
5065
5114
|
BankDepositCharge: ResolverTypeWrapper<IGetChargesByIdsResult>;
|
|
@@ -5099,6 +5148,8 @@ export type ResolversTypes = {
|
|
|
5099
5148
|
Charge: ResolverTypeWrapper<ResolversInterfaceTypes<ResolversTypes>['Charge']>;
|
|
5100
5149
|
ChargeFilter: ChargeFilter;
|
|
5101
5150
|
ChargeFilterType: ChargeFilterType;
|
|
5151
|
+
ChargeMatch: ResolverTypeWrapper<ChargeMatch>;
|
|
5152
|
+
ChargeMatchesResult: ResolverTypeWrapper<ChargeMatchesResult>;
|
|
5102
5153
|
ChargeMetadata: ResolverTypeWrapper<IGetChargesByIdsResult>;
|
|
5103
5154
|
ChargeSortBy: ChargeSortBy;
|
|
5104
5155
|
ChargeSortByField: ChargeSortByField;
|
|
@@ -5226,6 +5277,7 @@ export type ResolversTypes = {
|
|
|
5226
5277
|
MergeChargeResult: ResolverTypeWrapper<ResolversUnionTypes<ResolversTypes>['MergeChargeResult']>;
|
|
5227
5278
|
MergeChargeSuccessfulResult: ResolverTypeWrapper<Omit<MergeChargeSuccessfulResult, 'charge'> & { charge: ResolversTypes['Charge'] }>;
|
|
5228
5279
|
MergeChargesByTransactionReferenceResult: ResolverTypeWrapper<Omit<MergeChargesByTransactionReferenceResult, 'charges'> & { charges?: Maybe<ReadonlyArray<ResolversTypes['Charge']>> }>;
|
|
5280
|
+
MergedCharge: ResolverTypeWrapper<MergedCharge>;
|
|
5229
5281
|
MiscExpense: ResolverTypeWrapper<IGetExpensesByChargeIdsResult>;
|
|
5230
5282
|
MissingChargeInfo: MissingChargeInfo;
|
|
5231
5283
|
MonthlyVatCharge: ResolverTypeWrapper<IGetChargesByIdsResult>;
|
|
@@ -5350,6 +5402,7 @@ export type ResolversParentTypes = {
|
|
|
5350
5402
|
AdminContextInput: AdminContextInput;
|
|
5351
5403
|
AnnualId: AnnualId;
|
|
5352
5404
|
AnnualIdInput: AnnualIdInput;
|
|
5405
|
+
AutoMatchChargesResult: AutoMatchChargesResult;
|
|
5353
5406
|
BalanceTransactions: IGetNormalizedBalanceTransactionsResult;
|
|
5354
5407
|
BankDeposit: Omit<BankDeposit, 'transactions'> & { transactions: ReadonlyArray<ResolversParentTypes['Transaction']> };
|
|
5355
5408
|
BankDepositCharge: IGetChargesByIdsResult;
|
|
@@ -5384,6 +5437,8 @@ export type ResolversParentTypes = {
|
|
|
5384
5437
|
CategorizeIntoExistingBusinessTripExpenseInput: CategorizeIntoExistingBusinessTripExpenseInput;
|
|
5385
5438
|
Charge: ResolversInterfaceTypes<ResolversParentTypes>['Charge'];
|
|
5386
5439
|
ChargeFilter: ChargeFilter;
|
|
5440
|
+
ChargeMatch: ChargeMatch;
|
|
5441
|
+
ChargeMatchesResult: ChargeMatchesResult;
|
|
5387
5442
|
ChargeMetadata: IGetChargesByIdsResult;
|
|
5388
5443
|
ChargeSortBy: ChargeSortBy;
|
|
5389
5444
|
ChargeSuggestions: Omit<ChargeSuggestions, 'tags'> & { tags: ReadonlyArray<ResolversParentTypes['Tag']> };
|
|
@@ -5488,6 +5543,7 @@ export type ResolversParentTypes = {
|
|
|
5488
5543
|
MergeChargeResult: ResolversUnionTypes<ResolversParentTypes>['MergeChargeResult'];
|
|
5489
5544
|
MergeChargeSuccessfulResult: Omit<MergeChargeSuccessfulResult, 'charge'> & { charge: ResolversParentTypes['Charge'] };
|
|
5490
5545
|
MergeChargesByTransactionReferenceResult: Omit<MergeChargesByTransactionReferenceResult, 'charges'> & { charges?: Maybe<ReadonlyArray<ResolversParentTypes['Charge']>> };
|
|
5546
|
+
MergedCharge: MergedCharge;
|
|
5491
5547
|
MiscExpense: IGetExpensesByChargeIdsResult;
|
|
5492
5548
|
MonthlyVatCharge: IGetChargesByIdsResult;
|
|
5493
5549
|
Mutation: {};
|
|
@@ -5695,6 +5751,14 @@ export type AnnualIdResolvers<ContextType = GraphQLModules.Context, ParentType e
|
|
|
5695
5751
|
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
|
|
5696
5752
|
};
|
|
5697
5753
|
|
|
5754
|
+
export type AutoMatchChargesResultResolvers<ContextType = GraphQLModules.Context, ParentType extends ResolversParentTypes['AutoMatchChargesResult'] = ResolversParentTypes['AutoMatchChargesResult']> = {
|
|
5755
|
+
errors?: Resolver<ReadonlyArray<ResolversTypes['String']>, ParentType, ContextType>;
|
|
5756
|
+
mergedCharges?: Resolver<ReadonlyArray<ResolversTypes['MergedCharge']>, ParentType, ContextType>;
|
|
5757
|
+
skippedCharges?: Resolver<ReadonlyArray<ResolversTypes['UUID']>, ParentType, ContextType>;
|
|
5758
|
+
totalMatches?: Resolver<ResolversTypes['Int'], ParentType, ContextType>;
|
|
5759
|
+
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
|
|
5760
|
+
};
|
|
5761
|
+
|
|
5698
5762
|
export type BalanceTransactionsResolvers<ContextType = GraphQLModules.Context, ParentType extends ResolversParentTypes['BalanceTransactions'] = ResolversParentTypes['BalanceTransactions']> = {
|
|
5699
5763
|
amount?: Resolver<ResolversTypes['FinancialAmount'], ParentType, ContextType>;
|
|
5700
5764
|
amountUsd?: Resolver<ResolversTypes['FinancialAmount'], ParentType, ContextType>;
|
|
@@ -6043,6 +6107,17 @@ export type ChargeResolvers<ContextType = GraphQLModules.Context, ParentType ext
|
|
|
6043
6107
|
yearsOfRelevance?: Resolver<Maybe<ReadonlyArray<ResolversTypes['YearOfRelevance']>>, ParentType, ContextType>;
|
|
6044
6108
|
};
|
|
6045
6109
|
|
|
6110
|
+
export type ChargeMatchResolvers<ContextType = GraphQLModules.Context, ParentType extends ResolversParentTypes['ChargeMatch'] = ResolversParentTypes['ChargeMatch']> = {
|
|
6111
|
+
chargeId?: Resolver<ResolversTypes['UUID'], ParentType, ContextType>;
|
|
6112
|
+
confidenceScore?: Resolver<ResolversTypes['Float'], ParentType, ContextType>;
|
|
6113
|
+
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
|
|
6114
|
+
};
|
|
6115
|
+
|
|
6116
|
+
export type ChargeMatchesResultResolvers<ContextType = GraphQLModules.Context, ParentType extends ResolversParentTypes['ChargeMatchesResult'] = ResolversParentTypes['ChargeMatchesResult']> = {
|
|
6117
|
+
matches?: Resolver<ReadonlyArray<ResolversTypes['ChargeMatch']>, ParentType, ContextType>;
|
|
6118
|
+
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
|
|
6119
|
+
};
|
|
6120
|
+
|
|
6046
6121
|
export type ChargeMetadataResolvers<ContextType = GraphQLModules.Context, ParentType extends ResolversParentTypes['ChargeMetadata'] = ResolversParentTypes['ChargeMetadata']> = {
|
|
6047
6122
|
createdAt?: Resolver<ResolversTypes['DateTime'], ParentType, ContextType>;
|
|
6048
6123
|
documentsCount?: Resolver<ResolversTypes['Int'], ParentType, ContextType>;
|
|
@@ -7000,6 +7075,12 @@ export type MergeChargesByTransactionReferenceResultResolvers<ContextType = Grap
|
|
|
7000
7075
|
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
|
|
7001
7076
|
};
|
|
7002
7077
|
|
|
7078
|
+
export type MergedChargeResolvers<ContextType = GraphQLModules.Context, ParentType extends ResolversParentTypes['MergedCharge'] = ResolversParentTypes['MergedCharge']> = {
|
|
7079
|
+
chargeId?: Resolver<ResolversTypes['UUID'], ParentType, ContextType>;
|
|
7080
|
+
confidenceScore?: Resolver<ResolversTypes['Float'], ParentType, ContextType>;
|
|
7081
|
+
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
|
|
7082
|
+
};
|
|
7083
|
+
|
|
7003
7084
|
export type MiscExpenseResolvers<ContextType = GraphQLModules.Context, ParentType extends ResolversParentTypes['MiscExpense'] = ResolversParentTypes['MiscExpense']> = {
|
|
7004
7085
|
amount?: Resolver<ResolversTypes['FinancialAmount'], ParentType, ContextType>;
|
|
7005
7086
|
charge?: Resolver<ResolversTypes['Charge'], ParentType, ContextType>;
|
|
@@ -7056,6 +7137,7 @@ export type MutationResolvers<ContextType = GraphQLModules.Context, ParentType e
|
|
|
7056
7137
|
addDeelContract?: Resolver<ResolversTypes['Boolean'], ParentType, ContextType, RequireFields<MutationAddDeelContractArgs, 'businessId' | 'contractId' | 'contractStartDate' | 'contractorId' | 'contractorName'>>;
|
|
7057
7138
|
addSortCode?: Resolver<ResolversTypes['Boolean'], ParentType, ContextType, RequireFields<MutationAddSortCodeArgs, 'key' | 'name'>>;
|
|
7058
7139
|
addTag?: Resolver<ResolversTypes['Boolean'], ParentType, ContextType, RequireFields<MutationAddTagArgs, 'name'>>;
|
|
7140
|
+
autoMatchCharges?: Resolver<ResolversTypes['AutoMatchChargesResult'], ParentType, ContextType>;
|
|
7059
7141
|
batchGenerateBusinessesOutOfTransactions?: Resolver<ReadonlyArray<ResolversTypes['Business']>, ParentType, ContextType>;
|
|
7060
7142
|
batchUpdateCharges?: Resolver<ResolversTypes['BatchUpdateChargesResult'], ParentType, ContextType, RequireFields<MutationBatchUpdateChargesArgs, 'chargeIds' | 'fields'>>;
|
|
7061
7143
|
batchUploadDocuments?: Resolver<ReadonlyArray<ResolversTypes['UploadDocumentResult']>, ParentType, ContextType, RequireFields<MutationBatchUploadDocumentsArgs, 'documents'>>;
|
|
@@ -7339,6 +7421,7 @@ export type QueryResolvers<ContextType = GraphQLModules.Context, ParentType exte
|
|
|
7339
7421
|
employeesByEmployerId?: Resolver<ReadonlyArray<ResolversTypes['Employee']>, ParentType, ContextType, RequireFields<QueryEmployeesByEmployerIdArgs, 'employerId'>>;
|
|
7340
7422
|
exchangeRates?: Resolver<Maybe<ResolversTypes['ExchangeRates']>, ParentType, ContextType, Partial<QueryExchangeRatesArgs>>;
|
|
7341
7423
|
financialEntity?: Resolver<ResolversTypes['FinancialEntity'], ParentType, ContextType, RequireFields<QueryFinancialEntityArgs, 'id'>>;
|
|
7424
|
+
findChargeMatches?: Resolver<ResolversTypes['ChargeMatchesResult'], ParentType, ContextType, RequireFields<QueryFindChargeMatchesArgs, 'chargeId'>>;
|
|
7342
7425
|
gmailListenerStatus?: Resolver<ResolversTypes['Boolean'], ParentType, ContextType>;
|
|
7343
7426
|
greenInvoiceClient?: Resolver<ResolversTypes['GreenInvoiceClient'], ParentType, ContextType, RequireFields<QueryGreenInvoiceClientArgs, 'clientId'>>;
|
|
7344
7427
|
incomeExpenseChart?: Resolver<ResolversTypes['IncomeExpenseChart'], ParentType, ContextType, RequireFields<QueryIncomeExpenseChartArgs, 'filters'>>;
|
|
@@ -7880,6 +7963,7 @@ export type Resolvers<ContextType = GraphQLModules.Context> = {
|
|
|
7880
7963
|
AdminBusiness?: AdminBusinessResolvers<ContextType>;
|
|
7881
7964
|
AdminContext?: AdminContextResolvers<ContextType>;
|
|
7882
7965
|
AnnualId?: AnnualIdResolvers<ContextType>;
|
|
7966
|
+
AutoMatchChargesResult?: AutoMatchChargesResultResolvers<ContextType>;
|
|
7883
7967
|
BalanceTransactions?: BalanceTransactionsResolvers<ContextType>;
|
|
7884
7968
|
BankDeposit?: BankDepositResolvers<ContextType>;
|
|
7885
7969
|
BankDepositCharge?: BankDepositChargeResolvers<ContextType>;
|
|
@@ -7907,6 +7991,8 @@ export type Resolvers<ContextType = GraphQLModules.Context> = {
|
|
|
7907
7991
|
BusinessTripTravelAndSubsistenceExpense?: BusinessTripTravelAndSubsistenceExpenseResolvers<ContextType>;
|
|
7908
7992
|
CardFinancialAccount?: CardFinancialAccountResolvers<ContextType>;
|
|
7909
7993
|
Charge?: ChargeResolvers<ContextType>;
|
|
7994
|
+
ChargeMatch?: ChargeMatchResolvers<ContextType>;
|
|
7995
|
+
ChargeMatchesResult?: ChargeMatchesResultResolvers<ContextType>;
|
|
7910
7996
|
ChargeMetadata?: ChargeMetadataResolvers<ContextType>;
|
|
7911
7997
|
ChargeSortByField?: ChargeSortByFieldResolvers;
|
|
7912
7998
|
ChargeSuggestions?: ChargeSuggestionsResolvers<ContextType>;
|
|
@@ -7989,6 +8075,7 @@ export type Resolvers<ContextType = GraphQLModules.Context> = {
|
|
|
7989
8075
|
MergeChargeResult?: MergeChargeResultResolvers<ContextType>;
|
|
7990
8076
|
MergeChargeSuccessfulResult?: MergeChargeSuccessfulResultResolvers<ContextType>;
|
|
7991
8077
|
MergeChargesByTransactionReferenceResult?: MergeChargesByTransactionReferenceResultResolvers<ContextType>;
|
|
8078
|
+
MergedCharge?: MergedChargeResolvers<ContextType>;
|
|
7992
8079
|
MiscExpense?: MiscExpenseResolvers<ContextType>;
|
|
7993
8080
|
MissingChargeInfo?: MissingChargeInfoResolvers;
|
|
7994
8081
|
MonthlyVatCharge?: MonthlyVatChargeResolvers<ContextType>;
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
# Charges Matcher Module
|
|
2
|
+
|
|
3
|
+
This module implements a transaction-document matching system for the Accounter fullstack
|
|
4
|
+
application. It provides both manual matching suggestions and automatic matching capabilities for
|
|
5
|
+
unmatched charges.
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
The charges-matcher module uses a confidence-based scoring algorithm to identify potential matches
|
|
10
|
+
between:
|
|
11
|
+
|
|
12
|
+
- Charges with only transactions (transaction charges)
|
|
13
|
+
- Charges with only accounting documents (document charges)
|
|
14
|
+
|
|
15
|
+
The system provides two main operations:
|
|
16
|
+
|
|
17
|
+
1. **Single-Match Query**: Find potential matches for a specific unmatched charge
|
|
18
|
+
2. **Auto-Match Mutation**: Automatically match all unmatched charges above a confidence threshold
|
|
19
|
+
|
|
20
|
+
## Module Structure
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
charges-matcher/
|
|
24
|
+
├── index.ts # Module exports and GraphQL module definition
|
|
25
|
+
├── types.ts # TypeScript type definitions
|
|
26
|
+
├── typeDefs/
|
|
27
|
+
│ └── charges-matcher.graphql.ts # GraphQL schema definitions
|
|
28
|
+
├── resolvers/ # GraphQL resolvers (to be implemented)
|
|
29
|
+
├── providers/ # Business logic providers (to be implemented)
|
|
30
|
+
├── helpers/ # Helper functions (to be implemented)
|
|
31
|
+
└── __tests__/
|
|
32
|
+
├── test-helpers.ts # Test utilities and mock factories
|
|
33
|
+
└── test-infrastructure.spec.ts # Infrastructure tests
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Type Definitions
|
|
37
|
+
|
|
38
|
+
### Shared Types
|
|
39
|
+
|
|
40
|
+
The module reuses types from existing modules:
|
|
41
|
+
|
|
42
|
+
- `Transaction`: From `@modules/transactions/types.js` (`IGetTransactionsByIdsResult`)
|
|
43
|
+
- `Document`: From `@modules/documents/types.js` (`IGetAllDocumentsResult`)
|
|
44
|
+
- `Currency`: Re-exported from documents module
|
|
45
|
+
- `DocumentType`: Re-exported from documents module
|
|
46
|
+
|
|
47
|
+
### GraphQL Response Types
|
|
48
|
+
|
|
49
|
+
- `ChargeMatch`: Single match with charge ID and confidence score
|
|
50
|
+
- `ChargeMatchesResult`: Array of matches (up to 5)
|
|
51
|
+
- `MergedCharge`: Record of a merged charge with confidence score
|
|
52
|
+
- `AutoMatchChargesResult`: Summary of auto-match operation
|
|
53
|
+
|
|
54
|
+
### Internal Types
|
|
55
|
+
|
|
56
|
+
- `AggregatedTransaction`: Aggregated data from multiple transactions
|
|
57
|
+
- `AggregatedDocument`: Aggregated data from multiple documents
|
|
58
|
+
- `ConfidenceScores`: Individual confidence scores for each matching factor
|
|
59
|
+
- `ConfidenceResult`: Complete confidence calculation result
|
|
60
|
+
- `ChargeType`: Enum for charge classification (TRANSACTION_ONLY, DOCUMENT_ONLY, MATCHED)
|
|
61
|
+
- `ChargeWithData`: Charge with its associated transactions and documents
|
|
62
|
+
- `MatchCandidate`: Candidate charge with aggregated data
|
|
63
|
+
|
|
64
|
+
## Database Schema
|
|
65
|
+
|
|
66
|
+
The module works with these existing tables:
|
|
67
|
+
|
|
68
|
+
### charges
|
|
69
|
+
|
|
70
|
+
- `id`: UUID (primary key)
|
|
71
|
+
- `owner_id`: UUID (references businesses)
|
|
72
|
+
- Other fields not directly used in matching logic
|
|
73
|
+
|
|
74
|
+
### transactions
|
|
75
|
+
|
|
76
|
+
- `id`: UUID
|
|
77
|
+
- `charge_id`: UUID (foreign key to charges)
|
|
78
|
+
- `amount`: numeric (PostgreSQL numeric type)
|
|
79
|
+
- `currency`: enum
|
|
80
|
+
- `business_id`: UUID (nullable)
|
|
81
|
+
- `event_date`: DATE
|
|
82
|
+
- `debit_date`: DATE (nullable)
|
|
83
|
+
- `debit_timestamp`: TIMESTAMP (nullable)
|
|
84
|
+
- `is_fee`: boolean
|
|
85
|
+
- `source_description`: text (nullable)
|
|
86
|
+
|
|
87
|
+
### documents
|
|
88
|
+
|
|
89
|
+
- `id`: UUID
|
|
90
|
+
- `charge_id`: UUID (foreign key to charges)
|
|
91
|
+
- `total_amount`: double precision (nullable)
|
|
92
|
+
- `currency_code`: enum (nullable)
|
|
93
|
+
- `creditor_id`: UUID (nullable)
|
|
94
|
+
- `debtor_id`: UUID (nullable)
|
|
95
|
+
- `date`: DATE (nullable)
|
|
96
|
+
- `type`: enum (INVOICE, CREDIT_INVOICE, RECEIPT, etc.)
|
|
97
|
+
- `serial_number`: text (nullable)
|
|
98
|
+
|
|
99
|
+
## Testing Infrastructure
|
|
100
|
+
|
|
101
|
+
### Mock Factories
|
|
102
|
+
|
|
103
|
+
Test helpers provide factory functions for creating mock data:
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
import {
|
|
107
|
+
createMockTransaction,
|
|
108
|
+
createMockDocument,
|
|
109
|
+
createMockAggregatedTransaction,
|
|
110
|
+
createMockAggregatedDocument,
|
|
111
|
+
} from './__tests__/test-helpers.js';
|
|
112
|
+
|
|
113
|
+
// Create a transaction with defaults
|
|
114
|
+
const transaction = createMockTransaction();
|
|
115
|
+
|
|
116
|
+
// Create with overrides
|
|
117
|
+
const customTransaction = createMockTransaction({
|
|
118
|
+
amount: '250.00',
|
|
119
|
+
currency: 'USD',
|
|
120
|
+
});
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Helper Functions
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
import {
|
|
127
|
+
calculateExpectedConfidence,
|
|
128
|
+
roundConfidence,
|
|
129
|
+
isValidConfidenceScore,
|
|
130
|
+
daysDifference,
|
|
131
|
+
isWithinDays,
|
|
132
|
+
} from './__tests__/test-helpers.js';
|
|
133
|
+
|
|
134
|
+
// Calculate weighted confidence
|
|
135
|
+
const scores = { amount: 0.9, currency: 1.0, business: 0.5, date: 0.8 };
|
|
136
|
+
const confidence = calculateExpectedConfidence(scores); // 0.79
|
|
137
|
+
|
|
138
|
+
// Round to 2 decimal places
|
|
139
|
+
const rounded = roundConfidence(0.956789); // 0.96
|
|
140
|
+
|
|
141
|
+
// Validate score range
|
|
142
|
+
isValidConfidenceScore(0.95); // true
|
|
143
|
+
isValidConfidenceScore(1.5); // false
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Key Concepts
|
|
147
|
+
|
|
148
|
+
### Unmatched Charge
|
|
149
|
+
|
|
150
|
+
A charge is considered unmatched if it has:
|
|
151
|
+
|
|
152
|
+
- ≥1 transactions AND 0 accounting documents, OR
|
|
153
|
+
- 0 transactions AND ≥1 accounting documents
|
|
154
|
+
|
|
155
|
+
**Note**: PROFORMA, OTHER, and UNPROCESSED document types don't count toward matched/unmatched
|
|
156
|
+
status.
|
|
157
|
+
|
|
158
|
+
### Matched Charge
|
|
159
|
+
|
|
160
|
+
A charge is considered matched if it has:
|
|
161
|
+
|
|
162
|
+
- ≥1 transactions AND ≥1 accounting documents
|
|
163
|
+
|
|
164
|
+
### Accounting Documents
|
|
165
|
+
|
|
166
|
+
Documents with types: INVOICE, CREDIT_INVOICE, RECEIPT, INVOICE_RECEIPT
|
|
167
|
+
|
|
168
|
+
### Confidence Score
|
|
169
|
+
|
|
170
|
+
A value between 0.00 and 1.00 calculated using:
|
|
171
|
+
|
|
172
|
+
```
|
|
173
|
+
confidence = (amount × 0.4) + (currency × 0.2) + (business × 0.3) + (date × 0.1)
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Where each component score is between 0.0 and 1.0.
|
|
177
|
+
|
|
178
|
+
### Auto-Match Threshold
|
|
179
|
+
|
|
180
|
+
Charges are automatically matched only when:
|
|
181
|
+
|
|
182
|
+
- Exactly one match has confidence ≥ 0.95
|
|
183
|
+
- Multiple matches ≥ 0.95 result in the charge being skipped
|
|
184
|
+
|
|
185
|
+
## GraphQL API
|
|
186
|
+
|
|
187
|
+
### Query: findChargeMatches
|
|
188
|
+
|
|
189
|
+
Find potential matches for a single unmatched charge.
|
|
190
|
+
|
|
191
|
+
```graphql
|
|
192
|
+
query findChargeMatches($chargeId: UUID!) {
|
|
193
|
+
findChargeMatches(chargeId: $chargeId) {
|
|
194
|
+
matches {
|
|
195
|
+
chargeId
|
|
196
|
+
confidenceScore
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
**Returns**: Up to 5 matches, ordered by confidence score (highest first)
|
|
203
|
+
|
|
204
|
+
### Mutation: autoMatchCharges
|
|
205
|
+
|
|
206
|
+
Automatically match all unmatched charges above the confidence threshold.
|
|
207
|
+
|
|
208
|
+
```graphql
|
|
209
|
+
mutation autoMatchCharges {
|
|
210
|
+
autoMatchCharges {
|
|
211
|
+
totalMatches
|
|
212
|
+
mergedCharges {
|
|
213
|
+
chargeId
|
|
214
|
+
confidenceScore
|
|
215
|
+
}
|
|
216
|
+
skippedCharges
|
|
217
|
+
errors
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
**Returns**: Summary of matches made, skipped charges, and any errors
|
|
223
|
+
|
|
224
|
+
## Implementation Roadmap
|
|
225
|
+
|
|
226
|
+
### Step 1: Module Setup (✓ Complete)
|
|
227
|
+
|
|
228
|
+
- [x] Create module structure
|
|
229
|
+
- [x] Define TypeScript types
|
|
230
|
+
- [x] Create GraphQL schema
|
|
231
|
+
- [x] Set up test infrastructure
|
|
232
|
+
|
|
233
|
+
### Step 2: Core Logic (To Do)
|
|
234
|
+
|
|
235
|
+
- [ ] Implement charge classification
|
|
236
|
+
- [ ] Implement multi-item aggregation
|
|
237
|
+
- [ ] Implement confidence calculation helpers
|
|
238
|
+
- [ ] Implement candidate filtering
|
|
239
|
+
|
|
240
|
+
### Step 3: GraphQL Integration (To Do)
|
|
241
|
+
|
|
242
|
+
- [ ] Implement findChargeMatches resolver
|
|
243
|
+
- [ ] Implement autoMatchCharges resolver
|
|
244
|
+
- [ ] Implement providers for data access
|
|
245
|
+
- [ ] Add integration tests
|
|
246
|
+
|
|
247
|
+
### Step 4: UI Integration (To Do)
|
|
248
|
+
|
|
249
|
+
- [ ] Create ChargeMatchingModal component
|
|
250
|
+
- [ ] Create AutoMatchButton component
|
|
251
|
+
- [ ] Add to charge detail screens
|
|
252
|
+
- [ ] Add to charges list view
|
|
253
|
+
|
|
254
|
+
## Dependencies
|
|
255
|
+
|
|
256
|
+
This module depends on:
|
|
257
|
+
|
|
258
|
+
- `@modules/charges`: For charge data access and merge operations
|
|
259
|
+
- `@modules/transactions`: For transaction data access
|
|
260
|
+
- `@modules/documents`: For document data access
|
|
261
|
+
- `@modules/common`: For error handling and common utilities
|
|
262
|
+
- `@modules/financial-entities`: For business name resolution
|
|
263
|
+
|
|
264
|
+
## Running Tests
|
|
265
|
+
|
|
266
|
+
```bash
|
|
267
|
+
# Run all tests
|
|
268
|
+
yarn test
|
|
269
|
+
|
|
270
|
+
# Run specific test file
|
|
271
|
+
yarn test packages/server/src/modules/charges-matcher/__tests__/test-infrastructure.spec.ts
|
|
272
|
+
|
|
273
|
+
# Run tests in watch mode
|
|
274
|
+
yarn test --watch
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
## License
|
|
278
|
+
|
|
279
|
+
See the main project LICENSE file.
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import * as Types from "../../../__generated__/types.js";
|
|
2
|
+
import * as gm from "graphql-modules";
|
|
3
|
+
export namespace ChargesMatcherModule {
|
|
4
|
+
interface DefinedFields {
|
|
5
|
+
Query: 'findChargeMatches';
|
|
6
|
+
Mutation: 'autoMatchCharges';
|
|
7
|
+
ChargeMatchesResult: 'matches';
|
|
8
|
+
ChargeMatch: 'chargeId' | 'confidenceScore';
|
|
9
|
+
AutoMatchChargesResult: 'totalMatches' | 'mergedCharges' | 'skippedCharges' | 'errors';
|
|
10
|
+
MergedCharge: 'chargeId' | 'confidenceScore';
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export type Query = Pick<Types.Query, DefinedFields['Query']>;
|
|
14
|
+
export type ChargeMatchesResult = Pick<Types.ChargeMatchesResult, DefinedFields['ChargeMatchesResult']>;
|
|
15
|
+
export type UUID = Types.Uuid;
|
|
16
|
+
export type Mutation = Pick<Types.Mutation, DefinedFields['Mutation']>;
|
|
17
|
+
export type AutoMatchChargesResult = Pick<Types.AutoMatchChargesResult, DefinedFields['AutoMatchChargesResult']>;
|
|
18
|
+
export type ChargeMatch = Pick<Types.ChargeMatch, DefinedFields['ChargeMatch']>;
|
|
19
|
+
export type MergedCharge = Pick<Types.MergedCharge, DefinedFields['MergedCharge']>;
|
|
20
|
+
|
|
21
|
+
export type QueryResolvers = Pick<Types.QueryResolvers, DefinedFields['Query']>;
|
|
22
|
+
export type MutationResolvers = Pick<Types.MutationResolvers, DefinedFields['Mutation']>;
|
|
23
|
+
export type ChargeMatchesResultResolvers = Pick<Types.ChargeMatchesResultResolvers, DefinedFields['ChargeMatchesResult']>;
|
|
24
|
+
export type ChargeMatchResolvers = Pick<Types.ChargeMatchResolvers, DefinedFields['ChargeMatch']>;
|
|
25
|
+
export type AutoMatchChargesResultResolvers = Pick<Types.AutoMatchChargesResultResolvers, DefinedFields['AutoMatchChargesResult']>;
|
|
26
|
+
export type MergedChargeResolvers = Pick<Types.MergedChargeResolvers, DefinedFields['MergedCharge']>;
|
|
27
|
+
|
|
28
|
+
export interface Resolvers {
|
|
29
|
+
Query?: QueryResolvers;
|
|
30
|
+
Mutation?: MutationResolvers;
|
|
31
|
+
ChargeMatchesResult?: ChargeMatchesResultResolvers;
|
|
32
|
+
ChargeMatch?: ChargeMatchResolvers;
|
|
33
|
+
AutoMatchChargesResult?: AutoMatchChargesResultResolvers;
|
|
34
|
+
MergedCharge?: MergedChargeResolvers;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export interface MiddlewareMap {
|
|
38
|
+
'*'?: {
|
|
39
|
+
'*'?: gm.Middleware[];
|
|
40
|
+
};
|
|
41
|
+
Query?: {
|
|
42
|
+
'*'?: gm.Middleware[];
|
|
43
|
+
findChargeMatches?: gm.Middleware[];
|
|
44
|
+
};
|
|
45
|
+
Mutation?: {
|
|
46
|
+
'*'?: gm.Middleware[];
|
|
47
|
+
autoMatchCharges?: gm.Middleware[];
|
|
48
|
+
};
|
|
49
|
+
ChargeMatchesResult?: {
|
|
50
|
+
'*'?: gm.Middleware[];
|
|
51
|
+
matches?: gm.Middleware[];
|
|
52
|
+
};
|
|
53
|
+
ChargeMatch?: {
|
|
54
|
+
'*'?: gm.Middleware[];
|
|
55
|
+
chargeId?: gm.Middleware[];
|
|
56
|
+
confidenceScore?: gm.Middleware[];
|
|
57
|
+
};
|
|
58
|
+
AutoMatchChargesResult?: {
|
|
59
|
+
'*'?: gm.Middleware[];
|
|
60
|
+
totalMatches?: gm.Middleware[];
|
|
61
|
+
mergedCharges?: gm.Middleware[];
|
|
62
|
+
skippedCharges?: gm.Middleware[];
|
|
63
|
+
errors?: gm.Middleware[];
|
|
64
|
+
};
|
|
65
|
+
MergedCharge?: {
|
|
66
|
+
'*'?: gm.Middleware[];
|
|
67
|
+
chargeId?: gm.Middleware[];
|
|
68
|
+
confidenceScore?: gm.Middleware[];
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
}
|