juspay / juspay/decision-engine
feat(feedback): support gateway scoring updates for Rule-Based routing in update-gateway-score API
- Dominant language
- Rust
- Stars
- 128
- Forks
- 36
- Avg merge
- 1d 15h
- Merged PRs (30d)
- 34
Description
## Context
The `update-gateway-score` API (`POST /update-gateway-score`) is the feedback channel used by callers to let the decision engine know the outcome of a transaction so that gateway scores can be updated. Today this flow is heavily biased toward the SR-based routing path.
Relevant entry points:
- Handler: [`src/routes/update_gateway_score.rs`](src/routes/update_gateway_score.rs)
- Core scoring logic: `update_gateway_score` in [`src/feedback/gateway_scoring_service.rs`](src/feedback/gateway_scoring_service.rs) (around L566)
Inside `update_gateway_score`, the routing approach is read from transaction metadata via `get_routing_approach` and then compared using two substring helpers:
```rust
// gateway_scoring_service.rs
pub fn is_routing_approach_in_srv3(maybe_text: Option) -> bool {
match maybe_text {
Some(text) => text.contains(\"V3\"),
None => false,
}
}
pub fn is_routing_approach_in_explore(maybe_text: Option) -> bool {
match maybe_text {
Some(text) => text.contains(\"HEDGING\"),
None => false,
}
}
```
These gate `should_isolate_srv3_producer` and `should_update_explore_txn`, which in turn control whether `GatewayScoringData` is loaded from Redis and used to update scores.
However, the `GatewayDeciderApproach` enum in `src/decider/gatewaydecider/types.rs` has many non-SR variants that callers legitimately use, notably:
- `PriorityLogic` (i.e. rule-based / Euclid routing)
- `NtwBasedRouting`
- `MerchantPreference`
- `Default`
When routing was done via `PRIORITY_LOGIC` (rule-based), the routing approach string does not contain `V3` or `HEDGING`, so the scoring pipeline short-circuits and no score updates are applied for the selected gateway. Merchants using rule-based routing therefore get no benefit from the feedback loop, and gateway health signals collected via `update-gateway-score` are silently dropped.
## Motivation
- Rule-based routing is a first-class routing strategy in the decision engine (see the `Rule-Based (Euclid)` entry in the dashboard sidebar and the `EuclidRulesPage`).
- Gateway scores (SR / elimination / latency) are useful regardless of how the gateway was originally selected — the score reflects the health of the gateway, not the selector that picked it.
- Users reasonably expect that if they hit `/update-gateway-score` with a successful or failed transaction, the engine will update its view of that gateway's health.
## Proposal
1. Decouple \"which scoring dimensions to update\" from \"which routing approach selected this txn\". Scoring updates should run whenever the caller hits `update-gateway-score`, independent of whether the original decision came from SR, rule-based, network-based, or merchant-preference routing.
2. Replace the substring checks (`contains(\"V3\")`, `contains(\"HEDGING\")`) with explicit matches on `GatewayDeciderApproach` variants where gating is truly needed (e.g. SRv3-producer isolation should check `SrSelectionV3Routing` / `SrV3*` variants explicitly).
3. For rule-based routing specifically, ensure `should_update_gateway_score` and SRv3 score updates are allowed so that the Redis `GatewayScoringData` is read and scores (SR, elimination, latency) are updated.
4. Add unit/integration tests that call `update-gateway-score` for a transaction originally routed via `PRIORITY_LOGIC` and assert that the expected Redis keys are updated.
## Acceptance Criteria
- [ ] `update-gateway-score` updates gateway scores for transactions whose `routing_approach` is `PRIORITY_LOGIC` (rule-based), not just SR-based variants.
- [ ] Substring-based routing approach checks in `gateway_scoring_service.rs` are replaced with explicit enum matches (or a well-documented helper) so the gating is type-safe.
- [ ] Existing SR-based flows (`SrSelectionV3Routing`, `SrV3Hedging`, etc.) continue to behave identically — no regression in SRv3 producer isolation or explore/exploit behavior.
- [ ] Tests cover at least: (a) success txn via rule-based routing → gateway score rewarded, (b) failure txn via rule-based routing → gateway score penalised, (c) SRv3 txn unchanged.
- [ ] Docs for the `update-gateway-score` endpoint (`docs/api-reference/endpoint/updateGatewayScore.mdx`) note that all routing approaches are supported.
Contributor guide
Assessment
This issue has not been assessed yet.