@infrab4a/connect 5.3.0-beta.30 → 5.3.0-beta.32

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 (38) hide show
  1. package/index.cjs.js +333 -92
  2. package/index.esm.js +324 -74
  3. package/package.json +1 -1
  4. package/src/domain/shop-settings/models/shop-configs.d.ts +3 -12
  5. package/src/domain/shop-settings/models/types/antifraud-config.type.d.ts +21 -0
  6. package/src/domain/shop-settings/models/types/index.d.ts +1 -0
  7. package/src/domain/shop-settings/models/types/limit-orders.type.d.ts +3 -2
  8. package/src/domain/shopping/helpers/antifraud-enabled.helper.d.ts +8 -0
  9. package/src/domain/shopping/helpers/antifraud-volume-limits.helper.d.ts +6 -0
  10. package/src/domain/shopping/helpers/index.d.ts +2 -0
  11. package/src/domain/shopping/index.d.ts +1 -0
  12. package/src/domain/shopping/models/campaign-hashtag-posts.d.ts +23 -0
  13. package/src/domain/shopping/models/campaign-hashtag.d.ts +12 -10
  14. package/src/domain/shopping/models/checkout.d.ts +2 -0
  15. package/src/domain/shopping/models/coupons/coupon.d.ts +1 -0
  16. package/src/domain/shopping/models/index.d.ts +1 -0
  17. package/src/domain/shopping/models/line-item.d.ts +4 -0
  18. package/src/domain/shopping/models/order.d.ts +1 -0
  19. package/src/domain/shopping/models/shipping-method.d.ts +1 -0
  20. package/src/domain/shopping/models/types/line-item-recurrence.type.d.ts +1 -1
  21. package/src/domain/shopping/repositories/campaign-hashtag-posts.repository.d.ts +4 -0
  22. package/src/domain/shopping/repositories/index.d.ts +1 -0
  23. package/src/domain/shopping/services/antifraud-bankslip.service.d.ts +3 -1
  24. package/src/domain/shopping/services/antifraud-card.service.d.ts +6 -6
  25. package/src/domain/shopping/services/antifraud-glampoints.service.d.ts +4 -2
  26. package/src/domain/shopping/services/antifraud-pix.service.d.ts +4 -2
  27. package/src/domain/shopping/types/antifraud-card-validation.type.d.ts +40 -0
  28. package/src/domain/shopping/types/antifraud-volume-limits.type.d.ts +24 -0
  29. package/src/domain/shopping/types/create-recurrency-payload.type.d.ts +0 -2
  30. package/src/domain/shopping/types/index.d.ts +3 -0
  31. package/src/domain/shopping/types/shopping-recurrence-update-payloads.type.d.ts +35 -0
  32. package/src/infra/cache/index.d.ts +1 -0
  33. package/src/infra/cache/resolve-cache-config.d.ts +2 -0
  34. package/src/infra/cache/restcache.adapter.d.ts +3 -0
  35. package/src/infra/firebase/firestore/repositories/shopping/campaign-hashtag-posts-firestore.repository.d.ts +8 -0
  36. package/src/infra/firebase/firestore/repositories/shopping/index.d.ts +1 -0
  37. package/src/utils/index.d.ts +1 -0
  38. package/src/utils/to-cents.d.ts +5 -0
package/index.cjs.js CHANGED
@@ -20,25 +20,7 @@ var storage = require('firebase/storage');
20
20
 
21
21
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
22
22
 
23
- function _interopNamespace(e) {
24
- if (e && e.__esModule) return e;
25
- var n = Object.create(null);
26
- if (e) {
27
- Object.keys(e).forEach(function (k) {
28
- if (k !== 'default') {
29
- var d = Object.getOwnPropertyDescriptor(e, k);
30
- Object.defineProperty(n, k, d.get ? d : {
31
- enumerable: true,
32
- get: function () { return e[k]; }
33
- });
34
- }
35
- });
36
- }
37
- n["default"] = e;
38
- return Object.freeze(n);
39
- }
40
-
41
- var serializeJavascript__namespace = /*#__PURE__*/_interopNamespace(serializeJavascript);
23
+ var serializeJavascript__default = /*#__PURE__*/_interopDefaultLegacy(serializeJavascript);
42
24
  var axios__default = /*#__PURE__*/_interopDefaultLegacy(axios);
43
25
 
44
26
  exports.AntifraudProviders = void 0;
@@ -175,6 +157,123 @@ class PaymentProviderFactory {
175
157
  }
176
158
  }
177
159
 
160
+ const ANTIFRAUD_CONFIG_CACHE_TTL_SECONDS = 60;
161
+ /**
162
+ * Lê `shopConfigs.antifraude.enabled`.
163
+ * - `false` explícito → antifraude desligado
164
+ * - ausente / erro / inválido → `true` (mantém comportamento histórico)
165
+ */
166
+ async function isAntifraudEnabled(shopConfigsRepository) {
167
+ if (!shopConfigsRepository) {
168
+ return true;
169
+ }
170
+ try {
171
+ const result = await shopConfigsRepository.find({}, { cache: { enabled: true, ttl: ANTIFRAUD_CONFIG_CACHE_TTL_SECONDS } });
172
+ const enabled = result?.data?.at(0)?.antifraude?.enabled;
173
+ if (typeof enabled === 'boolean') {
174
+ return enabled;
175
+ }
176
+ return true;
177
+ }
178
+ catch (error) {
179
+ console.warn(JSON.stringify({
180
+ msg: 'antifraud_enabled_config_load_failed',
181
+ enabled: true,
182
+ error: error instanceof Error ? error.message : String(error),
183
+ }));
184
+ return true;
185
+ }
186
+ }
187
+
188
+ /** Defaults de runtime (week.zip = Infinity). Usados só como fallback no checkout. */
189
+ const DEFAULT_ANTIFRAUD_VOLUME_LIMITS = {
190
+ enabled: true,
191
+ source: 'fallback',
192
+ day: {
193
+ subscriber: { cpf: 4, email: 4, phone: 4, card: 4, zip: 4 },
194
+ nonSubscriber: { cpf: 2, email: 2, phone: 2, card: 2, zip: 2 },
195
+ },
196
+ week: {
197
+ subscriber: { cpf: 12, email: 12, phone: 12, card: 12, zip: Infinity },
198
+ nonSubscriber: { cpf: 7, email: 7, phone: 7, card: 7, zip: Infinity },
199
+ },
200
+ blockedAttemptsDay: {
201
+ subscriber: 7,
202
+ nonSubscriber: 5,
203
+ },
204
+ };
205
+ function isPositiveInteger(value) {
206
+ return typeof value === 'number' && Number.isFinite(value) && value >= 1 && Number.isInteger(value);
207
+ }
208
+ function normalizeLimitOrders(raw, allowInfiniteZip) {
209
+ if (!raw)
210
+ return null;
211
+ const zip = allowInfiniteZip && (raw.zip === null || raw.zip === undefined || raw.zip === Infinity) ? Infinity : raw.zip;
212
+ const normalized = {
213
+ cpf: raw.cpf,
214
+ email: raw.email,
215
+ phone: raw.phone,
216
+ zip: zip,
217
+ card: raw.card,
218
+ };
219
+ for (const key of ['cpf', 'email', 'phone', 'zip', 'card']) {
220
+ if (key === 'zip' && normalized.zip === Infinity)
221
+ continue;
222
+ if (!isPositiveInteger(normalized[key]))
223
+ return null;
224
+ }
225
+ return normalized;
226
+ }
227
+ function cloneFallbackLimits() {
228
+ return {
229
+ ...DEFAULT_ANTIFRAUD_VOLUME_LIMITS,
230
+ day: {
231
+ subscriber: { ...DEFAULT_ANTIFRAUD_VOLUME_LIMITS.day.subscriber },
232
+ nonSubscriber: { ...DEFAULT_ANTIFRAUD_VOLUME_LIMITS.day.nonSubscriber },
233
+ },
234
+ week: {
235
+ subscriber: { ...DEFAULT_ANTIFRAUD_VOLUME_LIMITS.week.subscriber },
236
+ nonSubscriber: { ...DEFAULT_ANTIFRAUD_VOLUME_LIMITS.week.nonSubscriber },
237
+ },
238
+ blockedAttemptsDay: { ...DEFAULT_ANTIFRAUD_VOLUME_LIMITS.blockedAttemptsDay },
239
+ source: 'fallback',
240
+ };
241
+ }
242
+ /** Config inválida/ausente → fallback (comportamento histórico). */
243
+ function resolveAntifraudVolumeLimits(antifraude) {
244
+ if (!antifraude || typeof antifraude.enabled !== 'boolean') {
245
+ return cloneFallbackLimits();
246
+ }
247
+ const daySubscriber = normalizeLimitOrders(antifraude.day?.subscriber, false);
248
+ const dayNonSubscriber = normalizeLimitOrders(antifraude.day?.nonSubscriber, false);
249
+ const weekSubscriber = normalizeLimitOrders(antifraude.week?.subscriber, true);
250
+ const weekNonSubscriber = normalizeLimitOrders(antifraude.week?.nonSubscriber, true);
251
+ const blocked = antifraude.blockedAttemptsDay;
252
+ if (!daySubscriber ||
253
+ !dayNonSubscriber ||
254
+ !weekSubscriber ||
255
+ !weekNonSubscriber ||
256
+ !blocked ||
257
+ !isPositiveInteger(blocked.subscriber) ||
258
+ !isPositiveInteger(blocked.nonSubscriber)) {
259
+ // Kill-switch explícito prevalece mesmo com payload inválido.
260
+ if (antifraude.enabled === false) {
261
+ return { ...cloneFallbackLimits(), enabled: false, source: 'fallback' };
262
+ }
263
+ return cloneFallbackLimits();
264
+ }
265
+ return {
266
+ enabled: antifraude.enabled,
267
+ source: 'config',
268
+ day: { subscriber: daySubscriber, nonSubscriber: dayNonSubscriber },
269
+ week: { subscriber: weekSubscriber, nonSubscriber: weekNonSubscriber },
270
+ blockedAttemptsDay: {
271
+ subscriber: blocked.subscriber,
272
+ nonSubscriber: blocked.nonSubscriber,
273
+ },
274
+ };
275
+ }
276
+
178
277
  const registry = new Map();
179
278
  function registerClass(name, classConstructor) {
180
279
  registry.set(name, classConstructor);
@@ -660,9 +759,22 @@ const deserialize = (data) => {
660
759
  return eval('(' + data + ')');
661
760
  };
662
761
  const serialize = (data) => {
663
- return serializeJavascript__namespace(data);
762
+ return serializeJavascript__default["default"](data);
664
763
  };
665
764
 
765
+ /**
766
+ * Converts a BRL major-unit amount (e.g. 10.5) to integer cents (1050).
767
+ * Uses fixed 2-decimal normalization to avoid IEEE-754 artifacts like 19.99 * 100.
768
+ */
769
+ function toCents(amount) {
770
+ if (!Number.isFinite(amount)) {
771
+ throw new Error(`Invalid amount: ${amount}`);
772
+ }
773
+ const sign = amount < 0 ? -1 : 1;
774
+ const [whole, fraction = '0'] = Math.abs(amount).toFixed(2).split('.');
775
+ return sign * (Number(whole) * 100 + Number(fraction));
776
+ }
777
+
666
778
  class BaseModel {
667
779
  get identifier() {
668
780
  const fields = this.constructor.identifiersFields.filter((field) => field !== 'identifier');
@@ -1043,6 +1155,12 @@ class CampaignHashtag extends BaseModel {
1043
1155
  }
1044
1156
  }
1045
1157
 
1158
+ class CampaignHashtagPosts extends BaseModel {
1159
+ static get identifiersFields() {
1160
+ return ['id'];
1161
+ }
1162
+ }
1163
+
1046
1164
  class BeautyProfile extends BaseModel {
1047
1165
  toPlain() {
1048
1166
  const plain = super.toPlain();
@@ -1911,12 +2029,23 @@ class StockOutError extends BusinessError {
1911
2029
  }
1912
2030
  }
1913
2031
 
2032
+ /* eslint-disable no-console */
1914
2033
  class AntifraudBankSlipService {
1915
- constructor(orderBlockedRepository) {
2034
+ constructor(orderBlockedRepository, shopConfigsRepository) {
1916
2035
  this.orderBlockedRepository = orderBlockedRepository;
2036
+ this.shopConfigsRepository = shopConfigsRepository;
1917
2037
  this.MAX_ORDER_VALUE = 5000;
1918
2038
  }
1919
2039
  async validate(checkout) {
2040
+ const enabled = await isAntifraudEnabled(this.shopConfigsRepository);
2041
+ if (!enabled) {
2042
+ console.info(JSON.stringify({
2043
+ msg: 'antifraud_bankslip_skipped',
2044
+ enabled: false,
2045
+ checkoutId: checkout.id,
2046
+ }));
2047
+ return true;
2048
+ }
1920
2049
  if (checkout.totalPrice && checkout.totalPrice > this.MAX_ORDER_VALUE && !checkout.user?.isSubscriber) {
1921
2050
  await this.orderBlockedRepository.createBlockedOrderOrPayment({
1922
2051
  checkout,
@@ -1938,62 +2067,67 @@ class AntifraudBankSlipService {
1938
2067
  }
1939
2068
  }
1940
2069
 
2070
+ /* eslint-disable max-params */
1941
2071
  class AntifraudCardService {
1942
- constructor(orderRepository, orderBlockedRepository) {
2072
+ constructor(orderRepository, orderBlockedRepository, shopConfigsRepository) {
1943
2073
  this.orderRepository = orderRepository;
1944
2074
  this.orderBlockedRepository = orderBlockedRepository;
1945
- this.LIMIT_ORDERS_DAY = null;
1946
- this.LIMIT_ORDERS_WEEK = null;
2075
+ this.shopConfigsRepository = shopConfigsRepository;
1947
2076
  }
1948
2077
  async validate(checkout, card) {
1949
- this.setLimitsByUserType(checkout.user.isSubscriber);
1950
- await this.validateBlockedOrderAttempts(checkout, card);
1951
- await this.validateDayAndWeekOrderLimits(checkout, card);
2078
+ // Limites locais por request — evita race em provider Nest singleton entre awaits.
2079
+ const resolved = await this.loadResolvedLimits();
2080
+ const isSubscriber = !!checkout.user?.isSubscriber;
2081
+ const dayLimits = isSubscriber ? resolved.day.subscriber : resolved.day.nonSubscriber;
2082
+ const weekLimits = isSubscriber ? resolved.week.subscriber : resolved.week.nonSubscriber;
2083
+ const blockedAttemptsDay = isSubscriber
2084
+ ? resolved.blockedAttemptsDay.subscriber
2085
+ : resolved.blockedAttemptsDay.nonSubscriber;
2086
+ if (!resolved.enabled) {
2087
+ console.info(JSON.stringify({
2088
+ msg: 'antifraud_card_volume_skipped',
2089
+ source: resolved.source,
2090
+ enabled: false,
2091
+ checkoutId: checkout.id,
2092
+ isSubscriber,
2093
+ }));
2094
+ return true;
2095
+ }
2096
+ console.info(JSON.stringify({
2097
+ msg: 'antifraud_card_volume_limits',
2098
+ source: resolved.source,
2099
+ enabled: true,
2100
+ checkoutId: checkout.id,
2101
+ isSubscriber,
2102
+ blockedAttemptsDay,
2103
+ day: dayLimits,
2104
+ week: weekLimits,
2105
+ }));
2106
+ await this.validateBlockedOrderAttempts(checkout, card, blockedAttemptsDay);
2107
+ await this.validateDayAndWeekOrderLimits(checkout, card, dayLimits, weekLimits);
1952
2108
  return true;
1953
2109
  }
1954
- setLimitsByUserType(isSubscriber) {
1955
- this.LIMIT_ORDERS_DAY = {
1956
- subscriber: {
1957
- cpf: 4,
1958
- email: 4,
1959
- phone: 4,
1960
- card: 4,
1961
- zip: 4,
1962
- },
1963
- nonSubscriber: {
1964
- cpf: 2,
1965
- email: 2,
1966
- phone: 2,
1967
- card: 2,
1968
- zip: 2,
1969
- },
1970
- };
1971
- this.LIMIT_ORDERS_WEEK = {
1972
- subscriber: {
1973
- cpf: 12,
1974
- email: 12,
1975
- phone: 12,
1976
- card: 12,
1977
- zip: Infinity,
1978
- },
1979
- nonSubscriber: {
1980
- cpf: 7,
1981
- email: 7,
1982
- phone: 7,
1983
- card: 7,
1984
- zip: Infinity,
1985
- },
1986
- };
1987
- this.LIMIT_BLOCKED_ORDERS_DAY = isSubscriber ? 7 : 5;
1988
- }
1989
- getLimitsByUserType(type, isSubscriber) {
1990
- const limits = type === 'day' ? this.LIMIT_ORDERS_DAY : this.LIMIT_ORDERS_WEEK;
1991
- return isSubscriber ? limits['subscriber'] : limits['nonSubscriber'];
2110
+ async loadResolvedLimits() {
2111
+ if (!this.shopConfigsRepository) {
2112
+ return resolveAntifraudVolumeLimits(null);
2113
+ }
2114
+ try {
2115
+ const result = await this.shopConfigsRepository.find({}, { cache: { enabled: true, ttl: ANTIFRAUD_CONFIG_CACHE_TTL_SECONDS } });
2116
+ return resolveAntifraudVolumeLimits(result?.data?.at(0)?.antifraude);
2117
+ }
2118
+ catch (error) {
2119
+ console.warn(JSON.stringify({
2120
+ msg: 'antifraud_card_volume_config_load_failed',
2121
+ source: 'fallback',
2122
+ error: error instanceof Error ? error.message : String(error),
2123
+ }));
2124
+ return resolveAntifraudVolumeLimits(null);
2125
+ }
1992
2126
  }
1993
- async validateBlockedOrderAttempts(checkout, card) {
1994
- const isValid = await this.verifyBlockedOrderAttempts(checkout, card);
2127
+ async validateBlockedOrderAttempts(checkout, card, blockedAttemptsDay) {
2128
+ const isValid = await this.verifyBlockedOrderAttempts(checkout, card, blockedAttemptsDay);
1995
2129
  if (!isValid) {
1996
- throw new FraudValidationError(`Cliente com mais de ${this.LIMIT_BLOCKED_ORDERS_DAY} compras negadas/bloqueadas no dia`, exports.ErrorsCode.fraudPreventionInternal, {
2130
+ throw new FraudValidationError(`Cliente com mais de ${blockedAttemptsDay} compras negadas/bloqueadas no dia`, exports.ErrorsCode.fraudPreventionInternal, {
1997
2131
  checkoutId: checkout.id,
1998
2132
  userEmail: checkout.user.email,
1999
2133
  info: {
@@ -2004,8 +2138,8 @@ class AntifraudCardService {
2004
2138
  });
2005
2139
  }
2006
2140
  }
2007
- async validateDayAndWeekOrderLimits(checkout, card) {
2008
- const isValid = await this.verifyDayAndWeekOrders(checkout, card);
2141
+ async validateDayAndWeekOrderLimits(checkout, card, dayLimits, weekLimits) {
2142
+ const isValid = await this.verifyDayAndWeekOrders(checkout, card, dayLimits, weekLimits);
2009
2143
  if (!isValid) {
2010
2144
  throw new FraudValidationError('Cliente tentando comprar mais do que o permitido no dia/semana', exports.ErrorsCode.fraudPreventionInternal, {
2011
2145
  checkoutId: checkout.id,
@@ -2018,15 +2152,15 @@ class AntifraudCardService {
2018
2152
  });
2019
2153
  }
2020
2154
  }
2021
- async verifyBlockedOrderAttempts(checkout, card) {
2155
+ async verifyBlockedOrderAttempts(checkout, card, blockedAttemptsDay) {
2022
2156
  const dateRange = this.getTodayDateRange();
2023
2157
  const blockedOrders = await this.getBlockedOrdersByMultipleCriteria(checkout, dateRange);
2024
2158
  const totalBlockedAttempts = this.calculateUniqueBlockedAttempts(blockedOrders, checkout);
2025
- if (totalBlockedAttempts >= this.LIMIT_BLOCKED_ORDERS_DAY) {
2159
+ if (totalBlockedAttempts >= blockedAttemptsDay) {
2026
2160
  await this.createBlockedOrderRecord({
2027
2161
  checkout,
2028
2162
  card,
2029
- reason: `More than ${this.LIMIT_BLOCKED_ORDERS_DAY} attempts have failed`,
2163
+ reason: `More than ${blockedAttemptsDay} attempts have failed`,
2030
2164
  key: 'Failed attempts',
2031
2165
  period: 'day',
2032
2166
  });
@@ -2128,12 +2262,12 @@ class AntifraudCardService {
2128
2262
  card,
2129
2263
  });
2130
2264
  }
2131
- async verifyDayAndWeekOrders(checkout, card) {
2265
+ async verifyDayAndWeekOrders(checkout, card, dayLimits, weekLimits) {
2132
2266
  const validationParams = this.buildValidationParams(checkout, card);
2133
- const isDayLimitValid = await this.validateDayOrderLimits(checkout, validationParams);
2267
+ const isDayLimitValid = await this.validateDayOrderLimits(checkout, validationParams, dayLimits);
2134
2268
  if (!isDayLimitValid)
2135
2269
  return false;
2136
- const isWeekLimitValid = await this.validateWeekOrderLimits(checkout, validationParams);
2270
+ const isWeekLimitValid = await this.validateWeekOrderLimits(checkout, validationParams, weekLimits);
2137
2271
  return isWeekLimitValid;
2138
2272
  }
2139
2273
  buildValidationParams(checkout, card) {
@@ -2145,9 +2279,8 @@ class AntifraudCardService {
2145
2279
  card,
2146
2280
  };
2147
2281
  }
2148
- async validateDayOrderLimits(checkout, params) {
2282
+ async validateDayOrderLimits(checkout, params, limits) {
2149
2283
  const ordersPerDay = await this.validateOrdersByRange(params, this.getDateRange('day'));
2150
- const limits = this.getLimitsByUserType('day', checkout.user.isSubscriber);
2151
2284
  return this.checkOrderLimitsAndBlock({
2152
2285
  checkout,
2153
2286
  orderCounts: ordersPerDay,
@@ -2155,9 +2288,8 @@ class AntifraudCardService {
2155
2288
  period: 'day',
2156
2289
  });
2157
2290
  }
2158
- async validateWeekOrderLimits(checkout, params) {
2291
+ async validateWeekOrderLimits(checkout, params, limits) {
2159
2292
  const ordersPerWeek = await this.validateOrdersByRange(params, this.getDateRange('week'));
2160
- const limits = this.getLimitsByUserType('week', checkout.user.isSubscriber);
2161
2293
  return this.checkOrderLimitsAndBlock({
2162
2294
  checkout,
2163
2295
  orderCounts: ordersPerWeek,
@@ -2234,15 +2366,35 @@ class AntifraudCardService {
2234
2366
  }
2235
2367
 
2236
2368
  class AntifraudGlampointsService {
2237
- constructor() { }
2238
- async validate(_checkout) {
2369
+ constructor(shopConfigsRepository) {
2370
+ this.shopConfigsRepository = shopConfigsRepository;
2371
+ }
2372
+ async validate(checkout) {
2373
+ const enabled = await isAntifraudEnabled(this.shopConfigsRepository);
2374
+ if (!enabled) {
2375
+ console.info(JSON.stringify({
2376
+ msg: 'antifraud_glampoints_skipped',
2377
+ enabled: false,
2378
+ checkoutId: checkout.id,
2379
+ }));
2380
+ }
2239
2381
  return true;
2240
2382
  }
2241
2383
  }
2242
2384
 
2243
2385
  class AntifraudPixService {
2244
- constructor() { }
2245
- async validate(_checkout) {
2386
+ constructor(shopConfigsRepository) {
2387
+ this.shopConfigsRepository = shopConfigsRepository;
2388
+ }
2389
+ async validate(checkout) {
2390
+ const enabled = await isAntifraudEnabled(this.shopConfigsRepository);
2391
+ if (!enabled) {
2392
+ console.info(JSON.stringify({
2393
+ msg: 'antifraud_pix_skipped',
2394
+ enabled: false,
2395
+ checkoutId: checkout.id,
2396
+ }));
2397
+ }
2246
2398
  return true;
2247
2399
  }
2248
2400
  }
@@ -2596,6 +2748,26 @@ class ShopSettings extends BaseModel {
2596
2748
  }
2597
2749
  }
2598
2750
 
2751
+ /**
2752
+ * Defaults iguais ao hardcode histórico do checkout.
2753
+ * `week.*.zip = null` → Infinity no runtime do volume de cartão.
2754
+ */
2755
+ const DEFAULT_SHOP_ANTIFRAUD_CONFIG = {
2756
+ enabled: true,
2757
+ day: {
2758
+ subscriber: { cpf: 4, email: 4, phone: 4, card: 4, zip: 4 },
2759
+ nonSubscriber: { cpf: 2, email: 2, phone: 2, card: 2, zip: 2 },
2760
+ },
2761
+ week: {
2762
+ subscriber: { cpf: 12, email: 12, phone: 12, card: 12, zip: null },
2763
+ nonSubscriber: { cpf: 7, email: 7, phone: 7, card: 7, zip: null },
2764
+ },
2765
+ blockedAttemptsDay: {
2766
+ subscriber: 7,
2767
+ nonSubscriber: 5,
2768
+ },
2769
+ };
2770
+
2599
2771
  class AdyenBlockedOrderHelper {
2600
2772
  static async handleUnauthorizedPayment(params) {
2601
2773
  await params.orderBlockedRepository.createBlockedOrderOrPayment({
@@ -2720,11 +2892,39 @@ class AdyenCardAxiosAdapter {
2720
2892
  }
2721
2893
  }
2722
2894
 
2895
+ function resolveCacheConfig(cache) {
2896
+ if (lodash.isNil(cache) || typeof cache !== 'object')
2897
+ return undefined;
2898
+ const candidate = cache;
2899
+ const cacheAdapter = candidate.cacheAdapter;
2900
+ if (!cacheAdapter)
2901
+ return undefined;
2902
+ if (!isCacheAdapter(cacheAdapter))
2903
+ return undefined;
2904
+ if (typeof cacheAdapter.isConfigured === 'function' && !cacheAdapter.isConfigured()) {
2905
+ return undefined;
2906
+ }
2907
+ return {
2908
+ cacheAdapter,
2909
+ ttlDefault: candidate.ttlDefault,
2910
+ };
2911
+ }
2912
+ function isCacheAdapter(adapter) {
2913
+ return (typeof adapter.get === 'function' &&
2914
+ typeof adapter.set === 'function' &&
2915
+ typeof adapter.remove === 'function' &&
2916
+ typeof adapter.clear === 'function');
2917
+ }
2918
+
2723
2919
  class RestCacheAdapter {
2724
2920
  constructor(config) {
2921
+ this.client = null;
2725
2922
  this.logger = new DebugHelper('RestCacheAdapter');
2923
+ this.configured = this.isValidBaseURL(config.baseURL);
2924
+ if (!this.configured)
2925
+ return;
2726
2926
  this.client = axios__default["default"].create({
2727
- baseURL: config.baseURL,
2927
+ baseURL: config.baseURL.trim(),
2728
2928
  headers: {
2729
2929
  'Content-Type': 'application/json',
2730
2930
  ...(lodash.isNil(config.authToken) ? {} : { Authorization: `Bearer ${config.authToken}` }),
@@ -2732,7 +2932,12 @@ class RestCacheAdapter {
2732
2932
  },
2733
2933
  });
2734
2934
  }
2935
+ isConfigured() {
2936
+ return this.configured;
2937
+ }
2735
2938
  async set(options) {
2939
+ if (!this.client)
2940
+ return false;
2736
2941
  try {
2737
2942
  const response = await this.client.post('/redis/set', {
2738
2943
  key: options.key,
@@ -2748,6 +2953,8 @@ class RestCacheAdapter {
2748
2953
  }
2749
2954
  }
2750
2955
  async get(key) {
2956
+ if (!this.client)
2957
+ return null;
2751
2958
  try {
2752
2959
  const response = await this.client.post('/redis/get', {
2753
2960
  key,
@@ -2764,6 +2971,8 @@ class RestCacheAdapter {
2764
2971
  }
2765
2972
  }
2766
2973
  async remove(key) {
2974
+ if (!this.client)
2975
+ return false;
2767
2976
  try {
2768
2977
  const response = await this.client.post('/redis/del', {
2769
2978
  key,
@@ -2777,6 +2986,8 @@ class RestCacheAdapter {
2777
2986
  }
2778
2987
  }
2779
2988
  async clear() {
2989
+ if (!this.client)
2990
+ return false;
2780
2991
  try {
2781
2992
  const response = await this.client.post('/redis/flushdb', {});
2782
2993
  return response.data.success;
@@ -2787,6 +2998,9 @@ class RestCacheAdapter {
2787
2998
  return false;
2788
2999
  }
2789
3000
  }
3001
+ isValidBaseURL(baseURL) {
3002
+ return lodash.isString(baseURL) && baseURL.trim().length > 0;
3003
+ }
2790
3004
  }
2791
3005
 
2792
3006
  class AxiosAdapter {
@@ -5437,7 +5651,7 @@ class CampaignHashtagFirestoreRepository extends withCrudFirestore(withHelpers(w
5437
5651
  constructor({ firestore, interceptors, cache, }) {
5438
5652
  super({
5439
5653
  firestore,
5440
- collectionName: 'hashtagCampaignsAuto',
5654
+ collectionName: 'CampaignsHashtags',
5441
5655
  model: CampaignHashtag,
5442
5656
  interceptors,
5443
5657
  cache,
@@ -5445,6 +5659,18 @@ class CampaignHashtagFirestoreRepository extends withCrudFirestore(withHelpers(w
5445
5659
  }
5446
5660
  }
5447
5661
 
5662
+ class CampaignHashtagPostsFirestoreRepository extends withCrudFirestore(withHelpers(withFirestore(Base))) {
5663
+ constructor({ firestore, interceptors, cache, }) {
5664
+ super({
5665
+ firestore,
5666
+ collectionName: 'CampaignsHashtagsPosts',
5667
+ model: CampaignHashtagPosts,
5668
+ interceptors,
5669
+ cache,
5670
+ });
5671
+ }
5672
+ }
5673
+
5448
5674
  class CheckoutFirestoreRepository extends withCrudFirestore(withHelpers(withFirestore(Base))) {
5449
5675
  constructor({ firestore, interceptors, cache, }) {
5450
5676
  super({
@@ -6133,7 +6359,7 @@ function createHasuraGraphQLClass(MixinBase) {
6133
6359
  this.model = options.model;
6134
6360
  this.fields = options.fields || this.model.identifiersFields;
6135
6361
  this.logger = DebugHelper.from(this);
6136
- this.cache = options.cache;
6362
+ this.cache = resolveCacheConfig(options.cache);
6137
6363
  }
6138
6364
  get headers() {
6139
6365
  return HasuraAuthHelper.buildHeaders(this.authOptions);
@@ -11130,9 +11356,9 @@ class PagarmeV5BaseAxiosAdapter {
11130
11356
  }
11131
11357
  async refund(order, amount) {
11132
11358
  try {
11133
- console.warn('[PAGARME REFUND] Starting refund process for order', order.id, order.payment, 'with amount', amount);
11134
- const amountToSend = +amount.toFixed(2) * 100;
11135
- console.warn('[PAGARME REFUND] Amount to send in cents', amountToSend);
11359
+ console.warn('[PAGARME REFUND] Starting refund process for order', order.id, order.payment.payment_method, order.payment.amount, 'to refund with amount', amount);
11360
+ const amountInCents = toCents(amount);
11361
+ console.warn('[PAGARME REFUND] Amount to send in cents', amountInCents);
11136
11362
  const { data } = await axios__default["default"]({
11137
11363
  method: 'DELETE',
11138
11364
  url: `${this.credentials.URL}/charges/${order.payment.charger_id}`,
@@ -11141,7 +11367,7 @@ class PagarmeV5BaseAxiosAdapter {
11141
11367
  'Content-Type': 'application/json',
11142
11368
  },
11143
11369
  data: {
11144
- amount: amountToSend,
11370
+ amount: amountInCents,
11145
11371
  },
11146
11372
  });
11147
11373
  console.warn('[RESPONSE PAGARME REFUND]', JSON.stringify(data));
@@ -11157,7 +11383,13 @@ class PagarmeV5BaseAxiosAdapter {
11157
11383
  });
11158
11384
  return {
11159
11385
  status: this.getRefundStatus(data.status),
11160
- success: [exports.PagarMeV5OrderStatus.Pago, exports.PagarMeV5OrderStatus.Cancelado].includes(data.status) ? true : false,
11386
+ success: [
11387
+ exports.PagarMeV5OrderStatus.Pago,
11388
+ exports.PagarMeV5OrderStatus.Cancelado,
11389
+ exports.PagarMeV5PaymentStatus['Em processamento'],
11390
+ ].includes(data.status)
11391
+ ? true
11392
+ : false,
11161
11393
  };
11162
11394
  }
11163
11395
  catch (error) {
@@ -11672,6 +11904,7 @@ Object.defineProperty(exports, 'unset', {
11672
11904
  enumerable: true,
11673
11905
  get: function () { return lodash.unset; }
11674
11906
  });
11907
+ exports.ANTIFRAUD_CONFIG_CACHE_TTL_SECONDS = ANTIFRAUD_CONFIG_CACHE_TTL_SECONDS;
11675
11908
  exports.Address = Address;
11676
11909
  exports.AdyenCardAxiosAdapter = AdyenCardAxiosAdapter;
11677
11910
  exports.AdyenPaymentMethodFactory = AdyenPaymentMethodFactory;
@@ -11698,6 +11931,8 @@ exports.CampaignDashboard = CampaignDashboard;
11698
11931
  exports.CampaignDashboardFirestoreRepository = CampaignDashboardFirestoreRepository;
11699
11932
  exports.CampaignHashtag = CampaignHashtag;
11700
11933
  exports.CampaignHashtagFirestoreRepository = CampaignHashtagFirestoreRepository;
11934
+ exports.CampaignHashtagPosts = CampaignHashtagPosts;
11935
+ exports.CampaignHashtagPostsFirestoreRepository = CampaignHashtagPostsFirestoreRepository;
11701
11936
  exports.Category = Category;
11702
11937
  exports.CategoryCollectionChildren = CategoryCollectionChildren;
11703
11938
  exports.CategoryCollectionChildrenHasuraGraphQLRepository = CategoryCollectionChildrenHasuraGraphQLRepository;
@@ -11719,6 +11954,8 @@ exports.ConnectDocumentService = ConnectDocumentService;
11719
11954
  exports.ConnectFirestoreService = ConnectFirestoreService;
11720
11955
  exports.Coupon = Coupon;
11721
11956
  exports.CouponFirestoreRepository = CouponFirestoreRepository;
11957
+ exports.DEFAULT_ANTIFRAUD_VOLUME_LIMITS = DEFAULT_ANTIFRAUD_VOLUME_LIMITS;
11958
+ exports.DEFAULT_SHOP_ANTIFRAUD_CONFIG = DEFAULT_SHOP_ANTIFRAUD_CONFIG;
11722
11959
  exports.Debug = Debug;
11723
11960
  exports.DebugDecoratorHelper = DebugDecoratorHelper;
11724
11961
  exports.DebugHelper = DebugHelper;
@@ -11855,12 +12092,16 @@ exports.WishlistHasuraGraphQLRepository = WishlistHasuraGraphQLRepository;
11855
12092
  exports.deserialize = deserialize;
11856
12093
  exports.getClass = getClass;
11857
12094
  exports.is = is;
12095
+ exports.isAntifraudEnabled = isAntifraudEnabled;
11858
12096
  exports.isDebuggable = isDebuggable;
11859
12097
  exports.isUUID = isUUID;
11860
12098
  exports.parseDateTime = parseDateTime;
11861
12099
  exports.registerClass = registerClass;
12100
+ exports.resolveAntifraudVolumeLimits = resolveAntifraudVolumeLimits;
12101
+ exports.resolveCacheConfig = resolveCacheConfig;
11862
12102
  exports.resolveClass = resolveClass;
11863
12103
  exports.serialize = serialize;
12104
+ exports.toCents = toCents;
11864
12105
  exports.withCreateFirestore = withCreateFirestore;
11865
12106
  exports.withCreateHasuraGraphQL = withCreateHasuraGraphQL;
11866
12107
  exports.withCrudFirestore = withCrudFirestore;