@riocrypto/common-server 1.0.2922 → 1.0.2924

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.
@@ -24,7 +24,12 @@ const pickByShare = (candidates, position) => {
24
24
  // from the configured split.
25
25
  //
26
26
  // A percentage divides volume between the rails that are actually available to
27
- // the customer; it is not a switch. A rail left at zero, left out of the rule, or
27
+ // the customer; it is not a switch. On a scheduled corridor the percentages are
28
+ // whichever window covers the current minute where that corridor banks, so the
29
+ // same order placed two hours later can be divided differently. Everything below
30
+ // that point is indifferent to where the shares came from.
31
+ //
32
+ // A rail left at zero, left out of the rule, or
28
33
  // belonging to a corridor with no rule at all still takes their orders when it is
29
34
  // the only one available to them, which is why the candidate set comes from the
30
35
  // corridor rather than from the rule. What keeps an order away from a rail is the
@@ -96,6 +101,11 @@ const resolveProcessor = ({ country, fiat, purpose, routingConfig, excludedProce
96
101
  // ruleless until an admin first saves one - as is any corridor whose shares
97
102
  // were all cleared, since the settings page stores that as no rule at all.
98
103
  const rule = getRule(routingConfig, country, fiat, purpose);
104
+ // The split in force at this instant, which on a scheduled corridor depends on
105
+ // what time it is where the corridor banks. Resolved from `decidedAt` so the
106
+ // shares, the window and the timestamp recorded on the decision can never end
107
+ // up describing different minutes.
108
+ const { percentages: configuredPercentages, matchedWindow } = (0, common_1.resolveProcessorRoutingPercentages)(rule, country, fiat, purpose, decidedAt);
99
109
  // Starts from the corridor's rails rather than from the rails the rule names,
100
110
  // because a percentage decides how volume is divided between the rails a
101
111
  // customer can use - it is not what makes a rail usable. Also drops any share
@@ -139,11 +149,21 @@ const resolveProcessor = ({ country, fiat, purpose, routingConfig, excludedProce
139
149
  const candidates = enablementOverridden
140
150
  ? eligible
141
151
  : eligible.filter((processor) => !disabled.includes(processor) && !gatedUnset.includes(processor));
142
- // What was filtered, carried by every decision below. Kept in one place so a
143
- // branch cannot quietly stop reporting one of them, since these sets are the
144
- // whole reason a decision can still be explained weeks later.
145
- const filtered = Object.assign({ corridor, excluded: excludedProcessors, disabled,
146
- unset }, (enablementOverridden ? { enablementOverridden: true } : {}));
152
+ // What was filtered and which window the shares came from, carried by every
153
+ // decision below. Kept in one place so a branch cannot quietly stop reporting
154
+ // one of them, since this is the whole reason a decision can still be explained
155
+ // weeks later. The window is recorded even on the refusals, because "the
156
+ // afternoon window gave Fintoc everything and this customer has Fintoc off" is
157
+ // the shape of the question that gets asked.
158
+ const filtered = Object.assign(Object.assign({ corridor, excluded: excludedProcessors, disabled,
159
+ unset }, (enablementOverridden ? { enablementOverridden: true } : {})), (matchedWindow
160
+ ? {
161
+ window: {
162
+ startMinute: matchedWindow.startMinute,
163
+ endMinute: matchedWindow.endMinute,
164
+ },
165
+ }
166
+ : {}));
147
167
  if (!candidates.length) {
148
168
  return Object.assign(Object.assign({
149
169
  // Told apart because they are different conversations. One customer turned
@@ -155,13 +175,10 @@ const resolveProcessor = ({ country, fiat, purpose, routingConfig, excludedProce
155
175
  : common_1.RoutingDecisionReason.NoEnabledCandidate }, filtered), { decidedAt });
156
176
  }
157
177
  const shares = candidates
158
- .map((processor) => {
159
- var _a;
160
- return ({
161
- processor,
162
- percentage: Number((_a = rule === null || rule === void 0 ? void 0 : rule.percentages) === null || _a === void 0 ? void 0 : _a[processor]) || 0,
163
- });
164
- })
178
+ .map((processor) => ({
179
+ processor,
180
+ percentage: Number(configuredPercentages[processor]) || 0,
181
+ }))
165
182
  .filter((candidate) => candidate.percentage > 0);
166
183
  const percentages = Object.fromEntries(shares.map((share) => [share.processor, share.percentage]));
167
184
  // None of the rails this customer can use carries a share - or no rule is
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@riocrypto/common-server",
3
- "version": "1.0.2922",
3
+ "version": "1.0.2924",
4
4
  "description": "",
5
5
  "main": "./build/index.js",
6
6
  "types": "./build/index.d.ts",
@@ -28,7 +28,7 @@
28
28
  "@google-cloud/secret-manager": "^5.6.0",
29
29
  "@google-cloud/storage": "^7.19.0",
30
30
  "@hyperdx/node-opentelemetry": "^0.10.3",
31
- "@riocrypto/common": "1.0.2720",
31
+ "@riocrypto/common": "1.0.2722",
32
32
  "@slack/web-api": "^7.15.0",
33
33
  "@types/express": "^4.17.25",
34
34
  "axios": "1.18.1",