@ksefnik/core 0.0.1

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 (238) hide show
  1. package/LICENSE +21 -0
  2. package/dist/bank/auto-detect.d.ts +3 -0
  3. package/dist/bank/auto-detect.d.ts.map +1 -0
  4. package/dist/bank/auto-detect.js +29 -0
  5. package/dist/bank/auto-detect.js.map +1 -0
  6. package/dist/bank/index.d.ts +10 -0
  7. package/dist/bank/index.d.ts.map +1 -0
  8. package/dist/bank/index.js +20 -0
  9. package/dist/bank/index.js.map +1 -0
  10. package/dist/bank/nip-extractor.d.ts +3 -0
  11. package/dist/bank/nip-extractor.d.ts.map +1 -0
  12. package/dist/bank/nip-extractor.js +36 -0
  13. package/dist/bank/nip-extractor.js.map +1 -0
  14. package/dist/bank/parsers/csv-base.d.ts +4 -0
  15. package/dist/bank/parsers/csv-base.d.ts.map +1 -0
  16. package/dist/bank/parsers/csv-base.js +48 -0
  17. package/dist/bank/parsers/csv-base.js.map +1 -0
  18. package/dist/bank/parsers/index.d.ts +8 -0
  19. package/dist/bank/parsers/index.d.ts.map +1 -0
  20. package/dist/bank/parsers/index.js +21 -0
  21. package/dist/bank/parsers/index.js.map +1 -0
  22. package/dist/bank/parsers/ing.parser.d.ts +7 -0
  23. package/dist/bank/parsers/ing.parser.d.ts.map +1 -0
  24. package/dist/bank/parsers/ing.parser.js +43 -0
  25. package/dist/bank/parsers/ing.parser.js.map +1 -0
  26. package/dist/bank/parsers/mbank.parser.d.ts +7 -0
  27. package/dist/bank/parsers/mbank.parser.d.ts.map +1 -0
  28. package/dist/bank/parsers/mbank.parser.js +39 -0
  29. package/dist/bank/parsers/mbank.parser.js.map +1 -0
  30. package/dist/bank/parsers/mt940.parser.d.ts +7 -0
  31. package/dist/bank/parsers/mt940.parser.d.ts.map +1 -0
  32. package/dist/bank/parsers/mt940.parser.js +57 -0
  33. package/dist/bank/parsers/mt940.parser.js.map +1 -0
  34. package/dist/bank/parsers/pko.parser.d.ts +7 -0
  35. package/dist/bank/parsers/pko.parser.d.ts.map +1 -0
  36. package/dist/bank/parsers/pko.parser.js +38 -0
  37. package/dist/bank/parsers/pko.parser.js.map +1 -0
  38. package/dist/bank/parsers/santander.parser.d.ts +7 -0
  39. package/dist/bank/parsers/santander.parser.d.ts.map +1 -0
  40. package/dist/bank/parsers/santander.parser.js +46 -0
  41. package/dist/bank/parsers/santander.parser.js.map +1 -0
  42. package/dist/index.d.ts +16 -0
  43. package/dist/index.d.ts.map +1 -0
  44. package/dist/index.js +18 -0
  45. package/dist/index.js.map +1 -0
  46. package/dist/ksef/cache.d.ts +12 -0
  47. package/dist/ksef/cache.d.ts.map +1 -0
  48. package/dist/ksef/cache.js +36 -0
  49. package/dist/ksef/cache.js.map +1 -0
  50. package/dist/ksef/index.d.ts +6 -0
  51. package/dist/ksef/index.d.ts.map +1 -0
  52. package/dist/ksef/index.js +5 -0
  53. package/dist/ksef/index.js.map +1 -0
  54. package/dist/ksef/ksef.adapter.d.ts +16 -0
  55. package/dist/ksef/ksef.adapter.d.ts.map +1 -0
  56. package/dist/ksef/ksef.adapter.js +81 -0
  57. package/dist/ksef/ksef.adapter.js.map +1 -0
  58. package/dist/ksef/retry.d.ts +7 -0
  59. package/dist/ksef/retry.d.ts.map +1 -0
  60. package/dist/ksef/retry.js +41 -0
  61. package/dist/ksef/retry.js.map +1 -0
  62. package/dist/ksef/session.d.ts +16 -0
  63. package/dist/ksef/session.d.ts.map +1 -0
  64. package/dist/ksef/session.js +39 -0
  65. package/dist/ksef/session.js.map +1 -0
  66. package/dist/ksef/types.d.ts +56 -0
  67. package/dist/ksef/types.d.ts.map +1 -0
  68. package/dist/ksef/types.js +2 -0
  69. package/dist/ksef/types.js.map +1 -0
  70. package/dist/ksefnik.d.ts +51 -0
  71. package/dist/ksefnik.d.ts.map +1 -0
  72. package/dist/ksefnik.js +104 -0
  73. package/dist/ksefnik.js.map +1 -0
  74. package/dist/matching/context.d.ts +5 -0
  75. package/dist/matching/context.d.ts.map +1 -0
  76. package/dist/matching/context.js +19 -0
  77. package/dist/matching/context.js.map +1 -0
  78. package/dist/matching/index.d.ts +6 -0
  79. package/dist/matching/index.d.ts.map +1 -0
  80. package/dist/matching/index.js +6 -0
  81. package/dist/matching/index.js.map +1 -0
  82. package/dist/matching/passes/exact.pass.d.ts +3 -0
  83. package/dist/matching/passes/exact.pass.d.ts.map +1 -0
  84. package/dist/matching/passes/exact.pass.js +34 -0
  85. package/dist/matching/passes/exact.pass.js.map +1 -0
  86. package/dist/matching/passes/fuzzy.pass.d.ts +3 -0
  87. package/dist/matching/passes/fuzzy.pass.d.ts.map +1 -0
  88. package/dist/matching/passes/fuzzy.pass.js +40 -0
  89. package/dist/matching/passes/fuzzy.pass.js.map +1 -0
  90. package/dist/matching/passes/index.d.ts +9 -0
  91. package/dist/matching/passes/index.d.ts.map +1 -0
  92. package/dist/matching/passes/index.js +21 -0
  93. package/dist/matching/passes/index.js.map +1 -0
  94. package/dist/matching/passes/invoice-ref.pass.d.ts +3 -0
  95. package/dist/matching/passes/invoice-ref.pass.d.ts.map +1 -0
  96. package/dist/matching/passes/invoice-ref.pass.js +32 -0
  97. package/dist/matching/passes/invoice-ref.pass.js.map +1 -0
  98. package/dist/matching/passes/ksef-ref.pass.d.ts +3 -0
  99. package/dist/matching/passes/ksef-ref.pass.d.ts.map +1 -0
  100. package/dist/matching/passes/ksef-ref.pass.js +25 -0
  101. package/dist/matching/passes/ksef-ref.pass.js.map +1 -0
  102. package/dist/matching/passes/partial.pass.d.ts +3 -0
  103. package/dist/matching/passes/partial.pass.d.ts.map +1 -0
  104. package/dist/matching/passes/partial.pass.js +55 -0
  105. package/dist/matching/passes/partial.pass.js.map +1 -0
  106. package/dist/matching/passes/proximity.pass.d.ts +3 -0
  107. package/dist/matching/passes/proximity.pass.d.ts.map +1 -0
  108. package/dist/matching/passes/proximity.pass.js +49 -0
  109. package/dist/matching/passes/proximity.pass.js.map +1 -0
  110. package/dist/matching/pipeline.d.ts +3 -0
  111. package/dist/matching/pipeline.d.ts.map +1 -0
  112. package/dist/matching/pipeline.js +76 -0
  113. package/dist/matching/pipeline.js.map +1 -0
  114. package/dist/matching/scoring.d.ts +5 -0
  115. package/dist/matching/scoring.d.ts.map +1 -0
  116. package/dist/matching/scoring.js +28 -0
  117. package/dist/matching/scoring.js.map +1 -0
  118. package/dist/plugins/index.d.ts +3 -0
  119. package/dist/plugins/index.d.ts.map +1 -0
  120. package/dist/plugins/index.js +3 -0
  121. package/dist/plugins/index.js.map +1 -0
  122. package/dist/plugins/loader.d.ts +3 -0
  123. package/dist/plugins/loader.d.ts.map +1 -0
  124. package/dist/plugins/loader.js +13 -0
  125. package/dist/plugins/loader.js.map +1 -0
  126. package/dist/plugins/registry.d.ts +8 -0
  127. package/dist/plugins/registry.d.ts.map +1 -0
  128. package/dist/plugins/registry.js +15 -0
  129. package/dist/plugins/registry.js.map +1 -0
  130. package/dist/storage/in-memory.storage.d.ts +13 -0
  131. package/dist/storage/in-memory.storage.d.ts.map +1 -0
  132. package/dist/storage/in-memory.storage.js +57 -0
  133. package/dist/storage/in-memory.storage.js.map +1 -0
  134. package/dist/storage/index.d.ts +3 -0
  135. package/dist/storage/index.d.ts.map +1 -0
  136. package/dist/storage/index.js +3 -0
  137. package/dist/storage/index.js.map +1 -0
  138. package/dist/storage/sqlite.storage.d.ts +13 -0
  139. package/dist/storage/sqlite.storage.d.ts.map +1 -0
  140. package/dist/storage/sqlite.storage.js +225 -0
  141. package/dist/storage/sqlite.storage.js.map +1 -0
  142. package/dist/validation/engine.d.ts +10 -0
  143. package/dist/validation/engine.d.ts.map +1 -0
  144. package/dist/validation/engine.js +19 -0
  145. package/dist/validation/engine.js.map +1 -0
  146. package/dist/validation/index.d.ts +6 -0
  147. package/dist/validation/index.d.ts.map +1 -0
  148. package/dist/validation/index.js +4 -0
  149. package/dist/validation/index.js.map +1 -0
  150. package/dist/validation/rule.d.ts +17 -0
  151. package/dist/validation/rule.d.ts.map +1 -0
  152. package/dist/validation/rule.js +2 -0
  153. package/dist/validation/rule.js.map +1 -0
  154. package/dist/validation/rules/amount-max.d.ts +3 -0
  155. package/dist/validation/rules/amount-max.d.ts.map +1 -0
  156. package/dist/validation/rules/amount-max.js +14 -0
  157. package/dist/validation/rules/amount-max.js.map +1 -0
  158. package/dist/validation/rules/amount-positive.d.ts +3 -0
  159. package/dist/validation/rules/amount-positive.d.ts.map +1 -0
  160. package/dist/validation/rules/amount-positive.js +13 -0
  161. package/dist/validation/rules/amount-positive.js.map +1 -0
  162. package/dist/validation/rules/buyer-nip-format.d.ts +3 -0
  163. package/dist/validation/rules/buyer-nip-format.d.ts.map +1 -0
  164. package/dist/validation/rules/buyer-nip-format.js +16 -0
  165. package/dist/validation/rules/buyer-nip-format.js.map +1 -0
  166. package/dist/validation/rules/currency-valid.d.ts +3 -0
  167. package/dist/validation/rules/currency-valid.d.ts.map +1 -0
  168. package/dist/validation/rules/currency-valid.js +13 -0
  169. package/dist/validation/rules/currency-valid.js.map +1 -0
  170. package/dist/validation/rules/date-not-future.d.ts +3 -0
  171. package/dist/validation/rules/date-not-future.d.ts.map +1 -0
  172. package/dist/validation/rules/date-not-future.js +18 -0
  173. package/dist/validation/rules/date-not-future.js.map +1 -0
  174. package/dist/validation/rules/date-order.d.ts +3 -0
  175. package/dist/validation/rules/date-order.d.ts.map +1 -0
  176. package/dist/validation/rules/date-order.js +15 -0
  177. package/dist/validation/rules/date-order.js.map +1 -0
  178. package/dist/validation/rules/date-range.d.ts +3 -0
  179. package/dist/validation/rules/date-range.d.ts.map +1 -0
  180. package/dist/validation/rules/date-range.js +18 -0
  181. package/dist/validation/rules/date-range.js.map +1 -0
  182. package/dist/validation/rules/date-valid.d.ts +3 -0
  183. package/dist/validation/rules/date-valid.d.ts.map +1 -0
  184. package/dist/validation/rules/date-valid.js +15 -0
  185. package/dist/validation/rules/date-valid.js.map +1 -0
  186. package/dist/validation/rules/description-length.d.ts +3 -0
  187. package/dist/validation/rules/description-length.d.ts.map +1 -0
  188. package/dist/validation/rules/description-length.js +19 -0
  189. package/dist/validation/rules/description-length.js.map +1 -0
  190. package/dist/validation/rules/duplicate-check.d.ts +3 -0
  191. package/dist/validation/rules/duplicate-check.d.ts.map +1 -0
  192. package/dist/validation/rules/duplicate-check.js +17 -0
  193. package/dist/validation/rules/duplicate-check.js.map +1 -0
  194. package/dist/validation/rules/index.d.ts +24 -0
  195. package/dist/validation/rules/index.d.ts.map +1 -0
  196. package/dist/validation/rules/index.js +44 -0
  197. package/dist/validation/rules/index.js.map +1 -0
  198. package/dist/validation/rules/invoice-number-format.d.ts +3 -0
  199. package/dist/validation/rules/invoice-number-format.d.ts.map +1 -0
  200. package/dist/validation/rules/invoice-number-format.js +14 -0
  201. package/dist/validation/rules/invoice-number-format.js.map +1 -0
  202. package/dist/validation/rules/ksef-reference-format.d.ts +3 -0
  203. package/dist/validation/rules/ksef-reference-format.d.ts.map +1 -0
  204. package/dist/validation/rules/ksef-reference-format.js +18 -0
  205. package/dist/validation/rules/ksef-reference-format.js.map +1 -0
  206. package/dist/validation/rules/line-items-sum.d.ts +3 -0
  207. package/dist/validation/rules/line-items-sum.d.ts.map +1 -0
  208. package/dist/validation/rules/line-items-sum.js +17 -0
  209. package/dist/validation/rules/line-items-sum.js.map +1 -0
  210. package/dist/validation/rules/nip-format.d.ts +3 -0
  211. package/dist/validation/rules/nip-format.d.ts.map +1 -0
  212. package/dist/validation/rules/nip-format.js +14 -0
  213. package/dist/validation/rules/nip-format.js.map +1 -0
  214. package/dist/validation/rules/nip-not-zeros.d.ts +3 -0
  215. package/dist/validation/rules/nip-not-zeros.d.ts.map +1 -0
  216. package/dist/validation/rules/nip-not-zeros.js +12 -0
  217. package/dist/validation/rules/nip-not-zeros.js.map +1 -0
  218. package/dist/validation/rules/quantity-positive.d.ts +3 -0
  219. package/dist/validation/rules/quantity-positive.d.ts.map +1 -0
  220. package/dist/validation/rules/quantity-positive.js +21 -0
  221. package/dist/validation/rules/quantity-positive.js.map +1 -0
  222. package/dist/validation/rules/required-fields.d.ts +3 -0
  223. package/dist/validation/rules/required-fields.d.ts.map +1 -0
  224. package/dist/validation/rules/required-fields.js +18 -0
  225. package/dist/validation/rules/required-fields.js.map +1 -0
  226. package/dist/validation/rules/seller-buyer-different.d.ts +3 -0
  227. package/dist/validation/rules/seller-buyer-different.d.ts.map +1 -0
  228. package/dist/validation/rules/seller-buyer-different.js +15 -0
  229. package/dist/validation/rules/seller-buyer-different.js.map +1 -0
  230. package/dist/validation/rules/vat-calculation.d.ts +3 -0
  231. package/dist/validation/rules/vat-calculation.d.ts.map +1 -0
  232. package/dist/validation/rules/vat-calculation.js +19 -0
  233. package/dist/validation/rules/vat-calculation.js.map +1 -0
  234. package/dist/validation/rules/vat-rate-valid.d.ts +3 -0
  235. package/dist/validation/rules/vat-rate-valid.d.ts.map +1 -0
  236. package/dist/validation/rules/vat-rate-valid.js +22 -0
  237. package/dist/validation/rules/vat-rate-valid.js.map +1 -0
  238. package/package.json +44 -0
@@ -0,0 +1,3 @@
1
+ import type { ReconciliationPass } from '@ksefnik/shared';
2
+ export declare const exactPass: ReconciliationPass;
3
+ //# sourceMappingURL=exact.pass.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exact.pass.d.ts","sourceRoot":"","sources":["../../../src/matching/passes/exact.pass.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAgC,MAAM,iBAAiB,CAAA;AAGvF,eAAO,MAAM,SAAS,EAAE,kBAkCvB,CAAA"}
@@ -0,0 +1,34 @@
1
+ import { extractFirstNIP } from '../../bank/nip-extractor.js';
2
+ export const exactPass = {
3
+ name: 'exact',
4
+ order: 200,
5
+ async run(context) {
6
+ const results = [];
7
+ const usedTxIds = new Set();
8
+ for (const invoice of context.invoices) {
9
+ for (const tx of context.transactions) {
10
+ if (usedTxIds.has(tx.id))
11
+ continue;
12
+ const txAmount = Math.abs(tx.amount);
13
+ if (txAmount !== invoice.grossAmount)
14
+ continue;
15
+ const nip = tx.senderNIP ?? tx.recipientNIP ?? extractFirstNIP(tx.description);
16
+ if (!nip || nip !== invoice.sellerNIP)
17
+ continue;
18
+ results.push({
19
+ invoiceId: invoice.id,
20
+ transactionId: tx.id,
21
+ confidence: 95,
22
+ reasons: [
23
+ `Exact amount match: ${txAmount} grosze`,
24
+ `NIP match: ${nip}`,
25
+ ],
26
+ });
27
+ usedTxIds.add(tx.id);
28
+ break;
29
+ }
30
+ }
31
+ return results;
32
+ },
33
+ };
34
+ //# sourceMappingURL=exact.pass.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exact.pass.js","sourceRoot":"","sources":["../../../src/matching/passes/exact.pass.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAA;AAE7D,MAAM,CAAC,MAAM,SAAS,GAAuB;IAC3C,IAAI,EAAE,OAAO;IACb,KAAK,EAAE,GAAG;IAEV,KAAK,CAAC,GAAG,CAAC,OAAwB;QAChC,MAAM,OAAO,GAAkB,EAAE,CAAA;QACjC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAA;QAEnC,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACvC,KAAK,MAAM,EAAE,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;gBACtC,IAAI,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;oBAAE,SAAQ;gBAElC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,CAAA;gBACpC,IAAI,QAAQ,KAAK,OAAO,CAAC,WAAW;oBAAE,SAAQ;gBAE9C,MAAM,GAAG,GAAG,EAAE,CAAC,SAAS,IAAI,EAAE,CAAC,YAAY,IAAI,eAAe,CAAC,EAAE,CAAC,WAAW,CAAC,CAAA;gBAC9E,IAAI,CAAC,GAAG,IAAI,GAAG,KAAK,OAAO,CAAC,SAAS;oBAAE,SAAQ;gBAE/C,OAAO,CAAC,IAAI,CAAC;oBACX,SAAS,EAAE,OAAO,CAAC,EAAE;oBACrB,aAAa,EAAE,EAAE,CAAC,EAAE;oBACpB,UAAU,EAAE,EAAE;oBACd,OAAO,EAAE;wBACP,uBAAuB,QAAQ,SAAS;wBACxC,cAAc,GAAG,EAAE;qBACpB;iBACF,CAAC,CAAA;gBACF,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;gBACpB,MAAK;YACP,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAA;IAChB,CAAC;CACF,CAAA"}
@@ -0,0 +1,3 @@
1
+ import type { ReconciliationPass } from '@ksefnik/shared';
2
+ export declare const fuzzyPass: ReconciliationPass;
3
+ //# sourceMappingURL=fuzzy.pass.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fuzzy.pass.d.ts","sourceRoot":"","sources":["../../../src/matching/passes/fuzzy.pass.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAgC,MAAM,iBAAiB,CAAA;AAKvF,eAAO,MAAM,SAAS,EAAE,kBAuCvB,CAAA"}
@@ -0,0 +1,40 @@
1
+ import { ratio } from 'fuzzball';
2
+ const FUZZY_THRESHOLD = 80;
3
+ export const fuzzyPass = {
4
+ name: 'fuzzy',
5
+ order: 400,
6
+ async run(context) {
7
+ const results = [];
8
+ const usedTxIds = new Set();
9
+ for (const invoice of context.invoices) {
10
+ if (!invoice.sellerName)
11
+ continue;
12
+ for (const tx of context.transactions) {
13
+ if (usedTxIds.has(tx.id))
14
+ continue;
15
+ // Amount must match exactly
16
+ if (Math.abs(tx.amount) !== invoice.grossAmount)
17
+ continue;
18
+ const txName = tx.senderName ?? tx.recipientName;
19
+ if (!txName)
20
+ continue;
21
+ const score = ratio(invoice.sellerName, txName);
22
+ if (score >= FUZZY_THRESHOLD) {
23
+ results.push({
24
+ invoiceId: invoice.id,
25
+ transactionId: tx.id,
26
+ confidence: 80,
27
+ reasons: [
28
+ `Fuzzy name match: "${invoice.sellerName}" ~ "${txName}" (score: ${score})`,
29
+ `Exact amount match: ${Math.abs(tx.amount)} grosze`,
30
+ ],
31
+ });
32
+ usedTxIds.add(tx.id);
33
+ break;
34
+ }
35
+ }
36
+ }
37
+ return results;
38
+ },
39
+ };
40
+ //# sourceMappingURL=fuzzy.pass.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fuzzy.pass.js","sourceRoot":"","sources":["../../../src/matching/passes/fuzzy.pass.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAA;AAEhC,MAAM,eAAe,GAAG,EAAE,CAAA;AAE1B,MAAM,CAAC,MAAM,SAAS,GAAuB;IAC3C,IAAI,EAAE,OAAO;IACb,KAAK,EAAE,GAAG;IAEV,KAAK,CAAC,GAAG,CAAC,OAAwB;QAChC,MAAM,OAAO,GAAkB,EAAE,CAAA;QACjC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAA;QAEnC,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACvC,IAAI,CAAC,OAAO,CAAC,UAAU;gBAAE,SAAQ;YAEjC,KAAK,MAAM,EAAE,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;gBACtC,IAAI,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;oBAAE,SAAQ;gBAElC,4BAA4B;gBAC5B,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,OAAO,CAAC,WAAW;oBAAE,SAAQ;gBAEzD,MAAM,MAAM,GAAG,EAAE,CAAC,UAAU,IAAI,EAAE,CAAC,aAAa,CAAA;gBAChD,IAAI,CAAC,MAAM;oBAAE,SAAQ;gBAErB,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,MAAM,CAAC,CAAA;gBAC/C,IAAI,KAAK,IAAI,eAAe,EAAE,CAAC;oBAC7B,OAAO,CAAC,IAAI,CAAC;wBACX,SAAS,EAAE,OAAO,CAAC,EAAE;wBACrB,aAAa,EAAE,EAAE,CAAC,EAAE;wBACpB,UAAU,EAAE,EAAE;wBACd,OAAO,EAAE;4BACP,sBAAsB,OAAO,CAAC,UAAU,QAAQ,MAAM,aAAa,KAAK,GAAG;4BAC3E,uBAAuB,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,SAAS;yBACpD;qBACF,CAAC,CAAA;oBACF,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;oBACpB,MAAK;gBACP,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAA;IAChB,CAAC;CACF,CAAA"}
@@ -0,0 +1,9 @@
1
+ import type { ReconciliationPass } from '@ksefnik/shared';
2
+ export { ksefRefPass } from './ksef-ref.pass.js';
3
+ export { exactPass } from './exact.pass.js';
4
+ export { invoiceRefPass } from './invoice-ref.pass.js';
5
+ export { fuzzyPass } from './fuzzy.pass.js';
6
+ export { partialPass } from './partial.pass.js';
7
+ export { proximityPass } from './proximity.pass.js';
8
+ export declare const defaultPasses: ReconciliationPass[];
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/matching/passes/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAQzD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAEnD,eAAO,MAAM,aAAa,EAAE,kBAAkB,EAOX,CAAA"}
@@ -0,0 +1,21 @@
1
+ import { ksefRefPass } from './ksef-ref.pass.js';
2
+ import { exactPass } from './exact.pass.js';
3
+ import { invoiceRefPass } from './invoice-ref.pass.js';
4
+ import { fuzzyPass } from './fuzzy.pass.js';
5
+ import { partialPass } from './partial.pass.js';
6
+ import { proximityPass } from './proximity.pass.js';
7
+ export { ksefRefPass } from './ksef-ref.pass.js';
8
+ export { exactPass } from './exact.pass.js';
9
+ export { invoiceRefPass } from './invoice-ref.pass.js';
10
+ export { fuzzyPass } from './fuzzy.pass.js';
11
+ export { partialPass } from './partial.pass.js';
12
+ export { proximityPass } from './proximity.pass.js';
13
+ export const defaultPasses = [
14
+ ksefRefPass,
15
+ exactPass,
16
+ invoiceRefPass,
17
+ fuzzyPass,
18
+ partialPass,
19
+ proximityPass,
20
+ ].sort((a, b) => a.order - b.order);
21
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/matching/passes/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAEnD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAEnD,MAAM,CAAC,MAAM,aAAa,GAAyB;IACjD,WAAW;IACX,SAAS;IACT,cAAc;IACd,SAAS;IACT,WAAW;IACX,aAAa;CACd,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAA"}
@@ -0,0 +1,3 @@
1
+ import type { ReconciliationPass } from '@ksefnik/shared';
2
+ export declare const invoiceRefPass: ReconciliationPass;
3
+ //# sourceMappingURL=invoice-ref.pass.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invoice-ref.pass.d.ts","sourceRoot":"","sources":["../../../src/matching/passes/invoice-ref.pass.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAgC,MAAM,iBAAiB,CAAA;AAEvF,eAAO,MAAM,cAAc,EAAE,kBAkC5B,CAAA"}
@@ -0,0 +1,32 @@
1
+ export const invoiceRefPass = {
2
+ name: 'invoice-ref',
3
+ order: 300,
4
+ async run(context) {
5
+ const results = [];
6
+ const usedTxIds = new Set();
7
+ for (const invoice of context.invoices) {
8
+ const ref = invoice.invoiceNumber.toLowerCase();
9
+ for (const tx of context.transactions) {
10
+ if (usedTxIds.has(tx.id))
11
+ continue;
12
+ if (tx.description.toLowerCase().includes(ref)) {
13
+ const amountMatches = Math.abs(tx.amount) === invoice.grossAmount;
14
+ const confidence = amountMatches ? 90 : 75;
15
+ const reasons = [`Invoice number "${invoice.invoiceNumber}" found in transaction description`];
16
+ if (amountMatches)
17
+ reasons.push('Amount also matches');
18
+ results.push({
19
+ invoiceId: invoice.id,
20
+ transactionId: tx.id,
21
+ confidence,
22
+ reasons,
23
+ });
24
+ usedTxIds.add(tx.id);
25
+ break;
26
+ }
27
+ }
28
+ }
29
+ return results;
30
+ },
31
+ };
32
+ //# sourceMappingURL=invoice-ref.pass.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invoice-ref.pass.js","sourceRoot":"","sources":["../../../src/matching/passes/invoice-ref.pass.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,cAAc,GAAuB;IAChD,IAAI,EAAE,aAAa;IACnB,KAAK,EAAE,GAAG;IAEV,KAAK,CAAC,GAAG,CAAC,OAAwB;QAChC,MAAM,OAAO,GAAkB,EAAE,CAAA;QACjC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAA;QAEnC,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACvC,MAAM,GAAG,GAAG,OAAO,CAAC,aAAa,CAAC,WAAW,EAAE,CAAA;YAE/C,KAAK,MAAM,EAAE,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;gBACtC,IAAI,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;oBAAE,SAAQ;gBAElC,IAAI,EAAE,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC/C,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,OAAO,CAAC,WAAW,CAAA;oBACjE,MAAM,UAAU,GAAG,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;oBAC1C,MAAM,OAAO,GAAG,CAAC,mBAAmB,OAAO,CAAC,aAAa,oCAAoC,CAAC,CAAA;oBAC9F,IAAI,aAAa;wBAAE,OAAO,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAA;oBAEtD,OAAO,CAAC,IAAI,CAAC;wBACX,SAAS,EAAE,OAAO,CAAC,EAAE;wBACrB,aAAa,EAAE,EAAE,CAAC,EAAE;wBACpB,UAAU;wBACV,OAAO;qBACR,CAAC,CAAA;oBACF,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;oBACpB,MAAK;gBACP,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAA;IAChB,CAAC;CACF,CAAA"}
@@ -0,0 +1,3 @@
1
+ import type { ReconciliationPass } from '@ksefnik/shared';
2
+ export declare const ksefRefPass: ReconciliationPass;
3
+ //# sourceMappingURL=ksef-ref.pass.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ksef-ref.pass.d.ts","sourceRoot":"","sources":["../../../src/matching/passes/ksef-ref.pass.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAgC,MAAM,iBAAiB,CAAA;AAEvF,eAAO,MAAM,WAAW,EAAE,kBA2BzB,CAAA"}
@@ -0,0 +1,25 @@
1
+ export const ksefRefPass = {
2
+ name: 'ksef-ref',
3
+ order: 100,
4
+ async run(context) {
5
+ const results = [];
6
+ for (const invoice of context.invoices) {
7
+ if (!invoice.ksefReference)
8
+ continue;
9
+ const ref = invoice.ksefReference.toLowerCase();
10
+ for (const tx of context.transactions) {
11
+ if (tx.description.toLowerCase().includes(ref)) {
12
+ results.push({
13
+ invoiceId: invoice.id,
14
+ transactionId: tx.id,
15
+ confidence: 99,
16
+ reasons: [`KSeF reference "${invoice.ksefReference}" found in transaction description`],
17
+ });
18
+ break;
19
+ }
20
+ }
21
+ }
22
+ return results;
23
+ },
24
+ };
25
+ //# sourceMappingURL=ksef-ref.pass.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ksef-ref.pass.js","sourceRoot":"","sources":["../../../src/matching/passes/ksef-ref.pass.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,WAAW,GAAuB;IAC7C,IAAI,EAAE,UAAU;IAChB,KAAK,EAAE,GAAG;IAEV,KAAK,CAAC,GAAG,CAAC,OAAwB;QAChC,MAAM,OAAO,GAAkB,EAAE,CAAA;QAEjC,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACvC,IAAI,CAAC,OAAO,CAAC,aAAa;gBAAE,SAAQ;YAEpC,MAAM,GAAG,GAAG,OAAO,CAAC,aAAa,CAAC,WAAW,EAAE,CAAA;YAE/C,KAAK,MAAM,EAAE,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;gBACtC,IAAI,EAAE,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC/C,OAAO,CAAC,IAAI,CAAC;wBACX,SAAS,EAAE,OAAO,CAAC,EAAE;wBACrB,aAAa,EAAE,EAAE,CAAC,EAAE;wBACpB,UAAU,EAAE,EAAE;wBACd,OAAO,EAAE,CAAC,mBAAmB,OAAO,CAAC,aAAa,oCAAoC,CAAC;qBACxF,CAAC,CAAA;oBACF,MAAK;gBACP,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAA;IAChB,CAAC;CACF,CAAA"}
@@ -0,0 +1,3 @@
1
+ import type { ReconciliationPass } from '@ksefnik/shared';
2
+ export declare const partialPass: ReconciliationPass;
3
+ //# sourceMappingURL=partial.pass.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"partial.pass.d.ts","sourceRoot":"","sources":["../../../src/matching/passes/partial.pass.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAgC,MAAM,iBAAiB,CAAA;AAEvF,eAAO,MAAM,WAAW,EAAE,kBA0DzB,CAAA"}
@@ -0,0 +1,55 @@
1
+ export const partialPass = {
2
+ name: 'partial',
3
+ order: 450,
4
+ async run(context) {
5
+ const results = [];
6
+ // Group transactions by NIP
7
+ const txByNip = new Map();
8
+ for (const tx of context.transactions) {
9
+ const nip = tx.senderNIP ?? tx.recipientNIP;
10
+ if (!nip)
11
+ continue;
12
+ const group = txByNip.get(nip) ?? [];
13
+ group.push(tx);
14
+ txByNip.set(nip, group);
15
+ }
16
+ for (const invoice of context.invoices) {
17
+ const txs = txByNip.get(invoice.sellerNIP);
18
+ if (!txs || txs.length < 2)
19
+ continue;
20
+ // Greedy: sort by amount descending, try to sum up to grossAmount
21
+ const sorted = [...txs].sort((a, b) => Math.abs(b.amount) - Math.abs(a.amount));
22
+ const selected = [];
23
+ let remaining = invoice.grossAmount;
24
+ for (const tx of sorted) {
25
+ const absAmount = Math.abs(tx.amount);
26
+ if (absAmount <= remaining) {
27
+ selected.push(tx.id);
28
+ remaining -= absAmount;
29
+ }
30
+ if (remaining === 0)
31
+ break;
32
+ }
33
+ if (selected.length < 2)
34
+ continue;
35
+ const ratio = (invoice.grossAmount - remaining) / invoice.grossAmount;
36
+ if (ratio < 0.95)
37
+ continue;
38
+ const isExact = remaining === 0;
39
+ const confidence = isExact ? 70 : 50;
40
+ results.push({
41
+ invoiceId: invoice.id,
42
+ transactionId: selected[0],
43
+ transactionIds: selected,
44
+ confidence,
45
+ reasons: [
46
+ `Partial match: ${selected.length} transactions from NIP ${invoice.sellerNIP}`,
47
+ `Sum covers ${Math.round(ratio * 100)}% of invoice amount`,
48
+ isExact ? 'Exact sum match' : 'Approximate sum match',
49
+ ],
50
+ });
51
+ }
52
+ return results;
53
+ },
54
+ };
55
+ //# sourceMappingURL=partial.pass.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"partial.pass.js","sourceRoot":"","sources":["../../../src/matching/passes/partial.pass.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,WAAW,GAAuB;IAC7C,IAAI,EAAE,SAAS;IACf,KAAK,EAAE,GAAG;IAEV,KAAK,CAAC,GAAG,CAAC,OAAwB;QAChC,MAAM,OAAO,GAAkB,EAAE,CAAA;QAEjC,4BAA4B;QAC5B,MAAM,OAAO,GAAG,IAAI,GAAG,EAAuC,CAAA;QAC9D,KAAK,MAAM,EAAE,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;YACtC,MAAM,GAAG,GAAG,EAAE,CAAC,SAAS,IAAI,EAAE,CAAC,YAAY,CAAA;YAC3C,IAAI,CAAC,GAAG;gBAAE,SAAQ;YAClB,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAA;YACpC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;YACd,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;QACzB,CAAC;QAED,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACvC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;YAC1C,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC;gBAAE,SAAQ;YAEpC,kEAAkE;YAClE,MAAM,MAAM,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAA;YAC/E,MAAM,QAAQ,GAAa,EAAE,CAAA;YAC7B,IAAI,SAAS,GAAG,OAAO,CAAC,WAAW,CAAA;YAEnC,KAAK,MAAM,EAAE,IAAI,MAAM,EAAE,CAAC;gBACxB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,CAAA;gBACrC,IAAI,SAAS,IAAI,SAAS,EAAE,CAAC;oBAC3B,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;oBACpB,SAAS,IAAI,SAAS,CAAA;gBACxB,CAAC;gBACD,IAAI,SAAS,KAAK,CAAC;oBAAE,MAAK;YAC5B,CAAC;YAED,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;gBAAE,SAAQ;YAEjC,MAAM,KAAK,GAAG,CAAC,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC,WAAW,CAAA;YACrE,IAAI,KAAK,GAAG,IAAI;gBAAE,SAAQ;YAE1B,MAAM,OAAO,GAAG,SAAS,KAAK,CAAC,CAAA;YAC/B,MAAM,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;YAEpC,OAAO,CAAC,IAAI,CAAC;gBACX,SAAS,EAAE,OAAO,CAAC,EAAE;gBACrB,aAAa,EAAE,QAAQ,CAAC,CAAC,CAAE;gBAC3B,cAAc,EAAE,QAAQ;gBACxB,UAAU;gBACV,OAAO,EAAE;oBACP,kBAAkB,QAAQ,CAAC,MAAM,0BAA0B,OAAO,CAAC,SAAS,EAAE;oBAC9E,cAAc,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC,qBAAqB;oBAC1D,OAAO,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,uBAAuB;iBACtD;aACF,CAAC,CAAA;QACJ,CAAC;QAED,OAAO,OAAO,CAAA;IAChB,CAAC;CACF,CAAA"}
@@ -0,0 +1,3 @@
1
+ import type { ReconciliationPass } from '@ksefnik/shared';
2
+ export declare const proximityPass: ReconciliationPass;
3
+ //# sourceMappingURL=proximity.pass.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proximity.pass.d.ts","sourceRoot":"","sources":["../../../src/matching/passes/proximity.pass.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAgC,MAAM,iBAAiB,CAAA;AAGvF,eAAO,MAAM,aAAa,EAAE,kBAuD3B,CAAA"}
@@ -0,0 +1,49 @@
1
+ import { clampConfidence } from '../scoring.js';
2
+ export const proximityPass = {
3
+ name: 'proximity',
4
+ order: 500,
5
+ async run(context) {
6
+ const results = [];
7
+ const usedTxIds = new Set();
8
+ for (const invoice of context.invoices) {
9
+ const target = invoice.grossAmount;
10
+ const minAmount = Math.floor(target * 0.95);
11
+ const maxAmount = Math.ceil(target * 1.05);
12
+ const referenceDate = invoice.dueDate ?? invoice.issueDate;
13
+ let bestMatch = null;
14
+ for (const tx of context.transactions) {
15
+ if (usedTxIds.has(tx.id))
16
+ continue;
17
+ const absAmount = Math.abs(tx.amount);
18
+ if (absAmount < minAmount || absAmount > maxAmount)
19
+ continue;
20
+ const daysDiff = Math.abs((new Date(tx.date).getTime() - new Date(referenceDate).getTime()) / (1000 * 60 * 60 * 24));
21
+ if (daysDiff > 30)
22
+ continue;
23
+ const proximityFactor = 1 - daysDiff / 30;
24
+ const confidence = clampConfidence(50 + 20 * proximityFactor);
25
+ if (!bestMatch || confidence > bestMatch.confidence) {
26
+ bestMatch = {
27
+ txId: tx.id,
28
+ confidence,
29
+ reasons: [
30
+ `Amount within 5%: invoice ${target}, transaction ${absAmount}`,
31
+ `Date proximity: ${Math.round(daysDiff)} days apart`,
32
+ ],
33
+ };
34
+ }
35
+ }
36
+ if (bestMatch) {
37
+ results.push({
38
+ invoiceId: invoice.id,
39
+ transactionId: bestMatch.txId,
40
+ confidence: bestMatch.confidence,
41
+ reasons: bestMatch.reasons,
42
+ });
43
+ usedTxIds.add(bestMatch.txId);
44
+ }
45
+ }
46
+ return results;
47
+ },
48
+ };
49
+ //# sourceMappingURL=proximity.pass.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proximity.pass.js","sourceRoot":"","sources":["../../../src/matching/passes/proximity.pass.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAE/C,MAAM,CAAC,MAAM,aAAa,GAAuB;IAC/C,IAAI,EAAE,WAAW;IACjB,KAAK,EAAE,GAAG;IAEV,KAAK,CAAC,GAAG,CAAC,OAAwB;QAChC,MAAM,OAAO,GAAkB,EAAE,CAAA;QACjC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAA;QAEnC,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACvC,MAAM,MAAM,GAAG,OAAO,CAAC,WAAW,CAAA;YAClC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;YAC3C,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;YAC1C,MAAM,aAAa,GAAG,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,SAAS,CAAA;YAE1D,IAAI,SAAS,GAAmE,IAAI,CAAA;YAEpF,KAAK,MAAM,EAAE,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;gBACtC,IAAI,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;oBAAE,SAAQ;gBAElC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,CAAA;gBACrC,IAAI,SAAS,GAAG,SAAS,IAAI,SAAS,GAAG,SAAS;oBAAE,SAAQ;gBAE5D,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CACvB,CAAC,IAAI,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,IAAI,CAAC,aAAa,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAC1F,CAAA;gBACD,IAAI,QAAQ,GAAG,EAAE;oBAAE,SAAQ;gBAE3B,MAAM,eAAe,GAAG,CAAC,GAAG,QAAQ,GAAG,EAAE,CAAA;gBACzC,MAAM,UAAU,GAAG,eAAe,CAAC,EAAE,GAAG,EAAE,GAAG,eAAe,CAAC,CAAA;gBAE7D,IAAI,CAAC,SAAS,IAAI,UAAU,GAAG,SAAS,CAAC,UAAU,EAAE,CAAC;oBACpD,SAAS,GAAG;wBACV,IAAI,EAAE,EAAE,CAAC,EAAE;wBACX,UAAU;wBACV,OAAO,EAAE;4BACP,6BAA6B,MAAM,iBAAiB,SAAS,EAAE;4BAC/D,mBAAmB,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,aAAa;yBACrD;qBACF,CAAA;gBACH,CAAC;YACH,CAAC;YAED,IAAI,SAAS,EAAE,CAAC;gBACd,OAAO,CAAC,IAAI,CAAC;oBACX,SAAS,EAAE,OAAO,CAAC,EAAE;oBACrB,aAAa,EAAE,SAAS,CAAC,IAAI;oBAC7B,UAAU,EAAE,SAAS,CAAC,UAAU;oBAChC,OAAO,EAAE,SAAS,CAAC,OAAO;iBAC3B,CAAC,CAAA;gBACF,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;YAC/B,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAA;IAChB,CAAC;CACF,CAAA"}
@@ -0,0 +1,3 @@
1
+ import type { Invoice, BankTransaction, ReconciliationReport, ReconciliationPass } from '@ksefnik/shared';
2
+ export declare function runPipeline(invoices: Invoice[], transactions: BankTransaction[], passes: ReconciliationPass[]): Promise<ReconciliationReport>;
3
+ //# sourceMappingURL=pipeline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../src/matching/pipeline.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,OAAO,EACP,eAAe,EAEf,oBAAoB,EACpB,kBAAkB,EAGnB,MAAM,iBAAiB,CAAA;AAGxB,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,OAAO,EAAE,EACnB,YAAY,EAAE,eAAe,EAAE,EAC/B,MAAM,EAAE,kBAAkB,EAAE,GAC3B,OAAO,CAAC,oBAAoB,CAAC,CAoE/B"}
@@ -0,0 +1,76 @@
1
+ import { getUnmatchedInvoices, getUnmatchedTransactions } from './context.js';
2
+ export async function runPipeline(invoices, transactions, passes) {
3
+ const startTime = Date.now();
4
+ const sortedPasses = [...passes].sort((a, b) => a.order - b.order);
5
+ const allMatches = [];
6
+ const passBreakdown = {};
7
+ for (const pass of sortedPasses) {
8
+ const unmatchedInvoices = getUnmatchedInvoices(invoices, allMatches);
9
+ const unmatchedTransactions = getUnmatchedTransactions(transactions, allMatches);
10
+ if (unmatchedInvoices.length === 0 || unmatchedTransactions.length === 0)
11
+ break;
12
+ const context = {
13
+ invoices: unmatchedInvoices,
14
+ transactions: unmatchedTransactions,
15
+ alreadyMatched: allMatches,
16
+ };
17
+ const results = await pass.run(context);
18
+ const newMatches = resultsToMatches(results, pass.name);
19
+ // Deduplicate: don't match already-matched invoices or transactions
20
+ const matchedInvoiceIds = new Set(allMatches.map((m) => m.invoiceId));
21
+ const matchedTxIds = new Set();
22
+ for (const m of allMatches) {
23
+ matchedTxIds.add(m.transactionId);
24
+ if (m.transactionIds)
25
+ m.transactionIds.forEach((id) => matchedTxIds.add(id));
26
+ }
27
+ for (const match of newMatches) {
28
+ if (matchedInvoiceIds.has(match.invoiceId))
29
+ continue;
30
+ if (matchedTxIds.has(match.transactionId))
31
+ continue;
32
+ allMatches.push(match);
33
+ matchedInvoiceIds.add(match.invoiceId);
34
+ matchedTxIds.add(match.transactionId);
35
+ if (match.transactionIds)
36
+ match.transactionIds.forEach((id) => matchedTxIds.add(id));
37
+ passBreakdown[pass.name] = (passBreakdown[pass.name] ?? 0) + 1;
38
+ }
39
+ }
40
+ const unmatchedInvoices = getUnmatchedInvoices(invoices, allMatches);
41
+ const unmatchedTxs = getUnmatchedTransactions(transactions, allMatches);
42
+ const avgConfidence = allMatches.length > 0
43
+ ? allMatches.reduce((sum, m) => sum + m.confidence, 0) / allMatches.length
44
+ : 0;
45
+ return {
46
+ id: crypto.randomUUID(),
47
+ matched: allMatches,
48
+ unmatchedInvoices,
49
+ unmatchedTransactions: unmatchedTxs,
50
+ summary: {
51
+ totalInvoices: invoices.length,
52
+ totalTransactions: transactions.length,
53
+ matchedCount: allMatches.length,
54
+ unmatchedInvoiceCount: unmatchedInvoices.length,
55
+ unmatchedTransactionCount: unmatchedTxs.length,
56
+ averageConfidence: Math.round(avgConfidence * 100) / 100,
57
+ passBreakdown,
58
+ },
59
+ runAt: new Date().toISOString(),
60
+ durationMs: Date.now() - startTime,
61
+ };
62
+ }
63
+ function resultsToMatches(results, passName) {
64
+ return results.map((r) => ({
65
+ id: crypto.randomUUID(),
66
+ invoiceId: r.invoiceId,
67
+ transactionId: r.transactionId,
68
+ transactionIds: r.transactionIds,
69
+ confidence: r.confidence,
70
+ passName,
71
+ reasons: r.reasons,
72
+ confirmed: false,
73
+ createdAt: new Date().toISOString(),
74
+ }));
75
+ }
76
+ //# sourceMappingURL=pipeline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../../src/matching/pipeline.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export declare function clampConfidence(score: number): number;
2
+ export declare function dateProximityBonus(invoiceDate: string, transactionDate: string, maxDays?: number): number;
3
+ export declare function amountMatchBonus(invoiceAmount: number, transactionAmount: number): number;
4
+ export declare function agePenalty(transactionDate: string, now?: Date): number;
5
+ //# sourceMappingURL=scoring.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scoring.d.ts","sourceRoot":"","sources":["../../src/matching/scoring.ts"],"names":[],"mappings":"AAAA,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,EACnB,eAAe,EAAE,MAAM,EACvB,OAAO,GAAE,MAAW,GACnB,MAAM,CASR;AAED,wBAAgB,gBAAgB,CAAC,aAAa,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,GAAG,MAAM,CAGzF;AAED,wBAAgB,UAAU,CAAC,eAAe,EAAE,MAAM,EAAE,GAAG,GAAE,IAAiB,GAAG,MAAM,CAKlF"}
@@ -0,0 +1,28 @@
1
+ export function clampConfidence(score) {
2
+ return Math.max(0, Math.min(100, Math.round(score)));
3
+ }
4
+ export function dateProximityBonus(invoiceDate, transactionDate, maxDays = 30) {
5
+ const inv = new Date(invoiceDate).getTime();
6
+ const tx = new Date(transactionDate).getTime();
7
+ const diffDays = Math.abs(inv - tx) / (1000 * 60 * 60 * 24);
8
+ if (diffDays <= 3)
9
+ return 10;
10
+ if (diffDays <= 7)
11
+ return 5;
12
+ if (diffDays <= maxDays)
13
+ return 0;
14
+ return -10;
15
+ }
16
+ export function amountMatchBonus(invoiceAmount, transactionAmount) {
17
+ if (Math.abs(transactionAmount) === invoiceAmount)
18
+ return 5;
19
+ return 0;
20
+ }
21
+ export function agePenalty(transactionDate, now = new Date()) {
22
+ const tx = new Date(transactionDate).getTime();
23
+ const diffDays = (now.getTime() - tx) / (1000 * 60 * 60 * 24);
24
+ if (diffDays > 60)
25
+ return -10;
26
+ return 0;
27
+ }
28
+ //# sourceMappingURL=scoring.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scoring.js","sourceRoot":"","sources":["../../src/matching/scoring.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,eAAe,CAAC,KAAa;IAC3C,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;AACtD,CAAC;AAED,MAAM,UAAU,kBAAkB,CAChC,WAAmB,EACnB,eAAuB,EACvB,UAAkB,EAAE;IAEpB,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,WAAW,CAAC,CAAC,OAAO,EAAE,CAAA;IAC3C,MAAM,EAAE,GAAG,IAAI,IAAI,CAAC,eAAe,CAAC,CAAC,OAAO,EAAE,CAAA;IAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAA;IAE3D,IAAI,QAAQ,IAAI,CAAC;QAAE,OAAO,EAAE,CAAA;IAC5B,IAAI,QAAQ,IAAI,CAAC;QAAE,OAAO,CAAC,CAAA;IAC3B,IAAI,QAAQ,IAAI,OAAO;QAAE,OAAO,CAAC,CAAA;IACjC,OAAO,CAAC,EAAE,CAAA;AACZ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,aAAqB,EAAE,iBAAyB;IAC/E,IAAI,IAAI,CAAC,GAAG,CAAC,iBAAiB,CAAC,KAAK,aAAa;QAAE,OAAO,CAAC,CAAA;IAC3D,OAAO,CAAC,CAAA;AACV,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,eAAuB,EAAE,MAAY,IAAI,IAAI,EAAE;IACxE,MAAM,EAAE,GAAG,IAAI,IAAI,CAAC,eAAe,CAAC,CAAC,OAAO,EAAE,CAAA;IAC9C,MAAM,QAAQ,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAA;IAC7D,IAAI,QAAQ,GAAG,EAAE;QAAE,OAAO,CAAC,EAAE,CAAA;IAC7B,OAAO,CAAC,CAAA;AACV,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { loadPlugin } from './loader.js';
2
+ export { PluginRegistry } from './registry.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/plugins/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA"}
@@ -0,0 +1,3 @@
1
+ export { loadPlugin } from './loader.js';
2
+ export { PluginRegistry } from './registry.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/plugins/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA"}
@@ -0,0 +1,3 @@
1
+ import type { KsefPlugin } from '@ksefnik/shared';
2
+ export declare function loadPlugin(name: string): Promise<KsefPlugin | null>;
3
+ //# sourceMappingURL=loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/plugins/loader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAEjD,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CASzE"}
@@ -0,0 +1,13 @@
1
+ export async function loadPlugin(name) {
2
+ try {
3
+ const mod = await import(name);
4
+ const plugin = mod.default ?? mod;
5
+ if (!plugin.name || !plugin.version)
6
+ return null;
7
+ return plugin;
8
+ }
9
+ catch {
10
+ return null;
11
+ }
12
+ }
13
+ //# sourceMappingURL=loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/plugins/loader.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAY;IAC3C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,CAAA;QAC9B,MAAM,MAAM,GAAe,GAAG,CAAC,OAAO,IAAI,GAAG,CAAA;QAC7C,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO;YAAE,OAAO,IAAI,CAAA;QAChD,OAAO,MAAM,CAAA;IACf,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { KsefPlugin, ReconciliationPass } from '@ksefnik/shared';
2
+ export declare class PluginRegistry {
3
+ private plugins;
4
+ register(plugin: KsefPlugin): void;
5
+ list(): KsefPlugin[];
6
+ getPasses(): ReconciliationPass[];
7
+ }
8
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/plugins/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAGrE,qBAAa,cAAc;IACzB,OAAO,CAAC,OAAO,CAAmB;IAElC,QAAQ,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI;IAIlC,IAAI,IAAI,UAAU,EAAE;IAIpB,SAAS,IAAI,kBAAkB,EAAE;CAIlC"}
@@ -0,0 +1,15 @@
1
+ import { defaultPasses } from '../matching/passes/index.js';
2
+ export class PluginRegistry {
3
+ plugins = [];
4
+ register(plugin) {
5
+ this.plugins.push(plugin);
6
+ }
7
+ list() {
8
+ return [...this.plugins];
9
+ }
10
+ getPasses() {
11
+ const pluginPasses = this.plugins.flatMap((p) => p.reconciliationPasses?.() ?? []);
12
+ return [...defaultPasses, ...pluginPasses].sort((a, b) => a.order - b.order);
13
+ }
14
+ }
15
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/plugins/registry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAE3D,MAAM,OAAO,cAAc;IACjB,OAAO,GAAiB,EAAE,CAAA;IAElC,QAAQ,CAAC,MAAkB;QACzB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IAC3B,CAAC;IAED,IAAI;QACF,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAA;IAC1B,CAAC;IAED,SAAS;QACP,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,oBAAoB,EAAE,EAAE,IAAI,EAAE,CAAC,CAAA;QAClF,OAAO,CAAC,GAAG,aAAa,EAAE,GAAG,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAA;IAC9E,CAAC;CACF"}
@@ -0,0 +1,13 @@
1
+ import type { Storage, InvoiceQuery, TransactionQuery, Invoice, BankTransaction, ReconciliationReport } from '@ksefnik/shared';
2
+ export declare class InMemoryStorage implements Storage {
3
+ private invoices;
4
+ private transactions;
5
+ private reports;
6
+ saveInvoices(invoices: Invoice[]): Promise<void>;
7
+ getInvoices(query?: InvoiceQuery): Promise<Invoice[]>;
8
+ saveTransactions(txs: BankTransaction[]): Promise<void>;
9
+ getTransactions(query?: TransactionQuery): Promise<BankTransaction[]>;
10
+ saveReport(report: ReconciliationReport): Promise<void>;
11
+ getReport(id: string): Promise<ReconciliationReport | null>;
12
+ }
13
+ //# sourceMappingURL=in-memory.storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"in-memory.storage.d.ts","sourceRoot":"","sources":["../../src/storage/in-memory.storage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,OAAO,EACP,YAAY,EACZ,gBAAgB,EAChB,OAAO,EACP,eAAe,EACf,oBAAoB,EACrB,MAAM,iBAAiB,CAAA;AAExB,qBAAa,eAAgB,YAAW,OAAO;IAC7C,OAAO,CAAC,QAAQ,CAA6B;IAC7C,OAAO,CAAC,YAAY,CAAqC;IACzD,OAAO,CAAC,OAAO,CAA0C;IAEnD,YAAY,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAMhD,WAAW,CAAC,KAAK,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAmBrD,gBAAgB,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAMvD,eAAe,CAAC,KAAK,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAsBrE,UAAU,CAAC,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvD,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;CAGlE"}