Skip to content

Fix referral quota for existing recipients#442

Merged
ralyodio merged 2 commits into
profullstack:masterfrom
Autowebassat-blip:fix-439-referral-quota-existing-recipients
Jun 14, 2026
Merged

Fix referral quota for existing recipients#442
ralyodio merged 2 commits into
profullstack:masterfrom
Autowebassat-blip:fix-439-referral-quota-existing-recipients

Conversation

@Autowebassat-blip

Copy link
Copy Markdown
Contributor

Fixes #439.

Referral quota checks were counting all valid email addresses before filtering addresses that had already been invited. That could return 429 even when only one new recipient would consume quota.

This moves duplicate-invite filtering before the hourly and daily quota checks, then counts only new valid emails against the limits.

Tests:

  • git diff --check
  • npm test -- src/app/api/referrals/route.test.ts --runInBand blocked: vitest not installed locally

@greptile-apps

greptile-apps Bot commented Jun 13, 2026

Copy link
Copy Markdown

Greptile Summary

This PR fixes an over-eager 429 response when submitting referral invites that include emails already in the referrals table. Previously the duplicate-invite filter ran after quota math, so the full validEmails count was used against hourly/daily limits even though some of those emails would be rejected as duplicates immediately after. The fix moves the DB duplicate check first, builds newValidEmails, and uses that smaller set for all subsequent quota comparisons. The previously-silenced Supabase error on the duplicate lookup is now surfaced and returns a proper 500.

  • The reordering correctly ensures only genuinely new invites consume quota, resolving spurious 429s for mixed batches.
  • Error handling on the duplicate-check query is now explicit, preventing silent bypass of the duplicate guard when the DB is unavailable.
  • The hourly and daily count queries still discard their error field (pre-existing), which could allow quota bypass under DB failure; this is unrelated to the stated fix but worth a follow-up.

Confidence Score: 5/5

Safe to merge; the reordering is logically correct and the newly added error guard on the duplicate-check query is an improvement.

The change is a focused reorder of three existing operations in POST /api/referrals. The duplicate-invite lookup now runs before quota math, newValidEmails replaces validEmails in both quota comparisons, and the previously-swallowed Supabase error on that lookup is now handled explicitly. No new execution paths are introduced that could cause data loss, double-sends, or auth bypass beyond what already existed.

Only src/app/api/referrals/route.ts changed; the quota-count queries in that file still discard their error field, worth a follow-up but not a blocker.

Important Files Changed

Filename Overview
src/app/api/referrals/route.ts Moves duplicate-invite DB check before hourly/daily quota math and properly handles the query error; quota checks now use newValidEmails instead of validEmails.

Sequence Diagram

sequenceDiagram
    participant C as Client
    participant R as POST /api/referrals
    participant DB as Supabase (svc)
    participant M as Email Service

    C->>R: "POST { emails }"
    R->>R: Auth check
    R->>R: "Validate & dedupe email syntax → validEmails"
    R->>DB: "SELECT referred_email WHERE referrer_id=? AND referred_email IN validEmails"
    DB-->>R: existingInvites (or error → 500)
    R->>R: Build alreadyInvited set → newValidEmails
    alt newValidEmails is empty
        R-->>C: 400 All already invited
    end
    R->>DB: "COUNT referrals WHERE referrer_id=? AND created_at > -1h"
    DB-->>R: hourlyCount
    alt "hourlyCount + newValidEmails.length > 10"
        R-->>C: 429 hourly limit
    end
    R->>DB: "COUNT referrals WHERE referrer_id=? AND created_at > -24h"
    DB-->>R: dailyCount
    alt "dailyCount + newValidEmails.length > 50"
        R-->>C: 429 daily limit
    end
    R->>DB: SELECT profile (user client)
    DB-->>R: profile
    R->>M: sendEmail for each newValidEmail
    M-->>R: emailResults
    R->>DB: INSERT successful referral rows (user client)
    DB-->>R: inserted referrals
    R-->>C: "200 { message, data }"
Loading

Reviews (2): Last reviewed commit: "Handle referral duplicate lookup errors" | Re-trigger Greptile

Comment thread src/app/api/referrals/route.ts Outdated
@ralyodio ralyodio merged commit 7cbe633 into profullstack:master Jun 14, 2026
6 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

Development

Successfully merging this pull request may close these issues.

Referral rate limit counts already-invited recipients

2 participants