mirror of
https://github.com/tinyhumansai/openhuman.git
synced 2026-07-28 05:12:33 +00:00
* refactor(referral): update referral system to a one-time flat reward structure - Transitioned to a link-based referral system offering a one-time $5 credit to both the referrer and the referred user upon the first subscription payment. - Removed the previous reward rate in basis points and eliminated recurring rewards, ensuring clarity in the referral process. - Updated API endpoints and service methods to reflect the new `claimReferral` functionality, enhancing user experience and eligibility checks. - Revised documentation and tests to align with the new referral structure, ensuring comprehensive coverage and understanding of the changes. * refactor(referral): simplify JSON response handling in referral claim function - Streamlined the `handle_referral_claim` function by removing unnecessary `as_deref()` and `filter()` calls, enhancing code clarity and performance. - Updated the JSON response construction to eliminate redundant line breaks, improving readability without altering functionality.
2.9 KiB
2.9 KiB
Referral System
Overview
Link-based referral system with one-time flat rewards for both parties.
- Reward: $5 credit to referrer and $5 credit to referred user
- Reward is one-time: awarded when the referred user's first subscription payment is confirmed
- No recurring rewards — once a referral is marked
CONVERTED, subsequent payments returnalready_converted
Main Rules
- Each user has one unique referral code with a shareable link.
- A user can claim a referral link only before their first subscription.
- Self-referral is blocked (user id + identity fields).
- Rewarding is idempotent:
- same payment cannot reward twice
- only one reward per referral (always one-time)
Data Model
ReferralCode (referralcodes)
userId(unique)referralCode(unique)
Referral (referrals)
referrerIdreferredUserId(unique)referralCodestatus:pending | convertedsourceIp,deviceFingerprint,convertedAt
ReferralTransaction (referraltransactions)
referralId,referrerId,referredUserIdsourcePaymentId,sourcePaymentGateway,sourcePaymentObjectIdpaymentAmountUsd,rewardAmountUsd,rewardRate(Decimal128)creditTransactionIdrecipientType:REFERRER | REFERREDidempotencyKey(unique)
Migration
Migration file: src/migrations/1744200000000-referral-system.ts
What it does:
- creates indexes for referral collections
- backfills missing referral codes for existing users
- backfills
Referralrecords from legacyuser.referral.invitedBy - supports
usersandtguserscollections
Run migration (non-interactive)
npx ts-migrate-mongoose up -f src/migrate.ts -a true
Check migration status
npm run migrate:list
Roll back referral migration (if needed)
npm run migrate:down
Core Services
src/services/referral/referralCodeService.ts- ensures and fetches user referral codes
src/services/referral/referralService.ts- claim referral link, enforce eligibility (subscription-based gating), return referral stats
src/services/referral/referralRewardService.ts- award flat $5 credit to both referrer and referred user, upsert audit transactions, mark referral converted
API
GET /referral/stats- returns code, referral link, totals, and referral rows
POST /referral/claim- request:
{ "code": "ABCD1234", "deviceFingerprint": "optional" } - supports
x-device-fingerprintheader - only users who have never subscribed are eligible
- request:
Payment Integration
Reward processing is triggered on successful payment flows in:
src/controllers/payment/coinbase/webhook.tssrc/controllers/payment/stripe/handleWebhook.ts
Tests
Key test: src/services/referral/__tests__/referralRewardService.test.ts
- flat $5 reward to both parties
- conversion blocking (already_converted)
- payment idempotency
- partial-retry recovery