@monorise/core 4.0.0 → 4.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -311,13 +311,14 @@ var Repository = class {
311
311
 
312
312
  // data/Entity.ts
313
313
  var Entity = class _Entity extends Item {
314
- constructor(entityType, entityId, data = {}, _createdAt, _updatedAt) {
314
+ constructor(entityType, entityId, data = {}, _createdAt, _updatedAt, _expiresAt) {
315
315
  super();
316
316
  this.entityType = entityType;
317
317
  this.entityId = entityId;
318
318
  this.data = data;
319
319
  this._createdAt = _createdAt;
320
320
  this._updatedAt = _updatedAt;
321
+ this._expiresAt = _expiresAt;
321
322
  this.fullId = this.pk;
322
323
  }
323
324
  static fromItem(item) {
@@ -332,7 +333,9 @@ var Entity = class _Entity extends Item {
332
333
  parsedItem.entityId,
333
334
  parsedItem.data,
334
335
  parsedItem.createdAt ? new Date(parsedItem.createdAt) : void 0,
335
- parsedItem.updatedAt ? new Date(parsedItem.updatedAt) : void 0
336
+ parsedItem.updatedAt ? new Date(parsedItem.updatedAt) : void 0,
337
+ // expiresAt is stored as epoch seconds (DynamoDB TTL requires type N)
338
+ parsedItem.expiresAt ? new Date(parsedItem.expiresAt * 1e3) : void 0
336
339
  );
337
340
  }
338
341
  get pk() {
@@ -362,6 +365,9 @@ var Entity = class _Entity extends Item {
362
365
  var _a;
363
366
  return (_a = this._updatedAt) == null ? void 0 : _a.toISOString();
364
367
  }
368
+ get expiresAt() {
369
+ return this._expiresAt ? Math.floor(this._expiresAt.getTime() / 1e3) : void 0;
370
+ }
365
371
  toItem() {
366
372
  return __spreadValues(__spreadValues({}, marshall2(this.toJSON(), { removeUndefinedValues: true })), this.keys());
367
373
  }
@@ -371,7 +377,8 @@ var Entity = class _Entity extends Item {
371
377
  entityId: this.entityId,
372
378
  data: this.data,
373
379
  createdAt: this.createdAt,
374
- updatedAt: this.updatedAt
380
+ updatedAt: this.updatedAt,
381
+ expiresAt: this.expiresAt
375
382
  };
376
383
  }
377
384
  };
@@ -383,6 +390,46 @@ var EntityRepository = class extends Repository {
383
390
  this.dynamodbClient = dynamodbClient;
384
391
  this.EmailAuthEnabledEntities = EmailAuthEnabledEntities;
385
392
  }
393
+ /**
394
+ * Computes the `expiresAt` Date for an entity via its `ttl.processor` config, if any.
395
+ * When `mergeWithExisting` is true, the processor receives the previous entity's data
396
+ * merged with `incomingData` (falls back to `incomingData` alone if no previous entity
397
+ * exists yet, eg. an upsert-as-create).
398
+ */
399
+ computeExpiresAt(entityType, entityId, incomingData, updatedAt, opts) {
400
+ return __async(this, null, function* () {
401
+ var _a, _b;
402
+ const processor = (_b = (_a = this.EntityConfig[entityType]) == null ? void 0 : _a.ttl) == null ? void 0 : _b.processor;
403
+ if (!processor) return void 0;
404
+ let data = incomingData;
405
+ let createdAt = updatedAt;
406
+ if (opts.mergeWithExisting) {
407
+ let previous = opts.previousEntity;
408
+ if (!previous) {
409
+ try {
410
+ previous = yield this.getEntity(entityType, entityId);
411
+ } catch (err) {
412
+ if (!(err instanceof StandardError && err.code === StandardErrorCode.ENTITY_IS_UNDEFINED)) {
413
+ throw err;
414
+ }
415
+ }
416
+ }
417
+ if (previous) {
418
+ data = __spreadValues(__spreadValues({}, previous.data), incomingData);
419
+ createdAt = previous.createdAt || updatedAt;
420
+ }
421
+ }
422
+ const result = processor({
423
+ entityId,
424
+ entityType,
425
+ data,
426
+ createdAt,
427
+ updatedAt
428
+ });
429
+ if (result === void 0) return void 0;
430
+ return result instanceof Date ? result : new Date(result * 1e3);
431
+ });
432
+ }
386
433
  listEntities(_0) {
387
434
  return __async(this, arguments, function* ({
388
435
  entityType,
@@ -606,12 +653,21 @@ var EntityRepository = class extends Repository {
606
653
  return __async(this, null, function* () {
607
654
  var _a, _b;
608
655
  const currentDatetime = (_a = opts == null ? void 0 : opts.createAndUpdateDatetime) != null ? _a : /* @__PURE__ */ new Date();
656
+ const finalEntityId = entityId || ulid();
657
+ const expiresAt = yield this.computeExpiresAt(
658
+ entityType,
659
+ finalEntityId,
660
+ entityPayload,
661
+ currentDatetime.toISOString(),
662
+ { mergeWithExisting: false }
663
+ );
609
664
  const entity = new Entity(
610
665
  entityType,
611
- entityId || ulid(),
666
+ finalEntityId,
612
667
  entityPayload,
613
668
  currentDatetime,
614
- currentDatetime
669
+ currentDatetime,
670
+ expiresAt
615
671
  );
616
672
  const uniqueFields = this.EntityConfig[entityType].uniqueFields || [];
617
673
  const uniqueFieldValues = {};
@@ -656,26 +712,47 @@ var EntityRepository = class extends Repository {
656
712
  upsertEntity(entityType, entityId, payload) {
657
713
  return __async(this, null, function* () {
658
714
  const currentDatetime = (/* @__PURE__ */ new Date()).toISOString();
659
- const toUpdateExpressions = this.toUpdate({
715
+ const expiresAtForUpdate = yield this.computeExpiresAt(
716
+ entityType,
717
+ entityId,
718
+ payload,
719
+ currentDatetime,
720
+ { mergeWithExisting: true }
721
+ );
722
+ const toUpdateExpressions = this.toUpdate(__spreadValues({
660
723
  entityType,
661
724
  entityId,
662
725
  data: payload,
663
726
  updatedAt: currentDatetime
664
- });
727
+ }, expiresAtForUpdate && {
728
+ expiresAt: Math.floor(expiresAtForUpdate.getTime() / 1e3)
729
+ }));
665
730
  const params = {
666
731
  TableName: this.TABLE_NAME,
667
732
  ReturnValues: "ALL_NEW",
733
+ ConditionExpression: "attribute_exists(PK)",
668
734
  Key: new Entity(entityType, entityId).keys(),
669
735
  UpdateExpression: toUpdateExpressions.UpdateExpression,
670
736
  ExpressionAttributeNames: __spreadValues({}, toUpdateExpressions.ExpressionAttributeNames),
671
737
  ExpressionAttributeValues: __spreadValues({}, toUpdateExpressions.ExpressionAttributeValues)
672
738
  };
673
- const resp = yield this.dynamodbClient.updateItem(params);
674
- const updatedEntity = Entity.fromItem(resp.Attributes);
675
- return updatedEntity;
739
+ try {
740
+ const resp = yield this.dynamodbClient.updateItem(params);
741
+ return Entity.fromItem(resp.Attributes);
742
+ } catch (err) {
743
+ if (!(err instanceof ConditionalCheckFailedException)) {
744
+ throw err;
745
+ }
746
+ }
747
+ return this.createEntity(
748
+ entityType,
749
+ payload,
750
+ entityId,
751
+ { createAndUpdateDatetime: new Date(currentDatetime) }
752
+ );
676
753
  });
677
754
  }
678
- updateEntityTransactItems(entity, updateParams, previousUniqueFieldValues, previousEntity) {
755
+ updateEntityTransactItems(entity, updateParams, previousUniqueFieldValues, previousEntity, expiresAt) {
679
756
  const transactItems = [
680
757
  {
681
758
  Update: __spreadProps(__spreadValues({}, updateParams), {
@@ -698,7 +775,7 @@ var EntityRepository = class extends Repository {
698
775
  Put: {
699
776
  TableName: this.TABLE_NAME,
700
777
  ConditionExpression: "attribute_not_exists(PK)",
701
- Item: __spreadProps(__spreadValues({}, entity.toItem()), {
778
+ Item: __spreadValues(__spreadProps(__spreadValues({}, entity.toItem()), {
702
779
  data: {
703
780
  M: __spreadValues(__spreadValues({}, previousEntity.toItem().data.M), entity.toItem().data.M)
704
781
  },
@@ -712,6 +789,10 @@ var EntityRepository = class extends Repository {
712
789
  S: previousEntity.createdAt || entity.createdAt || (/* @__PURE__ */ new Date()).toISOString()
713
790
  },
714
791
  updatedAt: { S: entity.updatedAt || (/* @__PURE__ */ new Date()).toISOString() }
792
+ }), expiresAt && {
793
+ expiresAt: {
794
+ N: String(Math.floor(expiresAt.getTime() / 1e3))
795
+ }
715
796
  })
716
797
  }
717
798
  }
@@ -721,11 +802,42 @@ var EntityRepository = class extends Repository {
721
802
  }
722
803
  updateEntity(entityType, entityId, toUpdate, opts) {
723
804
  return __async(this, null, function* () {
805
+ var _a, _b;
724
806
  try {
725
807
  const currentDatetime = (/* @__PURE__ */ new Date()).toISOString();
726
- const toUpdateExpressions = this.toUpdate(__spreadValues({
808
+ const uniqueFields = this.EntityConfig[entityType].uniqueFields || [];
809
+ const hasUniqueFields = Object.keys(toUpdate.data).some(
810
+ (field) => uniqueFields.includes(field)
811
+ );
812
+ const hasTtlProcessor = !!((_b = (_a = this.EntityConfig[entityType]) == null ? void 0 : _a.ttl) == null ? void 0 : _b.processor);
813
+ let previousEntity;
814
+ if (hasUniqueFields || hasTtlProcessor) {
815
+ try {
816
+ previousEntity = yield this.getEntity(entityType, entityId);
817
+ } catch (err) {
818
+ if (err instanceof StandardError && err.code === StandardErrorCode.ENTITY_IS_UNDEFINED) {
819
+ throw new StandardError(
820
+ StandardErrorCode.ENTITY_NOT_FOUND,
821
+ "Entity not found",
822
+ err,
823
+ { entityId, toUpdate }
824
+ );
825
+ }
826
+ throw err;
827
+ }
828
+ }
829
+ const expiresAtDate = yield this.computeExpiresAt(
830
+ entityType,
831
+ entityId,
832
+ toUpdate.data,
833
+ currentDatetime,
834
+ { mergeWithExisting: true, previousEntity }
835
+ );
836
+ const toUpdateExpressions = this.toUpdate(__spreadValues(__spreadValues({
727
837
  updatedAt: currentDatetime
728
- }, toUpdate));
838
+ }, toUpdate), expiresAtDate && {
839
+ expiresAt: Math.floor(expiresAtDate.getTime() / 1e3)
840
+ }));
729
841
  const params = {
730
842
  TableName: this.TABLE_NAME,
731
843
  ReturnValues: "ALL_NEW",
@@ -736,15 +848,9 @@ var EntityRepository = class extends Repository {
736
848
  ExpressionAttributeValues: __spreadValues(__spreadValues({}, toUpdateExpressions.ExpressionAttributeValues), opts == null ? void 0 : opts.ExpressionAttributeValues)
737
849
  };
738
850
  const entity = new Entity(entityType, entityId, toUpdate.data);
739
- const uniqueFields = this.EntityConfig[entityType].uniqueFields || [];
740
- const hasUniqueFields = Object.keys(toUpdate.data).some(
741
- (field) => uniqueFields.includes(field)
742
- );
743
851
  let updatedUniqueFields = [];
744
852
  let previousUniqueFieldValues = {};
745
- let previousEntity;
746
- if (hasUniqueFields) {
747
- previousEntity = yield this.getEntity(entityType, entityId);
853
+ if (hasUniqueFields && previousEntity) {
748
854
  updatedUniqueFields = uniqueFields.filter(
749
855
  (field) => toUpdate.data[field] !== void 0 && toUpdate.data[field] !== previousEntity.data[field]
750
856
  );
@@ -763,11 +869,13 @@ var EntityRepository = class extends Repository {
763
869
  }
764
870
  }
765
871
  if (updatedUniqueFields.length > 0) {
872
+ const effectiveExpiresAtDate = expiresAtDate != null ? expiresAtDate : previousEntity.expiresAt !== void 0 ? new Date(previousEntity.expiresAt * 1e3) : void 0;
766
873
  const TransactItems = this.updateEntityTransactItems(
767
874
  entity,
768
875
  params,
769
876
  previousUniqueFieldValues,
770
- previousEntity
877
+ previousEntity,
878
+ effectiveExpiresAtDate
771
879
  );
772
880
  try {
773
881
  yield this.dynamodbClient.transactWriteItems({ TransactItems });
@@ -802,7 +910,14 @@ var EntityRepository = class extends Repository {
802
910
  }
803
911
  throw err;
804
912
  }
805
- return yield this.getEntity(entityType, entityId);
913
+ return new Entity(
914
+ entityType,
915
+ entityId,
916
+ __spreadValues(__spreadValues({}, previousEntity.data), toUpdate.data),
917
+ previousEntity.createdAt ? new Date(previousEntity.createdAt) : void 0,
918
+ new Date(currentDatetime),
919
+ effectiveExpiresAtDate
920
+ );
806
921
  }
807
922
  }
808
923
  const resp = yield this.dynamodbClient.updateItem(params);
@@ -967,7 +1082,8 @@ var Mutual = class _Mutual {
967
1082
  parsedItem.createdAt ? new Date(parsedItem.createdAt) : void 0,
968
1083
  parsedItem.updatedAt ? new Date(parsedItem.updatedAt) : void 0,
969
1084
  parsedItem.mutualUpdatedAt ? new Date(parsedItem.mutualUpdatedAt) : void 0,
970
- parsedItem.expiresAt ? new Date(parsedItem.expiresAt) : void 0
1085
+ // expiresAt is stored as epoch seconds (DynamoDB TTL requires type N)
1086
+ parsedItem.expiresAt ? new Date(parsedItem.expiresAt * 1e3) : void 0
971
1087
  );
972
1088
  }
973
1089
  mainKeys() {
@@ -1010,8 +1126,7 @@ var Mutual = class _Mutual {
1010
1126
  return (_a = this._mutualUpdatedAt) == null ? void 0 : _a.toISOString();
1011
1127
  }
1012
1128
  get expiresAt() {
1013
- var _a;
1014
- return (_a = this._expiresAt) == null ? void 0 : _a.toISOString();
1129
+ return this._expiresAt ? Math.floor(this._expiresAt.getTime() / 1e3) : void 0;
1015
1130
  }
1016
1131
  toItem() {
1017
1132
  return __spreadValues(__spreadValues({}, marshall3(this.toJSON(), { removeUndefinedValues: true })), this.mainKeys());
@@ -1110,7 +1225,14 @@ var MutualRepository = class extends Repository {
1110
1225
  }
1111
1226
  getMutual(byEntityType, byEntityId, entityType, entityId, opts) {
1112
1227
  return __async(this, null, function* () {
1113
- var _a, _b;
1228
+ var _a, _b, _c, _d, _e, _f;
1229
+ console.log("[MONORISE_DEBUG] getMutual start:", {
1230
+ byEntityType,
1231
+ byEntityId,
1232
+ entityType,
1233
+ entityId,
1234
+ opts
1235
+ });
1114
1236
  const mutual = new Mutual(
1115
1237
  byEntityType,
1116
1238
  byEntityId,
@@ -1120,6 +1242,11 @@ var MutualRepository = class extends Repository {
1120
1242
  {},
1121
1243
  {}
1122
1244
  );
1245
+ console.log("[MONORISE_DEBUG] getMutual querying:", {
1246
+ byFullEntityId: mutual.byFullEntityId,
1247
+ fullEntityId: mutual.fullEntityId,
1248
+ tableName: this.TABLE_NAME
1249
+ });
1123
1250
  const resp = yield this.dynamodbClient.query({
1124
1251
  TableName: this.TABLE_NAME,
1125
1252
  KeyConditionExpression: "#PK = :PK and begins_with(#SK, :SK)",
@@ -1136,9 +1263,14 @@ var MutualRepository = class extends Repository {
1136
1263
  },
1137
1264
  Limit: 1
1138
1265
  });
1266
+ console.log("[MONORISE_DEBUG] getMutual query result:", {
1267
+ hasItems: !!((_a = resp.Items) == null ? void 0 : _a.length),
1268
+ itemCount: (_c = (_b = resp.Items) == null ? void 0 : _b.length) != null ? _c : 0,
1269
+ hasLastEvaluatedKey: !!resp.LastEvaluatedKey
1270
+ });
1139
1271
  let mutualMetadata = null;
1140
1272
  if (opts == null ? void 0 : opts.isFromMetadata) {
1141
- const tempMutual = Mutual.fromItem((_a = resp.Items) == null ? void 0 : _a[0]);
1273
+ const tempMutual = Mutual.fromItem((_d = resp.Items) == null ? void 0 : _d[0]);
1142
1274
  const respMetadataMutual = yield this.dynamodbClient.getItem({
1143
1275
  TableName: this.TABLE_NAME,
1144
1276
  Key: tempMutual.mainKeys(),
@@ -1146,12 +1278,28 @@ var MutualRepository = class extends Repository {
1146
1278
  });
1147
1279
  mutualMetadata = Mutual.fromItem(respMetadataMutual.Item);
1148
1280
  }
1149
- return mutualMetadata || Mutual.fromItem((_b = resp.Items) == null ? void 0 : _b[0]);
1281
+ console.log("[MONORISE_DEBUG] getMutual fromItem:", {
1282
+ hasMutualMetadata: !!mutualMetadata,
1283
+ hasFirstItem: !!((_e = resp.Items) == null ? void 0 : _e[0])
1284
+ });
1285
+ const result = mutualMetadata || Mutual.fromItem((_f = resp.Items) == null ? void 0 : _f[0]);
1286
+ console.log("[MONORISE_DEBUG] getMutual complete:", {
1287
+ mutualId: result.mutualId,
1288
+ byEntityType: result.byEntityType,
1289
+ entityType: result.entityType
1290
+ });
1291
+ return result;
1150
1292
  });
1151
1293
  }
1152
1294
  checkMutualExist(byEntityType, byEntityId, entityType, entityId) {
1153
1295
  return __async(this, null, function* () {
1154
- var _a;
1296
+ var _a, _b;
1297
+ console.log("[MONORISE_DEBUG] checkMutualExist:", {
1298
+ byEntityType,
1299
+ byEntityId,
1300
+ entityType,
1301
+ entityId
1302
+ });
1155
1303
  const mutual = new Mutual(
1156
1304
  byEntityType,
1157
1305
  byEntityId,
@@ -1166,7 +1314,11 @@ var MutualRepository = class extends Repository {
1166
1314
  Key: mutual.subKeys(),
1167
1315
  ProjectionExpression: "PK, SK, expiresAt"
1168
1316
  });
1169
- if (resp.Item && !((_a = resp.Item) == null ? void 0 : _a.expiresAt)) {
1317
+ console.log("[MONORISE_DEBUG] checkMutualExist result:", {
1318
+ hasItem: !!resp.Item,
1319
+ hasExpiresAt: !!((_a = resp.Item) == null ? void 0 : _a.expiresAt)
1320
+ });
1321
+ if (resp.Item && !((_b = resp.Item) == null ? void 0 : _b.expiresAt)) {
1170
1322
  throw new StandardError(
1171
1323
  StandardErrorCode.MUTUAL_EXISTS,
1172
1324
  "Entities are already linked"
@@ -1176,6 +1328,14 @@ var MutualRepository = class extends Repository {
1176
1328
  });
1177
1329
  }
1178
1330
  createMutualTransactItems(mutual, opts) {
1331
+ console.log("[MONORISE_DEBUG] createMutualTransactItems:", {
1332
+ mutualId: mutual.mutualId,
1333
+ byEntityType: mutual.byEntityType,
1334
+ byEntityId: mutual.byEntityId,
1335
+ entityType: mutual.entityType,
1336
+ entityId: mutual.entityId,
1337
+ hasOpts: !!opts
1338
+ });
1179
1339
  const TransactItems = [
1180
1340
  {
1181
1341
  Put: {
@@ -1250,10 +1410,19 @@ var MutualRepository = class extends Repository {
1250
1410
  }
1251
1411
  updateMutual(byEntityType, byEntityId, entityType, entityId, toUpdate, opts) {
1252
1412
  return __async(this, null, function* () {
1253
- var _a;
1413
+ var _a, _b;
1414
+ console.log("[MONORISE_DEBUG] updateMutual repository start:", {
1415
+ byEntityType,
1416
+ byEntityId,
1417
+ entityType,
1418
+ entityId,
1419
+ toUpdateKeys: Object.keys(toUpdate),
1420
+ opts
1421
+ });
1254
1422
  const returnUpdatedValue = (_a = opts == null ? void 0 : opts.returnUpdatedValue) != null ? _a : false;
1255
1423
  const errorContext = {};
1256
1424
  try {
1425
+ console.log("[MONORISE_DEBUG] updateMutual fetching mutual...");
1257
1426
  const mutual = yield this.getMutual(
1258
1427
  byEntityType,
1259
1428
  byEntityId,
@@ -1261,6 +1430,12 @@ var MutualRepository = class extends Repository {
1261
1430
  entityId,
1262
1431
  { ProjectionExpression: PROJECTION_EXPRESSION.NO_DATA }
1263
1432
  );
1433
+ console.log("[MONORISE_DEBUG] updateMutual mutual found:", {
1434
+ mutualId: mutual.mutualId,
1435
+ mainPk: mutual.mainPk,
1436
+ byFullEntityId: mutual.byFullEntityId,
1437
+ fullEntityId: mutual.fullEntityId
1438
+ });
1264
1439
  const currentDatetime = (/* @__PURE__ */ new Date()).toISOString();
1265
1440
  const toUpdateExpressions = this.toUpdate(
1266
1441
  __spreadValues({
@@ -1268,6 +1443,11 @@ var MutualRepository = class extends Repository {
1268
1443
  }, toUpdate),
1269
1444
  { maxLevel: opts == null ? void 0 : opts.maxObjectUpdateLevel }
1270
1445
  );
1446
+ console.log("[MONORISE_DEBUG] updateMutual update expression:", {
1447
+ UpdateExpression: toUpdateExpressions.UpdateExpression,
1448
+ ExpressionAttributeNames: toUpdateExpressions.ExpressionAttributeNames,
1449
+ hasExpressionAttributeValues: !!toUpdateExpressions.ExpressionAttributeValues
1450
+ });
1271
1451
  const updateExpression = {
1272
1452
  ConditionExpression: (opts == null ? void 0 : opts.ConditionExpression) || "attribute_exists(PK)",
1273
1453
  UpdateExpression: toUpdateExpressions.UpdateExpression,
@@ -1301,18 +1481,33 @@ var MutualRepository = class extends Repository {
1301
1481
  }
1302
1482
  ];
1303
1483
  errorContext.TransactItems = TransactItems;
1484
+ console.log("[MONORISE_DEBUG] updateMutual transact items prepared:", {
1485
+ itemCount: TransactItems.length,
1486
+ tableName: this.TABLE_NAME
1487
+ });
1488
+ console.log("[MONORISE_DEBUG] updateMutual executing transaction...");
1304
1489
  yield this.ddbUtils.executeTransactWrite({ TransactItems });
1490
+ console.log("[MONORISE_DEBUG] updateMutual transaction succeeded");
1305
1491
  if (!returnUpdatedValue) {
1492
+ console.log("[MONORISE_DEBUG] updateMutual returning (no value)");
1306
1493
  return;
1307
1494
  }
1495
+ console.log("[MONORISE_DEBUG] updateMutual fetching updated mutual...");
1308
1496
  const updatedMutual = yield this.getMutual(
1309
1497
  byEntityType,
1310
1498
  byEntityId,
1311
1499
  entityType,
1312
1500
  entityId
1313
1501
  );
1502
+ console.log("[MONORISE_DEBUG] updateMutual repository complete");
1314
1503
  return updatedMutual;
1315
1504
  } catch (err) {
1505
+ console.error("[MONORISE_DEBUG] updateMutual repository error:", {
1506
+ errorName: (_b = err == null ? void 0 : err.constructor) == null ? void 0 : _b.name,
1507
+ errorMessage: err == null ? void 0 : err.message,
1508
+ errorCode: err == null ? void 0 : err.code,
1509
+ isStandardError: err instanceof StandardError
1510
+ });
1316
1511
  if (err instanceof StandardError && err.code === StandardErrorCode.CONDITIONAL_CHECK_FAILED) {
1317
1512
  throw new StandardError(
1318
1513
  StandardErrorCode.MUTUAL_NOT_FOUND,
@@ -2047,6 +2242,7 @@ var getDependencies = () => {
2047
2242
  // middlewares/general-error-handler.ts
2048
2243
  var factory2 = createFactory2();
2049
2244
  var generalErrorHandler = (dependencies = getDependencies()) => factory2.createMiddleware((c) => __async(null, null, function* () {
2245
+ var _a, _b, _c, _d;
2050
2246
  if (c.error) {
2051
2247
  const { nanoid: nanoid2, publishErrorEvent: publishErrorEvent2 } = dependencies;
2052
2248
  const errorId = nanoid2();
@@ -2059,12 +2255,21 @@ var generalErrorHandler = (dependencies = getDependencies()) => factory2.createM
2059
2255
  body,
2060
2256
  error: c.error
2061
2257
  });
2062
- console.warn(
2063
- JSON.stringify({
2064
- message: "INTERNAL_SERVER_EXCEPTION",
2065
- details: c.error
2066
- })
2067
- );
2258
+ const error = c.error;
2259
+ console.warn("[MONORISE_DEBUG] INTERNAL_SERVER_EXCEPTION:", {
2260
+ errorId,
2261
+ method: c.req.method,
2262
+ path: c.req.path,
2263
+ errorName: error == null ? void 0 : error.name,
2264
+ errorMessage: error == null ? void 0 : error.message,
2265
+ errorCode: error == null ? void 0 : error.code,
2266
+ errorStack: error == null ? void 0 : error.stack,
2267
+ errorConstructor: (_a = error == null ? void 0 : error.constructor) == null ? void 0 : _a.name,
2268
+ hasLastError: !!(error == null ? void 0 : error.lastError),
2269
+ lastErrorName: (_c = (_b = error == null ? void 0 : error.lastError) == null ? void 0 : _b.constructor) == null ? void 0 : _c.name,
2270
+ lastErrorMessage: (_d = error == null ? void 0 : error.lastError) == null ? void 0 : _d.message,
2271
+ context: error == null ? void 0 : error.context
2272
+ });
2068
2273
  c.status(500);
2069
2274
  c.json({
2070
2275
  code: "INTERNAL_SERVER_EXCEPTION",
@@ -2147,7 +2352,7 @@ var handler2 = (container) => (ev) => __async(null, null, function* () {
2147
2352
  const { entityRepository, mutualRepository, publishEvent: publishEvent2 } = container;
2148
2353
  yield Promise.allSettled(
2149
2354
  ev.Records.map((record) => __async(null, null, function* () {
2150
- var _a, _b, _c, _d;
2355
+ var _a, _b, _c, _d, _e;
2151
2356
  const errorContext = {};
2152
2357
  const body = parseSQSBusEvent(record.body);
2153
2358
  const { detail } = body;
@@ -2170,6 +2375,7 @@ var handler2 = (container) => (ev) => __async(null, null, function* () {
2170
2375
  );
2171
2376
  }
2172
2377
  const mutualDataProcessor = (_d = config.mutualDataProcessor) != null ? _d : (() => ({}));
2378
+ const mutualDataSchema = (_e = config.mutual) == null ? void 0 : _e.mutualDataSchema;
2173
2379
  yield mutualRepository.createMutualLock({
2174
2380
  byEntityType,
2175
2381
  byEntityId,
@@ -2205,6 +2411,20 @@ var handler2 = (container) => (ev) => __async(null, null, function* () {
2205
2411
  addedEntityIds,
2206
2412
  (id) => __async(null, null, function* () {
2207
2413
  const entity = yield entityRepository.getEntity(entityType, id);
2414
+ const processedMutualData = mutualDataProcessor(
2415
+ mutualIds,
2416
+ new Mutual(
2417
+ byEntityType,
2418
+ byEntityId,
2419
+ byEntity.data,
2420
+ entityType,
2421
+ id,
2422
+ entity.data,
2423
+ {}
2424
+ ),
2425
+ customContext
2426
+ );
2427
+ const parsedMutualData = mutualDataSchema ? mutualDataSchema.parse(processedMutualData) : processedMutualData;
2208
2428
  yield mutualRepository.createMutual(
2209
2429
  byEntityType,
2210
2430
  byEntityId,
@@ -2212,19 +2432,7 @@ var handler2 = (container) => (ev) => __async(null, null, function* () {
2212
2432
  entityType,
2213
2433
  id,
2214
2434
  entity.data,
2215
- mutualDataProcessor(
2216
- mutualIds,
2217
- new Mutual(
2218
- byEntityType,
2219
- byEntityId,
2220
- byEntity.data,
2221
- entityType,
2222
- id,
2223
- entity.data,
2224
- {}
2225
- ),
2226
- customContext
2227
- ),
2435
+ parsedMutualData,
2228
2436
  {
2229
2437
  ConditionExpression: "attribute_not_exists(#mutualUpdatedAt) OR #mutualUpdatedAt < :publishedAt",
2230
2438
  ExpressionAttributeNames: {
@@ -2261,25 +2469,27 @@ var handler2 = (container) => (ev) => __async(null, null, function* () {
2261
2469
  const updateEntities = yield processEntities(
2262
2470
  toUpdateEntityIds,
2263
2471
  (id) => __async(null, null, function* () {
2472
+ const processedMutualData = mutualDataProcessor(
2473
+ mutualIds,
2474
+ new Mutual(
2475
+ byEntityType,
2476
+ byEntityId,
2477
+ byEntity.data,
2478
+ entityType,
2479
+ id,
2480
+ {},
2481
+ {}
2482
+ ),
2483
+ customContext
2484
+ );
2485
+ const parsedMutualData = mutualDataSchema ? mutualDataSchema.parse(processedMutualData) : processedMutualData;
2264
2486
  yield mutualRepository.updateMutual(
2265
2487
  byEntityType,
2266
2488
  byEntityId,
2267
2489
  entityType,
2268
2490
  id,
2269
2491
  {
2270
- mutualData: mutualDataProcessor(
2271
- mutualIds,
2272
- new Mutual(
2273
- byEntityType,
2274
- byEntityId,
2275
- byEntity.data,
2276
- entityType,
2277
- id,
2278
- {},
2279
- {}
2280
- ),
2281
- customContext
2282
- ),
2492
+ mutualData: parsedMutualData,
2283
2493
  mutualUpdatedAt: publishedAt
2284
2494
  },
2285
2495
  {
@@ -7731,7 +7941,8 @@ var EntityService = class {
7731
7941
  // services/mutual.service.ts
7732
7942
  import { ulid as ulid3 } from "ulid";
7733
7943
  var MutualService = class {
7734
- constructor(entityRepository, mutualRepository, publishEvent2, ddbUtils, entityServiceLifeCycle) {
7944
+ constructor(EntityConfig, entityRepository, mutualRepository, publishEvent2, ddbUtils, entityServiceLifeCycle) {
7945
+ this.EntityConfig = EntityConfig;
7735
7946
  this.entityRepository = entityRepository;
7736
7947
  this.mutualRepository = mutualRepository;
7737
7948
  this.publishEvent = publishEvent2;
@@ -7746,6 +7957,7 @@ var MutualService = class {
7746
7957
  accountId,
7747
7958
  options = {}
7748
7959
  }) {
7960
+ var _a;
7749
7961
  const {
7750
7962
  ensureEntityStrongConsistentWrite = false,
7751
7963
  asEntity,
@@ -7766,20 +7978,37 @@ var MutualService = class {
7766
7978
  options
7767
7979
  }
7768
7980
  };
7769
- const schema = external_exports.record(external_exports.string(), external_exports.any());
7981
+ console.log("[MONORISE_DEBUG] createMutual service start:", {
7982
+ byEntityType,
7983
+ byEntityId,
7984
+ entityType,
7985
+ entityId,
7986
+ mutualPayload,
7987
+ options
7988
+ });
7989
+ const schema = (_a = this.getMutualDataSchema(byEntityType, entityType)) != null ? _a : external_exports.record(external_exports.string(), external_exports.any());
7990
+ console.log("[MONORISE_DEBUG] createMutual schema resolved");
7770
7991
  const parsedMutualPayload = schema.parse(mutualPayload);
7992
+ console.log("[MONORISE_DEBUG] createMutual payload parsed:", parsedMutualPayload);
7993
+ console.log("[MONORISE_DEBUG] createMutual fetching entities...");
7771
7994
  const [{ data: byEntityData }, { data: entityData }] = yield Promise.all([
7772
7995
  this.entityRepository.getEntity(byEntityType, byEntityId),
7773
7996
  this.entityRepository.getEntity(entityType, entityId)
7774
7997
  ]);
7998
+ console.log("[MONORISE_DEBUG] createMutual entities fetched:", {
7999
+ hasByEntityData: !!byEntityData,
8000
+ hasEntityData: !!entityData
8001
+ });
7775
8002
  errorContext.byEntityData = byEntityData;
7776
8003
  errorContext.entityData = entityData;
8004
+ console.log("[MONORISE_DEBUG] createMutual checking mutual exist...");
7777
8005
  yield this.mutualRepository.checkMutualExist(
7778
8006
  byEntityType,
7779
8007
  byEntityId,
7780
8008
  entityType,
7781
8009
  entityId
7782
8010
  );
8011
+ console.log("[MONORISE_DEBUG] createMutual mutual does not exist (ok)");
7783
8012
  const currentDatetime = createAndUpdateDatetime || /* @__PURE__ */ new Date();
7784
8013
  const mutual = new Mutual(
7785
8014
  byEntityType,
@@ -7794,6 +8023,9 @@ var MutualService = class {
7794
8023
  currentDatetime,
7795
8024
  currentDatetime
7796
8025
  );
8026
+ console.log("[MONORISE_DEBUG] createMutual mutual object created:", {
8027
+ mutualId: mutual.mutualId
8028
+ });
7797
8029
  const mutualTransactions = skipMutualCreation ? [] : this.mutualRepository.createMutualTransactItems(mutual, {
7798
8030
  ConditionExpression,
7799
8031
  ExpressionAttributeNames,
@@ -7817,9 +8049,13 @@ var MutualService = class {
7817
8049
  }
7818
8050
  const createTransactItems = [...mutualTransactions, ...entityTransactions];
7819
8051
  errorContext.createTransactItems = createTransactItems;
8052
+ console.log("[MONORISE_DEBUG] createMutual executing transaction:", {
8053
+ transactItemCount: createTransactItems.length
8054
+ });
7820
8055
  yield this.ddbUtils.executeTransactWrite({
7821
8056
  TransactItems: createTransactItems
7822
8057
  });
8058
+ console.log("[MONORISE_DEBUG] createMutual transaction succeeded");
7823
8059
  if (asEntity && entity && ensureEntityStrongConsistentWrite) {
7824
8060
  yield this.entityServiceLifeCycle.afterCreateEntityHook(
7825
8061
  entity,
@@ -7858,6 +8094,7 @@ var MutualService = class {
7858
8094
  })
7859
8095
  ];
7860
8096
  yield Promise.all(eventPromises);
8097
+ console.log("[MONORISE_DEBUG] createMutual service complete");
7861
8098
  return { mutual, eventPayload };
7862
8099
  });
7863
8100
  this.updateMutual = (_0) => __async(this, [_0], function* ({
@@ -7869,8 +8106,20 @@ var MutualService = class {
7869
8106
  accountId,
7870
8107
  options
7871
8108
  }) {
7872
- const schema = external_exports.record(external_exports.string(), external_exports.any());
8109
+ var _a;
8110
+ console.log("[MONORISE_DEBUG] updateMutual service start:", {
8111
+ byEntityType,
8112
+ byEntityId,
8113
+ entityType,
8114
+ entityId,
8115
+ mutualPayload,
8116
+ options
8117
+ });
8118
+ const schema = (_a = this.getMutualDataSchema(byEntityType, entityType)) != null ? _a : external_exports.record(external_exports.string(), external_exports.any());
8119
+ console.log("[MONORISE_DEBUG] updateMutual schema resolved");
7873
8120
  const parsedMutualPayload = schema.parse(mutualPayload);
8121
+ console.log("[MONORISE_DEBUG] updateMutual payload parsed:", parsedMutualPayload);
8122
+ console.log("[MONORISE_DEBUG] updateMutual calling repository...");
7874
8123
  const mutual = yield this.mutualRepository.updateMutual(
7875
8124
  byEntityType,
7876
8125
  byEntityId,
@@ -7879,6 +8128,10 @@ var MutualService = class {
7879
8128
  { mutualData: parsedMutualPayload },
7880
8129
  options
7881
8130
  );
8131
+ console.log("[MONORISE_DEBUG] updateMutual repository result:", {
8132
+ hasMutual: !!mutual,
8133
+ mutualId: mutual == null ? void 0 : mutual.mutualId
8134
+ });
7882
8135
  yield this.publishEvent({
7883
8136
  event: EVENT.CORE.MUTUAL_UPDATED(byEntityType, entityType),
7884
8137
  payload: {
@@ -7890,6 +8143,7 @@ var MutualService = class {
7890
8143
  updatedByAccountId: accountId
7891
8144
  }
7892
8145
  });
8146
+ console.log("[MONORISE_DEBUG] updateMutual service complete");
7893
8147
  return mutual;
7894
8148
  });
7895
8149
  this.deleteMutual = (_0) => __async(this, [_0], function* ({
@@ -7918,6 +8172,22 @@ var MutualService = class {
7918
8172
  return mutual;
7919
8173
  });
7920
8174
  }
8175
+ getMutualDataSchema(byEntityType, entityType) {
8176
+ var _a, _b, _c;
8177
+ for (const [from, to] of [
8178
+ [byEntityType, entityType],
8179
+ [entityType, byEntityType]
8180
+ ]) {
8181
+ const mutualFields = (_b = (_a = this.EntityConfig[from]) == null ? void 0 : _a.mutual) == null ? void 0 : _b.mutualFields;
8182
+ if (!mutualFields) continue;
8183
+ for (const config of Object.values(mutualFields)) {
8184
+ if (config.entityType === to && ((_c = config.mutual) == null ? void 0 : _c.mutualDataSchema)) {
8185
+ return config.mutual.mutualDataSchema;
8186
+ }
8187
+ }
8188
+ }
8189
+ return void 0;
8190
+ }
7921
8191
  };
7922
8192
 
7923
8193
  // controllers/tag/list-tags.controller.ts
@@ -8077,6 +8347,7 @@ var DependencyContainer = class {
8077
8347
  get mutualService() {
8078
8348
  return this.createCachedInstance(
8079
8349
  MutualService,
8350
+ this.config.EntityConfig,
8080
8351
  this.entityRepository,
8081
8352
  this.mutualRepository,
8082
8353
  this.publishEvent,