feat(referrals): rework reward engine + email-verified landing
Some checks failed
QA Gate (P0/P1) / Test affected app (pull_request) Has been cancelled
Some checks failed
QA Gate (P0/P1) / Test affected app (pull_request) Has been cancelled
Reward engine: - Recurring milestones (every 3 → +7d, every 5 → +14d) instead of one-time tiers capped at 5; idempotent + transactional grants serialised per referrer so concurrent qualifications can't double-count. - Rewards now gated on the referred user's email verification (afterEmailVerification hook); already-verified referees (OAuth) qualify at apply time. - Reward days banked as users.referral_credit_days when the referrer has no live subscription, consumed on next trial start / activation (no more silently lost rewards). - Accurate cumulative rewardDays in stats; getMyReferrals returns referee name/masked email/status. Hardening / cleanup: - onConflictDoNothing makes apply idempotent (no unhandled unique violation). - Anti-fraud: normalizeEmail blocks self-referral via gmail dot/+tag aliases. - Collision-safe referral code generation at signup. - Single apply path (welcome onboarding modal); removed duplicate calls in register + subscription pages. Input validation on the apply code. Email verification UX: - Verification link now lands on a dedicated /email-verified confirmation page instead of the deep-linked VIN/search page. Schema: referrals.status + qualified_at, users.referral_credit_days (0009). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
3
apps/api/drizzle/0009_referral_rewards_rework.sql
Normal file
3
apps/api/drizzle/0009_referral_rewards_rework.sql
Normal file
@@ -0,0 +1,3 @@
|
||||
ALTER TABLE "referrals" ADD COLUMN "status" varchar(20) DEFAULT 'pending' NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE "referrals" ADD COLUMN "qualified_at" timestamp with time zone;--> statement-breakpoint
|
||||
ALTER TABLE "users" ADD COLUMN "referral_credit_days" integer DEFAULT 0 NOT NULL;
|
||||
5564
apps/api/drizzle/meta/0009_snapshot.json
Normal file
5564
apps/api/drizzle/meta/0009_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -64,6 +64,13 @@
|
||||
"when": 1779633572753,
|
||||
"tag": "0008_common_sumo",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 9,
|
||||
"version": "7",
|
||||
"when": 1779703007129,
|
||||
"tag": "0009_referral_rewards_rework",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user