@riocrypto/common-server 1.0.2911 → 1.0.2912

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.
@@ -28,8 +28,10 @@ const pickByShare = (candidates, position) => {
28
28
  // the only one available to them, which is why the candidate set comes from the
29
29
  // corridor rather than from the rule. What keeps an order away from a rail is the
30
30
  // customer, by switching it off or, while that direction is opt-in, by never
31
- // turning it on. Unless the rule says otherwise: a split set to apply to all
32
- // users divides the corridor by percentage alone and asks nobody.
31
+ // turning it on. Two exceptions: a split set to apply to all users divides the
32
+ // corridor by percentage alone and asks nobody, and a corridor the customer has
33
+ // no answer on record for at all is one they were never asked about, so silence
34
+ // there is not read as a refusal.
33
35
  //
34
36
  // Does no IO of its own - the routing config and the user's enablement are passed
35
37
  // in - and the only nondeterminism is the per-order roll, which a caller can
@@ -118,13 +120,24 @@ const resolveProcessor = ({ country, fiat, purpose, routingConfig, excludedProce
118
120
  const isGated = purpose !== common_1.ProcessorRoutingPurpose.BankAccountVerification;
119
121
  const disabled = isGated ? (enablement === null || enablement === void 0 ? void 0 : enablement.disabled) || [] : [];
120
122
  const unset = isGated && requireExplicitEnablement ? (enablement === null || enablement === void 0 ? void 0 : enablement.unset) || [] : [];
123
+ // Silence only means no in a corridor the customer has actually been asked
124
+ // about. Accounts are seeded and shown for the country they onboarded in, while
125
+ // a quote may name any corridor, so a corridor with nothing at all on record is
126
+ // one nobody has ever offered them rather than one they turned down. Refusing
127
+ // there would refuse a price over an account the customer has no page to go and
128
+ // turn on, so the gate stands down and the corridor routes as it did before
129
+ // opt-in. Anything they have answered, in either direction, puts the gate back.
130
+ const wasAsked = Boolean(enablement && (enablement.enabled.length || enablement.disabled.length));
121
131
  // Recorded either way, and only acted on when the split leaves the choice with
122
132
  // the customer. An order routed over their objection is the one that will be
123
133
  // asked about later, so what they had said needs to survive on the decision.
124
134
  const enablementOverridden = isGated && Boolean(rule === null || rule === void 0 ? void 0 : rule.appliesToAllUsers);
135
+ // Both sets are still reported below whether or not they were acted on, so a
136
+ // decision that routed past unspoken rails can be told from one that had none.
137
+ const gatedUnset = wasAsked ? unset : [];
125
138
  const candidates = enablementOverridden
126
139
  ? eligible
127
- : eligible.filter((processor) => !disabled.includes(processor) && !unset.includes(processor));
140
+ : eligible.filter((processor) => !disabled.includes(processor) && !gatedUnset.includes(processor));
128
141
  // What was filtered, carried by every decision below. Kept in one place so a
129
142
  // branch cannot quietly stop reporting one of them, since these sets are the
130
143
  // whole reason a decision can still be explained weeks later.
@@ -136,7 +149,7 @@ const resolveProcessor = ({ country, fiat, purpose, routingConfig, excludedProce
136
149
  // their rails off and can turn one back on; the other has never told us
137
150
  // which account their bank will let them pay, and needs to whitelist one
138
151
  // before anything can be routed.
139
- reason: unset.length
152
+ reason: gatedUnset.length
140
153
  ? common_1.RoutingDecisionReason.NoAcceptedCandidate
141
154
  : common_1.RoutingDecisionReason.NoEnabledCandidate }, filtered), { decidedAt });
142
155
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@riocrypto/common-server",
3
- "version": "1.0.2911",
3
+ "version": "1.0.2912",
4
4
  "description": "",
5
5
  "main": "./build/index.js",
6
6
  "types": "./build/index.d.ts",