# thurpe/bumpa-gamified-cashback architecture

> Architecture diagram of the GitHub repository thurpe/bumpa-gamified-cashback, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-27). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/thurpe/bumpa-gamified-cashback
- Repository: https://github.com/thurpe/bumpa-gamified-cashback

## Overview

Bumpa is an event-driven cashback backend: recording a customer purchase triggers achievement and badge evaluation, then queues a Paystack cashback payout. Customers can also query gamification state; payout recovery is handled by a reconciliation command and a signed webhook. The README documents these behaviors, but several implementations (including evaluators, the payout job, and reconciliation command) were not sampled, so their links reflect documented behavior rather than inspected call sites.

Main entry points: [`app/Models/Payout.php`](https://github.com/thurpe/bumpa-gamified-cashback/blob/main/app/Models/Payout.php) (Purchase, unlock, payout records), [`app/Listeners/EvaluateAchievements.php`](https://github.com/thurpe/bumpa-gamified-cashback/blob/main/app/Listeners/EvaluateAchievements.php) (Achievement evaluator), [`app/Listeners/EvaluateBadges.php`](https://github.com/thurpe/bumpa-gamified-cashback/blob/main/app/Listeners/EvaluateBadges.php) (Badge evaluator), [`app/Jobs/DispatchCashbackJob.php`](https://github.com/thurpe/bumpa-gamified-cashback/blob/main/app/Jobs/DispatchCashbackJob.php) (Cashback job)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_purchase["Purchase and events"]
  node_purchase_api["Purchase API"]
  node_purchase_event["PurchaseCompleted"]
  node_event_map["Event wiring"]
end

subgraph group_game["Gamification"]
  node_achievement_eval["Achievement evaluator"]
  node_achievement_event["AchievementUnlocked"]
  node_badge_eval["Badge evaluator<br/>[EvaluateBadges.php]"]
  node_badge_event["BadgeUnlocked<br/>[BadgeUnlocked.php]"]
  node_achievement_api["Achievements API"]
  node_game_state["Gamification state"]
  node_rules["Gamification rules<br/>[gamification.php]"]
end

subgraph group_payout["Cashback and recovery"]
  node_cashback_listener["Cashback dispatcher"]
  node_cashback_job["Cashback job"]
  node_paystack_client["Paystack client<br/>[PaystackClient.php]"]
  node_reconcile["Payout sweeper"]
  node_webhook["Paystack webhook"]
end

subgraph group_state["State and ledger"]
  node_ledger[("Purchase, unlock, payout records<br/>[Payout.php]")]
end

node_customer(("Customer"))
node_paystack{{"Paystack"}}
node_payment_event(("Transfer webhook"))

node_customer -->|"submits purchase"| node_purchase_api
node_purchase_api -->|"records purchase"| node_ledger
node_purchase_api -->|"dispatches"| node_purchase_event
node_event_map -->|"registers listener"| node_achievement_eval
node_event_map -->|"registers listener"| node_badge_eval
node_event_map -->|"registers listener"| node_cashback_listener
node_purchase_event -->|"triggers"| node_achievement_eval
node_achievement_eval -->|"reads thresholds"| node_rules
node_achievement_eval -->|"records unlock"| node_ledger
node_achievement_eval -->|"dispatches"| node_achievement_event
node_achievement_event -->|"triggers"| node_badge_eval
node_badge_eval -->|"reads thresholds"| node_rules
node_badge_eval -->|"records badge"| node_ledger
node_badge_eval -->|"dispatches"| node_badge_event
node_badge_event -->|"triggers"| node_cashback_listener
node_cashback_listener -->|"queues payout"| node_cashback_job
node_cashback_job -->|"updates payout"| node_ledger
node_cashback_job -->|"requests transfer"| node_paystack_client
node_paystack_client -->|"transfers or verifies"| node_paystack
node_reconcile -->|"finds pending payouts"| node_ledger
node_reconcile -->|"verifies transfer"| node_paystack_client
node_reconcile -->|"requeues failed payout"| node_cashback_job
node_payment_event -->|"posts callback"| node_webhook
node_webhook -->|"settles payout"| node_ledger
node_webhook -->|"requeues failure"| node_cashback_job
node_customer -->|"requests state"| node_achievement_api
node_achievement_api -->|"builds response"| node_game_state
node_game_state -->|"reads rules"| node_rules
node_game_state -->|"reads unlocks"| node_ledger

click node_purchase_api "https://github.com/thurpe/bumpa-gamified-cashback/blob/main/app/Http/Controllers/PurchaseController.php"
click node_purchase_event "https://github.com/thurpe/bumpa-gamified-cashback/blob/main/app/Events/PurchaseCompleted.php"
click node_event_map "https://github.com/thurpe/bumpa-gamified-cashback/blob/main/app/Providers/EventServiceProvider.php"
click node_achievement_eval "https://github.com/thurpe/bumpa-gamified-cashback/blob/main/app/Listeners/EvaluateAchievements.php"
click node_achievement_event "https://github.com/thurpe/bumpa-gamified-cashback/blob/main/app/Events/AchievementUnlocked.php"
click node_badge_eval "https://github.com/thurpe/bumpa-gamified-cashback/blob/main/app/Listeners/EvaluateBadges.php"
click node_badge_event "https://github.com/thurpe/bumpa-gamified-cashback/blob/main/app/Events/BadgeUnlocked.php"
click node_cashback_listener "https://github.com/thurpe/bumpa-gamified-cashback/blob/main/app/Listeners/DispatchCashback.php"
click node_cashback_job "https://github.com/thurpe/bumpa-gamified-cashback/blob/main/app/Jobs/DispatchCashbackJob.php"
click node_paystack_client "https://github.com/thurpe/bumpa-gamified-cashback/blob/main/app/Services/Paystack/PaystackClient.php"
click node_reconcile "https://github.com/thurpe/bumpa-gamified-cashback/blob/main/app/Console/Commands/ReconcilePayouts.php"
click node_webhook "https://github.com/thurpe/bumpa-gamified-cashback/blob/main/app/Http/Controllers/PaystackWebhookController.php"
click node_achievement_api "https://github.com/thurpe/bumpa-gamified-cashback/blob/main/app/Http/Controllers/AchievementController.php"
click node_game_state "https://github.com/thurpe/bumpa-gamified-cashback/blob/main/app/Support/GamificationState.php"
click node_rules "https://github.com/thurpe/bumpa-gamified-cashback/blob/main/config/gamification.php"
click node_ledger "https://github.com/thurpe/bumpa-gamified-cashback/blob/main/app/Models/Payout.php"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_purchase_api,node_purchase_event,node_event_map toneBlue
class node_achievement_eval,node_achievement_event,node_badge_eval,node_badge_event,node_achievement_api,node_game_state,node_rules toneAmber
class node_cashback_listener,node_cashback_job,node_paystack_client,node_reconcile,node_webhook,node_payment_event toneMint
class node_ledger toneRose
class node_customer,node_paystack toneIndigo
```

## Components

### Purchase and events

- [Purchase API](https://github.com/thurpe/bumpa-gamified-cashback/blob/main/app/Http/Controllers/PurchaseController.php): `app/Http/Controllers/PurchaseController.php`
- [PurchaseCompleted](https://github.com/thurpe/bumpa-gamified-cashback/blob/main/app/Events/PurchaseCompleted.php): `app/Events/PurchaseCompleted.php`
- [Event wiring](https://github.com/thurpe/bumpa-gamified-cashback/blob/main/app/Providers/EventServiceProvider.php): `app/Providers/EventServiceProvider.php`

### Gamification

- [Achievement evaluator](https://github.com/thurpe/bumpa-gamified-cashback/blob/main/app/Listeners/EvaluateAchievements.php): `app/Listeners/EvaluateAchievements.php`
- [AchievementUnlocked](https://github.com/thurpe/bumpa-gamified-cashback/blob/main/app/Events/AchievementUnlocked.php): `app/Events/AchievementUnlocked.php`
- [Badge evaluator](https://github.com/thurpe/bumpa-gamified-cashback/blob/main/app/Listeners/EvaluateBadges.php): `app/Listeners/EvaluateBadges.php`
- [BadgeUnlocked](https://github.com/thurpe/bumpa-gamified-cashback/blob/main/app/Events/BadgeUnlocked.php): `app/Events/BadgeUnlocked.php`
- [Achievements API](https://github.com/thurpe/bumpa-gamified-cashback/blob/main/app/Http/Controllers/AchievementController.php): `app/Http/Controllers/AchievementController.php`
- [Gamification state](https://github.com/thurpe/bumpa-gamified-cashback/blob/main/app/Support/GamificationState.php): `app/Support/GamificationState.php`
- [Gamification rules](https://github.com/thurpe/bumpa-gamified-cashback/blob/main/config/gamification.php): `config/gamification.php`

### Cashback and recovery

- [Cashback dispatcher](https://github.com/thurpe/bumpa-gamified-cashback/blob/main/app/Listeners/DispatchCashback.php): `app/Listeners/DispatchCashback.php`
- [Cashback job](https://github.com/thurpe/bumpa-gamified-cashback/blob/main/app/Jobs/DispatchCashbackJob.php): `app/Jobs/DispatchCashbackJob.php`
- [Paystack client](https://github.com/thurpe/bumpa-gamified-cashback/blob/main/app/Services/Paystack/PaystackClient.php): `app/Services/Paystack/PaystackClient.php`
- [Payout sweeper](https://github.com/thurpe/bumpa-gamified-cashback/blob/main/app/Console/Commands/ReconcilePayouts.php): `app/Console/Commands/ReconcilePayouts.php`
- [Paystack webhook](https://github.com/thurpe/bumpa-gamified-cashback/blob/main/app/Http/Controllers/PaystackWebhookController.php): `app/Http/Controllers/PaystackWebhookController.php`

### State and ledger

- [Purchase, unlock, payout records](https://github.com/thurpe/bumpa-gamified-cashback/blob/main/app/Models/Payout.php): `app/Models/Payout.php`

### Other components

- **Customer**
- **Paystack**
- **Transfer webhook**

## Connections

- Customer → Purchase API: submits purchase
- Purchase API → Purchase, unlock, payout records: records purchase
- Purchase API → PurchaseCompleted: dispatches
- Event wiring → Achievement evaluator: registers listener
- Event wiring → Badge evaluator: registers listener
- Event wiring → Cashback dispatcher: registers listener
- PurchaseCompleted → Achievement evaluator: triggers
- Achievement evaluator → Gamification rules: reads thresholds
- Achievement evaluator → Purchase, unlock, payout records: records unlock
- Achievement evaluator → AchievementUnlocked: dispatches
- AchievementUnlocked → Badge evaluator: triggers
- Badge evaluator → Gamification rules: reads thresholds
- Badge evaluator → Purchase, unlock, payout records: records badge
- Badge evaluator → BadgeUnlocked: dispatches
- BadgeUnlocked → Cashback dispatcher: triggers
- Cashback dispatcher → Cashback job: queues payout
- Cashback job → Purchase, unlock, payout records: updates payout
- Cashback job → Paystack client: requests transfer
- Paystack client → Paystack: transfers or verifies
- Payout sweeper → Purchase, unlock, payout records: finds pending payouts
- Payout sweeper → Paystack client: verifies transfer
- Payout sweeper → Cashback job: requeues failed payout
- Transfer webhook → Paystack webhook: posts callback
- Paystack webhook → Purchase, unlock, payout records: settles payout
- Paystack webhook → Cashback job: requeues failure
- Customer → Achievements API: requests state
- Achievements API → Gamification state: builds response
- Gamification state → Gamification rules: reads rules
- Gamification state → Purchase, unlock, payout records: reads unlocks
