RecomNext

Scenarios

A scenario is a named placement (slug) that bundles logic type, algorithm, nextQL filters and boosters, constraints, segmentation, and optional rule references. Fetch recommendations with the scenario slug to apply the full config at request time.

Logic types (use cases)
SettingTypeDefaultDescription
user-to-itemlogicTypeHomepage “For you”, personalized rails. Requires userId.
item-to-itemlogicTypePDP related (co-occurrence). Requires itemId.
similar-productslogicTypeVector similarity on PDP. Requires itemId + embeddings.
items-to-itemslogicTypeCart upsell from multiple seeds. Requires itemIds.
recently-viewedlogicTypeContinue browsing. Requires userId.
Algorithm registry

algorithm selects the scoring implementation. If omitted, the default for the logic type is used. Response includes algorithm for debugging and A/B analysis.

SettingTypeDefaultDescription
weighted-historyuser-to-itemdefault30d weighted interactions + popularity fallback.
co-occurrenceitem-to-itemdefaultCo-interaction matrix + category fallback.
vector-similaritysimilar-productsdefaultQdrant nearest neighbors.
multi-seed-co-occurrenceitems-to-itemsdefaultCart co-occurrence across seeds.
multi-seed-hybriditems-to-itemsRRF fusion of co-occurrence + vectors.
elsa-cfuser-to-item, item-to-itemRequires offline trained factors.
realm-sequentialuser-to-itemSession sequential model (offline).
beeformer-multimodalsimilar-productsText + image embeddings (offline).

List options: GET /recommendations/algorithms andGET /recommendations/algorithms/:logicType.

Scenario settings
SettingTypeDefaultDescription
slugstringStable URL-safe ID used in API and tracking.
filternextQLHard filter applied to candidates.
boostersstring[]Score multipliers: boost by N where condition.
rulesSlugsstring[]Reusable rules merged before scenario filter.
segmentationIdstringDiversity balancing config.
itemsPerSegmentnumberMax items per segment in results.
minItems / maxItemsnumber6 / 12Auto-fill and cap on count.
autoRelaxConstraintsbooleantrueRelax diversity when below minItems.
autoRelaxFiltersbooleanfalseIf filter matches nothing, drop clauses right→left (opt-in). Put durable constraints on the left.
relaxEntireFilterOnEmptybooleanfalseIf filter auto-relax still empty, drop the whole filter (opt-in).
autoExpandSegmentsbooleantrueIncrease per-segment slots when below minItems.
Query planning for filter auto-relax

Use when enabling autoRelaxFilters (and optionally relaxEntireFilterOnEmpty). Both default off — existing scenarios are unchanged until you opt in.

When to enable

Turn autoRelaxFilters on for merchandising filters where an empty shelf is worse than dropping soft clauses. Leave off for hard policy / compliance filters. TurnrelaxEntireFilterOnEmpty on only when showing unfiltered candidates is acceptable after soft clauses are exhausted.

Core authoring rule

Clauses drop from right to left when the full filter matches nothing. Put must-keep constraints on the left; nice-to-have on the right. Linked filter rules sit left of the scenario filter (highest rule priority first). Soft scenario clauses on the right drop before sticky rules.

Use case
AND chain

'allowed_countries' contains 'IN' and 'type' = 'game' and 'price' < 20— if nothing is under 20, price drops first; then type; countries last among these.

Use case
OR / groups

Put soft bands in the right group. Prefer clear AND + rightmost soft clauses when intent is “durable then soft.” Do not rely on OR arms as priority.

Response field (filterRelaxation)

When relaxation changes the filter, the API may return droppedClauses,effectiveFilter (null only if the entire filter was dropped),droppedEntireFilter, and originalFilter. UX idea: “Showing results without price filter.”

Contrast with constraint auto-relax

autoRelaxFilters triggers when the filter matched zero candidates.autoRelaxConstraints triggers when results are below minItems after ranking (diversity / freshness). Different knobs.

Checklist before save

(1) Left = durable; right = soft. (2) Rule priorities intentional. (3) Policy B on only if unfiltered fallback is OK. (4) Validate with Admin Try-it.

Constraints
SettingTypeDefaultDescription
maxPerCategorynumberDiversity cap per category in result set.
injectLongTailbooleanfalseInject low-exposure items.
longTailPercentage0–10010Share of slots for long-tail when injectLongTail true.
freshnessBoostDaysnumberBoost items within N days of freshness date.
purchasedItemsMaxPercent0–10010Cap already-purchased items; pass userId at fetch.
Use case
Homepage diversity

maxPerCategory: 2 with segmentation by genre prevents one genre dominating the carousel.

Use case
Cart — hide already purchased

Pass userId on cart upsell fetch with purchasedItemsMaxPercent: 5.

Vector tuning (qdrantSettings)

Used by vector-similarity and hybrid algorithms.

SettingTypeDefaultDescription
score_thresholdnumberMinimum similarity score for candidates.
hnsw_efnumberSearch accuracy vs latency tradeoff.
filter_categoriesstring[]Restrict vector search to categories.
exactbooleanExact search mode (slower, more accurate).
Hybrid tuning (hybridSettings)

For multi-seed-hybrid on cart-style placements.

SettingTypeDefaultDescription
strategyrrf | centroid | adaptiverrfHow multiple seeds fuse.
rrfKnumberRRF smoothing constant.
coTopK / vectorTopKnumberCandidate pool sizes per signal.
categoryBoostnumberMultiplier when candidate category matches a seed.
minCoSupportnumberMinimum seed support for co-occurrence candidates.
enabledbooleanScenario-level hybrid kill switch.
Processing order

Algorithm candidates → rule filters → scenario filter → rule + scenario boosters → constraints → segment balancing → min/max auto-fill.

Per-request filter overrides are not supported on the unified API — tune via scenarios, rules, or multiple scenarios for preset filter combinations.

Full scenario example
POST /scenarios
{
  "name": "PDP — Similar PC games",
  "slug": "pdp-similar-pc",
  "logicType": "similar-products",
  "algorithm": "vector-similarity",
  "filter": "'stock' > 0 and 'platform' in ['pc', 'multi']",
  "boosters": [
    "boost by 1.4 where 'featured' = true",
    "boost by 1.2 where 'genre' in ['rpg', 'action']"
  ],
  "constraints": {
    "maxPerCategory": 2,
    "injectLongTail": true,
    "longTailPercentage": 15,
    "freshnessBoostDays": 14,
    "purchasedItemsMaxPercent": 10
  },
  "qdrantSettings": {
    "score_threshold": 0.35
  },
  "segmentationId": "by-genre",
  "itemsPerSegment": 1,
  "minItems": 6,
  "maxItems": 12,
  "rulesSlugs": ["in-stock"],
  "autoRelaxConstraints": true,
  "autoExpandSegments": true
}
Experiments

Attach an A/B experiment to a scenario: variants point to different scenario slugs (e.g. control vs boosted). Assignment uses userId at fetch time. See Analytics and experiments.