@classytic/ledger 0.10.0 → 0.10.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 (2) hide show
  1. package/dist/index.mjs +42 -16
  2. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -909,6 +909,14 @@ async function safePublish$3(events, outboxStore, type, payload, ctx) {
909
909
  await events.publish(event);
910
910
  } catch {}
911
911
  }
912
+ function isDuplicateKeyBulkError(err) {
913
+ if (!err || typeof err !== "object") return false;
914
+ const e = err;
915
+ if (e.code === 11e3) return true;
916
+ if (Array.isArray(e.writeErrors) && e.writeErrors.length > 0) return true;
917
+ if (e.status === 409 && e.duplicate !== void 0) return true;
918
+ return false;
919
+ }
912
920
  /**
913
921
  * Wire seedAccounts, bulkCreate and posting-account validation
914
922
  * onto an existing mongokit Repository.
@@ -1075,24 +1083,42 @@ function wireAccountMethods(repository, country, orgField, integrations = {}) {
1075
1083
  _id: inserted[idx]._id
1076
1084
  }));
1077
1085
  } catch (err) {
1078
- const bulkError = err;
1079
- if (bulkError.code === 11e3 || bulkError.writeErrors) {
1080
- const insertedDocs = bulkError.insertedDocs ?? [];
1081
- const insertedNumbers = new Set(insertedDocs.map((d) => d.accountNumber));
1082
- for (const item of toCreate) if (insertedNumbers.has(item.accountNumber)) {
1083
- const iDoc = insertedDocs.find((d) => d.accountNumber === item.accountNumber);
1084
- results.created.push({
1085
- accountTypeCode: item.accountTypeCode,
1086
- active: item.active,
1087
- isCashAccount: item.isCashAccount,
1088
- _id: iDoc?._id
1089
- });
1090
- } else results.skipped.push({
1091
- index: item.index,
1086
+ if (!isDuplicateKeyBulkError(err)) throw err;
1087
+ const insertedDocs = err.insertedDocs ?? [];
1088
+ const insertedNumbers = new Set(insertedDocs.map((d) => d.accountNumber));
1089
+ const stillUnknown = toCreate.filter((t) => !insertedNumbers.has(t.accountNumber));
1090
+ const concurrentlyPersistedById = /* @__PURE__ */ new Map();
1091
+ if (stillUnknown.length > 0) {
1092
+ const concurrentFilter = { accountNumber: { $in: stillUnknown.map((t) => t.accountNumber) } };
1093
+ if (orgField && orgId != null) concurrentFilter[orgField] = orgId;
1094
+ const persisted = await repository.findAll(concurrentFilter, {
1095
+ select: {
1096
+ _id: 1,
1097
+ accountNumber: 1
1098
+ },
1099
+ lean: true
1100
+ });
1101
+ for (const p of persisted) concurrentlyPersistedById.set(p.accountNumber, p._id);
1102
+ }
1103
+ for (const item of toCreate) if (insertedNumbers.has(item.accountNumber)) {
1104
+ const iDoc = insertedDocs.find((d) => d.accountNumber === item.accountNumber);
1105
+ results.created.push({
1092
1106
  accountTypeCode: item.accountTypeCode,
1093
- reason: "Already exists (concurrent insert)"
1107
+ active: item.active,
1108
+ isCashAccount: item.isCashAccount,
1109
+ _id: iDoc?._id
1094
1110
  });
1095
- } else throw err;
1111
+ } else if (concurrentlyPersistedById.has(item.accountNumber)) results.skipped.push({
1112
+ index: item.index,
1113
+ accountTypeCode: item.accountTypeCode,
1114
+ reason: "Already exists (concurrent insert)",
1115
+ _id: concurrentlyPersistedById.get(item.accountNumber)
1116
+ });
1117
+ else results.skipped.push({
1118
+ index: item.index,
1119
+ accountTypeCode: item.accountTypeCode,
1120
+ reason: "Already exists (concurrent insert)"
1121
+ });
1096
1122
  }
1097
1123
  }
1098
1124
  const summary = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@classytic/ledger",
3
- "version": "0.10.0",
3
+ "version": "0.10.1",
4
4
  "description": "Production-grade double-entry accounting engine for MongoDB — schemas, reports, tax, multi-tenant",
5
5
  "type": "module",
6
6
  "sideEffects": false,