The gamification platform is an event-driven runtime for reward-bearing customer journeys that must not sit on the payments critical path. It consumes events, evaluates eligibility, progresses users through linear milestone journeys, and orchestrates NeuCoin/voucher rewards asynchronously. PostgreSQL is the authoritative store; Redis holds projection caches; Confluent Cloud Kafka is the streaming platform.
Phase 1 delivers a JSON-configured, count-based milestone game using a single archetype NUMERIC_COUNTER. UPI and FS events both drive the same numeric counter via config-defined triggers. The design keeps the hot path short and deterministic, while the config and event models are extensible to future gamification archetypes (amount, category, checklist, streak, daily grid).
Progress drivers
payment_success events with transaction_type = "UPI" (UPI to anybody on Tata Neu).fs_action_complete events for selected FS actions (e.g., credit card apply, loan enquiry, insurance purchase, bill payments - these would be sub categories).Game archetype and progression
NUMERIC_COUNTER – numeric progress state (count) with linear steps 1 -> 2 -> … -> N.REWARD, EMPTY, or FORTUNE_COOKIE (Fortune Cookie is data-model-ready in P1; UI can ship later).visibility: visible|hidden and display_type: flat|upto.Config/runtime
Cohorts & eligibility
cohort_id.Rewards
The system consists of four main layers:
External Systems:
Event Streaming:
Gamification Runtime:
Data Layer:
Client:
Key decisions:
NUMERIC_COUNTER is supported in P1 with typed triggers; there is no generic rule engine in the hot path.Note: DB schemas are WIP and will be derived from these JSON models; JSON is the primary configuration contract.
Top-level fields:
schema_version – config schema version.game_id – unique game identifier.game_archetype – "NUMERIC_COUNTER" in P1.cohort_id – Viduur/LaunchDarkly segment key; only cohort field in config.game_window – { start, end, type } (monthly/quarterly).progress_state_model – numeric state representation.milestone_steps[] – ladder with step types and rewards.triggers[] – declarative triggers over canonical event attributes.{
"schema_version": "1.0",
"game_id": "upi_fs_milestone_may_2026",
"game_archetype": "NUMERIC_COUNTER",
"cohort_id": "viduur_segment_upi_fs_early_lifecycle",
"game_window": {
"start": "2026-05-01T00:00:00Z",
"end": "2026-05-31T23:59:59Z",
"type": "monthly"
},
// this would vary per game archetype in future
// mapped to each game strategy (numeric counter for now)
"progress_state_model": {
"type": "numeric_counter",
"unit": "count",
"display_unit": "transactions",
"max_value": 12
},
"milestone_steps": [
{ "step": 3, "step_type": "REWARD",
"reward": {
"reward_type": "NC",
"value": 10,
"visibility": "visible",
"display_type": "flat"
}
},
{ "step": 6, "step_type": "REWARD",
"reward": {
"reward_type": "NC",
"value": 30,
"visibility": "hidden",
"display_type": "upto"
}
},
{ "step": 12, "step_type": "REWARD",
"reward": {
"reward_type": "NC",
"value": 100,
"visibility": "visible",
"display_type": "flat"
}
}
],
"triggers": [
{
"trigger_id": "upi_plus_one",
"event_type": "payment_success",
"rule": {
"operator": "and",
"conditions": [
{ "field": "attributes.payment_status", "op": "eq", "value": "SUCCESS" },
{ "field": "attributes.transaction_type", "op": "eq", "value": "UPI" },
{ "field": "attributes.transaction_amount", "op": "gte", "value": 1200 }
]
},
"progression_config": {
"mode": "increment_by_constant",
"value": 1
}
},
{
"trigger_id": "fs_plus_three",
"event_type": "fs_action_complete",
"rule": {
"operator": "and",
"conditions": [
{ "field": "attributes.action_type", "op": "eq", "value": "CREDIT_CARD_APPLY" }
]
},
"progression_config": {
// this config will vary for future games to increment by attribute fields such as .attributes.txn_amount
"mode": "increment_by_constant",
"value": 3
}
}
]
}
FS cross-sell is just another trigger (higher value) on FS events, not a separate skip/config block. This scales naturally to more FS actions or other event types.
game_config_version based on occurred_at (event-time version resolution).The Normalisation Layer:
event_id, user_id, occurred_at, event type, key attributes).{
"event_id": "evt_pay_001",
"event_type": "payment_success",
"event_version": "1.0",
"occurred_at": "2026-06-10T11:05:00+05:30",
"producer": "payments",
"user_id": "U123",
"correlation": {
"payment_id": "pay_123",
"txn_id": "txn_123", // FS correlation?
"canonical_transaction_id": "txn_123",
"original_event_id": null // FS correlation?
},
"attributes": {
"transaction_type": "UPI",
"payment_status": "SUCCESS",
"transaction_amount": 25000,
"currency": "INR",
"merchant_id": "m_001",
"merchant_category": "UTILITY",
"action_type": null
}
}
Future games leverage the same attributes.* space (e.g., merchant_category, billpay_category) in their triggers, giving us config-only extensibility.
Sequence:
Evaluation scope: Phase 1 uses INBOUNDEVENT evaluation only; no logical-transaction correlation is applied. Trigger stacking (multiple triggers on the same event) is supported via mode: ADDITIVE but is not required for UPI+FS Phase 1.
{
"event_id": "evt_001",
"event_type": "payment_success",
"event_version": "1.0",
"occurred_at": "2026-06-10T11:05:00+05:30",
"producer": "payments",
"user_id": "U123",
"correlation": {
"payment_id": "pay_123",
"txn_id": "txn_123",
"original_event_id": null
},
"attributes": {
"transaction_type": "UPI",
"payment_status": "SUCCESS",
"transaction_amount": 25000,
"currency": "INR",
"merchant_id": "m_001",
"merchant_category": "GROCERY",
"billpay_category": null,
"action_type": null,
"frm_flag": null
}
}
Homepage widget – GET /api/games/active
current_value, max_value, next visible reward, window remaining.Game Journey – GET /api/games/{game_id}
History/support – GET /api/games/{game_id}/history
BFF pattern:
The write path is fully event-driven, so the engine does not expose a synchronous mutation API for post-transaction screens. UX will choose one of two patterns, to be finalised based on approved Figma flows:
1. Optimistic post-transaction UI (preferred where safe)
+1 for UPI success, +3 for a qualifying FS action), the client can render optimistic progress immediately using:2. Authoritative but delayed UI (fallback)
this is work in progress and will be finalised once UX figmas are signed off; architecture supports both patterns without additional backend components.
Although Phase 1 is limited to UPI + FS and a linear milestone game, the architecture generalises cleanly:
New progress drivers – commerce orders, app opens, and other events can be onboarded by:
attributes.*.New archetypes – checklist, streak, and calendar grid games can be implemented as additional strategies behind the same engine contract, with corresponding config extensions (e.g., per-category targets, streak windows).
New progression modes – amount-based, weighted, uniqueness-based are already part of the NUMERIC_COUNTER design and only require additional progression_config enums and strategy logic, not new infrastructure.
In case of newer archetypes such as streaks, calendar based games, etc are introduced, we introduce new Game Strategy plugin to handle such games.
Admin UI – A future admin/config portal can sit on top of the JSON validation and activation APIs without changing the runtime responsibilities.
1. UPI + FS double-dipping (same logical transaction)
payment_success and fs_action_complete.2. FRM integration undefined
3. Clawback/reversal strategy undefined
4. Normalisation layer deployment shape
5. DB schema details are WIP