Skip to content

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

Implementation Summary

What I Built

I built a FastAPI-based Reward Decision Service that returns deterministic reward outcomes for transactions. The service is idempotent, config-driven, and uses Redis for caching with in-memory fallback.

Core Features Implemented

1. API Endpoint

  • POST /reward/decide - main endpoint for reward decisions
  • GET /health - health check endpoint
  • Request validation using Pydantic models
  • Response includes decision_id, policy_version, reward_type, reward_value, xp, reason_codes, and meta

2. Idempotency

  • Idempotency key: txn_id + user_id + merchant_id
  • Same request returns exact same response
  • TTL configurable (default 24 hours)
  • Implemented in IdempotencyService

3. Persona System

  • Four strategies: PREFIX, JSON_FILE, IN_MEMORY, MOCK_ENDPOINT
  • Default is PREFIX strategy (new_, ret_, pow_ prefixes)
  • Three personas: NEW, RETURNING, POWER
  • Each persona has different XP multipliers and daily CAC caps
  • Implemented in PersonaIdentifier service

4. Reward Logic

  • Three reward types: XP, CHECKOUT, GOLD
  • XP always given alongside monetary rewards
  • Weighted random selection based on config
  • Formula: xp = min(amount * xp_per_rupee * persona_multiplier, max_xp_per_txn)
  • Monetary rewards: CHECKOUT (10%), GOLD (5%) of transaction amount

5. Business Rules

  • Daily CAC cap per persona (NEW: 100, RETURNING: 300, POWER: 500)
  • Cooldown period between monetary rewards (5 minutes)
  • Prefer XP mode flag
  • Atomic CAC reservation to prevent race conditions
  • Downgrades to XP if rules violated

6. Caching

  • Redis as primary cache
  • In-memory fallback if Redis unavailable
  • Cache keys: idem:, last_reward:, cac:*
  • CacheManager handles both implementations
  • Atomic check-and-increment for CAC tracking

7. Configuration

  • YAML-based policy configuration (config/policy.yaml)
  • Environment variables via .env file
  • Configurable reward weights, XP rates, caps, feature flags
  • PolicyConfig class loads and validates config

Project Structure

app/

  • main.py - FastAPI application entry point
  • api/endpoints.py - API route handlers
  • core/config.py - configuration management
  • core/cache.py - cache manager with Redis and in-memory
  • models/request.py - request models
  • models/response.py - response models
  • models/enums.py - RewardType, Persona, ReasonCode enums
  • services/reward_decision.py - main business logic
  • services/idempotency.py - idempotency handling
  • services/persona_identifier.py - persona identification
  • utils/helpers.py - utility functions

config/

  • policy.yaml - reward policy configuration

tests/

  • unit/ - 96 unit tests
  • integration/ - 4 integration tests
  • load/ - K6 load tests

Testing

Unit Tests (96 tests)

  • test_helpers.py - 18 tests for utility functions
  • test_enums.py - 24 tests for enum classes
  • test_persona_identifier.py - 20 tests for persona strategies
  • test_idempotency_service.py - 11 tests for idempotency
  • test_reward_decision_service.py - 23 tests for reward logic
  • All dependencies mocked
  • Tests run in 0.20 seconds

Integration Tests (4 tests)

  • test_api_server.py - API endpoint testing
  • test_cac_race_condition.py - concurrent CAC updates
  • test_cooldown.py - cooldown period validation
  • test_determinism.py - idempotency verification
  • Uses real service instances with mocked cache

Load Tests

  • K6 smoke test - basic functionality check
  • K6 load test - sustained load testing
  • K6 stress test - breaking point testing
  • Setup script for K6 installation
  • Documentation for running tests

Docker Setup

  • Dockerfile for FastAPI service
  • docker-compose.yml with Redis and web service
  • Multi-worker deployment with Gunicorn
  • Health checks for both services
  • Persistent Redis data volume
  • Network isolation

Performance Optimizations

  • Async/await throughout the codebase
  • uvloop for faster event loop
  • httptools for faster HTTP parsing
  • orjson for faster JSON serialization
  • Cache-first design
  • Atomic operations to avoid locks

Code Conventions

  • Function names: camelCase
  • Variable names: snake_case
  • Type hints on all functions
  • Docstrings for all public methods
  • Pydantic for data validation

Key Implementation Details

Determinism

  • Same txn_id always returns same response via idempotency cache
  • Random reward selection happens once, then cached
  • Decision ID generated once and stored

CAC Tracking

  • Atomic check-and-increment operation
  • Daily reset based on date
  • Per-user, per-day tracking
  • Prevents race conditions with multiple concurrent requests

Cooldown Logic

  • Tracks last monetary reward timestamp
  • Checks time difference before allowing new reward
  • Can be disabled via feature flag
  • Only applies to monetary rewards, not XP

Persona Identification

  • Pluggable strategy pattern
  • Default PREFIX strategy for simplicity
  • Can switch strategies via environment variable
  • Fallback to prefix if other strategies fail

Configuration Files

.env - environment variables config/policy.yaml - reward policy data/personas.json - persona mappings (optional) requirements.txt - Python dependencies docker-compose.yml - Docker services

Dependencies

FastAPI - web framework Uvicorn - ASGI server Pydantic - data validation Redis - caching PyYAML - config parsing pytest - testing K6 - load testing

What Works

  • API accepts requests and returns rewards
  • Idempotency prevents duplicate processing
  • Persona system identifies user types
  • Business rules enforce caps and cooldowns
  • Caching works with Redis or in-memory
  • Tests validate all core functionality
  • Docker deployment ready
  • Load testing shows performance metrics

Known Limitations

  • No persistent database, only cache
  • No authentication or authorization
  • No rate limiting
  • No logging or metrics
  • No distributed locking for multi-instance deployment
  • No retry logic for failures
  • No circuit breakers
  • Config changes require restart

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages