Backend Systems
Designing Reliable Reward and Debit-Card Workflows for an Education Platform
A Django REST Framework case study focused on transactional consistency, concurrency control, and external card-provider workflows.
A Django REST Framework case study focused on transactional consistency, concurrency control, and external card-provider workflows.
Overview
I worked on an education platform for Electus Education Global / LHI, including backend services related to learner rewards and debit-card workflows.
The system included services such as learner, account, and organization administration domains. The public case study intentionally keeps internal implementation details generalized.
Business Context
Reward and card-loading workflows behave like financial-style systems even when they are part of an education platform. They require careful state transitions, auditability, provider integration, and protection against duplicate processing.
Problem
The platform needed workflows that could determine eligible rewards, enforce weekly or biweekly payment schedules, aggregate appropriate ledger entries, attempt card loads through an external provider, and update transaction state without concurrent workers processing the same records at the same time.
The domain included concepts such as card programs, cards, reward ledgers, card-load transactions, card order logs, balance audits, and cron-job logs.
My Role
I contributed Python backend engineering using Django REST Framework, PostgreSQL, Redis, Celery, Elasticsearch, REST APIs, background processing, and transactional database workflows.
System Architecture
Reward workflows connected learner reward records to a disbursement service, database transaction protection, external card-provider operations, load transactions, and operational audit logs.
Balance synchronization followed a separate background path for active cards: fetch provider balance, synchronize local state, and record relevant audit information.
Technical Challenges
The central challenge was consistency under concurrency. Multiple workers or requests must not claim the same reward ledger entries or submit duplicate financial-style load operations.
Failed external operations also needed controlled retry behavior. A retry should be deliberate, auditable, and aware of transaction state.
Engineering Decisions
Critical reward processing used transaction protection concepts such as transaction.atomic() and select_for_update().
The purpose was to keep related updates inside a transactional boundary and prevent concurrent workers or requests from processing the same reward records simultaneously.
The workflow treated card-load state explicitly with statuses such as pending, success, and failed. Reward ledger state could move from pending to claimed only when appropriate.
Implementation
The implementation combined DRF APIs, service-layer workflow logic, PostgreSQL transactions, Celery background processing, Redis-supported operations, and operational models for logs and audits.
External card-provider operations were modeled around concepts such as authentication, card ordering, card loading, and balance retrieval. Private endpoint URLs and production values are intentionally not published.
Reliability & Failure Handling
The system favored transactional safeguards, idempotency, and controlled retries. It does not claim perfect exactly-once delivery. Instead, the design reduces duplicate processing risk and keeps failed operations inspectable.
Security
Card and reward workflows require careful access control, sensitive-data handling, and auditability. This case study does not publish sensitive values such as card numbers, provider identifiers, credentials, or private endpoints.
Trade-offs
Locking records with select_for_update() improves consistency but must be used carefully to avoid excessive contention. The design balances correctness for financial-style records with background processing throughput.
Outcome
The platform gained clearer reward disbursement, card-load, balance-sync, audit, and retry workflows built around Django REST Framework and transactional backend design.
What I Learned
Reliable reward systems depend on explicit state, careful database boundaries, and audit logs that help operators understand what happened after a provider call succeeds, fails, or returns an ambiguous result.