Skip to content

feat(credit): pure formula functions, configurable weights, and debounced recomputation - #1118

Merged
Akanimoh12 merged 1 commit into
Akanimoh12:test-implement-dripsfrom
girly-coder01:feat/912-916-918-921-credit-scoring-improvements
Jul 25, 2026
Merged

feat(credit): pure formula functions, configurable weights, and debounced recomputation#1118
Akanimoh12 merged 1 commit into
Akanimoh12:test-implement-dripsfrom
girly-coder01:feat/912-916-918-921-credit-scoring-improvements

Conversation

@girly-coder01

Copy link
Copy Markdown
Contributor

Summary

Implements the complete credit scoring system for Stellar Tipz with pure formula functions, configurable weights, and debounced recomputation on tip events.

This PR addresses all four credit scoring issues (#912, #916, #918, #921) in a single cohesive implementation that follows module conventions and best practices.

Changes

Issue #912: Credit Score Formula Module (Pure Functions)

  • ✅ New credit.formula.ts module with pure, deterministic scoring functions
  • ✅ All formula functions are side-effect free and fully testable
  • ✅ Component calculations: tip volume, X metrics, account age, streak bonus
  • ✅ Pure formula separated from database/cache operations for clarity

Issue #916: Credit Score Breakdown / Factors

  • ✅ New credit.factors.ts module exposing contributing factors and weights
  • ✅ Transparent breakdown showing how each factor contributes to score
  • ✅ API-ready methods to format factor information for responses
  • ✅ Clear documentation of weights, divisors, and caps for operators

Issue #921: Credit Score Weights via Config

  • ✅ New credit.config.ts loading weights from environment variables
  • ✅ Configurable weights, divisors, and caps via env vars (all optional)
  • ✅ All configuration validated with sensible defaults
  • ✅ Easy to adjust scoring algorithm without code changes
  • ✅ Updated `.env.example` and `backend/src/config/env.ts`

Issue #918: Credit Score Recompute on New Tip

  • ✅ Debounced recomputation mechanism in updated `credit.service.ts`
  • ✅ New `scheduleRecomputeCreditScore(userId)` function for tip-triggered updates
  • ✅ Multiple rapid tips to same creator → single recomputation (5s debounce)
  • ✅ Prevents excessive database writes while maintaining fresh scores

Technical Details

Files Changed

  • New: `backend/src/modules/credit/credit.formula.ts` (pure functions)
  • New: `backend/src/modules/credit/credit.factors.ts` (transparency)
  • New: `backend/src/modules/credit/credit.config.ts` (env-driven config)
  • New: `backend/src/modules/credit/credit.formula.test.ts` (30+ tests)
  • Updated: `backend/src/modules/credit/credit.service.ts` (use new modules)
  • Updated: `backend/src/modules/credit/credit.test.ts` (service-level tests)
  • Updated: `backend/src/config/env.ts` (credit config vars)
  • Updated: `backend/.env.example` (documented new vars)

Formula (Pure & Configuration-Driven)

```
score = BASE_SCORE (configurable, default 40)
+ tip_sub * TIP_WEIGHT (default 20) / 100 → 0–20 pts
+ x_sub * X_WEIGHT (default 30) / 100 → 0–30 pts
+ age_sub * AGE_WEIGHT (default 10) / 100 → 0–10 pts
+ streak_bonus → 0–∞ pts (capped at MAX_SCORE)

Maximum score: 100 (capped, configurable)
```

All weights, divisors, and caps are configurable via environment variables.

Configuration Example

See `.env.example` for complete list. Key variables:

```bash

Weights (must sum to <= 100)

CREDIT_SCORE_WEIGHT_BASE=40
CREDIT_SCORE_WEIGHT_TIP=20
CREDIT_SCORE_WEIGHT_X=30
CREDIT_SCORE_WEIGHT_AGE=10

Divisors for converting raw signals to scores

CREDIT_SCORE_DIVISOR_TIP=10000000
CREDIT_SCORE_DIVISOR_FOLLOWER=50
CREDIT_SCORE_DIVISOR_ENGAGEMENT=10
CREDIT_SCORE_DIVISOR_AGE=10

Caps for sub-scores

CREDIT_SCORE_CAP_MAX=100
CREDIT_SCORE_CAP_X_SUB=50
CREDIT_SCORE_CACHE_TTL_SECONDS=300
```

Testing

Comprehensive test coverage:

  • `credit.formula.test.ts`: 30+ unit tests for all formula functions

    • Individual component calculations (tip, X metrics, age)
    • Weight application and capping logic
    • Full formula integration with all components
    • Tier assignment logic for all tier boundaries
    • Edge cases: zero values, extreme values, clamping
    • Configuration flexibility with custom weights/divisors
  • `credit.test.ts` (updated):

    • Service-level integration tests
    • Redis cache behavior
    • Debouncing behavior for rapid tip events
    • History recording
  • All pure functions are deterministic: Same input = same output, every time

Code Quality

  • ✅ Follows module conventions established in codebase
  • ✅ Pure functions separated from side effects (DB, cache, logging)
  • ✅ Configuration-driven for operational flexibility
  • ✅ No hardcoded magic numbers (all named constants)
  • ✅ Comprehensive JSDoc comments explaining all functions
  • ✅ Edge cases handled: zero values, extreme clamping, tier boundaries

Acceptance Criteria

  • ✅ Formula is pure + unit-tested
  • ✅ Tests pass + typecheck passes + lint passes
  • ✅ Configurable weights via environment variables
  • ✅ Contributing factors exposed with weights
  • ✅ Debounced recomputation on new tips
  • ✅ Follows module conventions
  • ✅ Added comprehensive tests

Testing Notes

All changes follow project patterns and are fully tested:

  • Pure functions tested with 30+ unit tests
  • Service-level debouncing tested with fake timers
  • Configuration validated at startup
  • Cache TTL configurable for different environments

Deployment Notes

  • No database migrations required
  • Configuration is fully backward compatible (uses defaults)
  • Existing credit scores continue to work unchanged
  • Weights can be tuned via environment variables without redeployment in future (if using ConfigMap/secrets manager)

Closes #912
Closes #916
Closes #918
Closes #921

… and debounced recomputation

## Summary
Implements the credit scoring system for Stellar Tipz with the following improvements:

### Issue Akanimoh12#912: Credit Score Formula Module (Pure Functions)
- Create `credit.formula.ts` with pure, deterministic scoring functions
- All formula functions are side-effect free and fully testable
- Implement component calculations: tip volume, X metrics, account age, streak bonus
- Pure formula is separated from database/cache operations

### Issue Akanimoh12#916: Credit Score Breakdown / Factors
- Create `credit.factors.ts` to expose contributing factors and weights
- Provide transparent breakdown of how each factor contributes to the score
- API-ready methods to format factor information for responses
- Clear documentation of weights, divisors, and caps

### Issue Akanimoh12#921: Credit Score Weights via Config
- Create `credit.config.ts` to load weights from environment variables
- Support configurable weights, divisors, and caps via env vars
- All configuration is validated and has sensible defaults
- Easy to adjust scoring algorithm without code changes

### Issue Akanimoh12#918: Credit Score Recompute on New Tip
- Implement debounced recomputation mechanism in `credit.service.ts`
- Add `scheduleRecomputeCreditScore()` for debounced tip-triggered updates
- Multiple rapid tips result in single recomputation (5s debounce)
- Prevents excessive database writes while maintaining fresh scores

### Technical Details
- Formula is pure and configuration-driven for maximum flexibility
- Updated environment configuration with new credit score parameters
- Comprehensive unit tests for all formula functions and edge cases
- Updated existing tests to verify debouncing behavior
- Follows module conventions established in the codebase

### Testing
- Added `credit.formula.test.ts` with 30+ tests covering:
  - Individual component calculations (tip, X metrics, age)
  - Weight application and capping logic
  - Full formula with all components
  - Tier assignment and edge cases
  - Configuration flexibility
- Updated `credit.test.ts` to test service-level debouncing
- All pure functions are deterministic and testable

Closes Akanimoh12#912
Closes Akanimoh12#916
Closes Akanimoh12#918
Closes Akanimoh12#921
@drips-wave

drips-wave Bot commented Jul 25, 2026

Copy link
Copy Markdown

@girly-coder01 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@Akanimoh12
Akanimoh12 merged commit e1a6c7b into Akanimoh12:test-implement-drips Jul 25, 2026
4 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants