Skip to content

✨ instant referee grant: retry grantForInvitation when the org is provisioned at email verification #3844

Description

@PierreBrisorgueil

Follow-up of #3842 (user request 2026-06-12). With a mailer configured, the referee's org is provisioned at EMAIL VERIFICATION — after the invitation.accepted event — so the referee's grant lands no_organization and waits for the reconcile cron (≤24h prod). Make it instant:

  • organizations (the org creator) emits an organizationProvisioned-style event on its own emitter (create modules/organizations/lib/events.js mirroring invitations/lib/events.js if none exists) when handleSignupOrganization completes at verifyEmail — payload { userId, organizationId }. Dependency directions stay clean (billing → organizations is an allowed optional-consumer edge, same as billing → invitations; auth/org never import billing).
  • billing.init.js listener (config-gated on billing.referral.enabled, async self-guarded like the existing one): if the user has referredBy, find their accepted invitation (acceptedUserId) and re-call BillingReferralService.grantForInvitationalready idempotent (referral:<invitationId>:* keys), so double-fire with the cron is harmless.
  • Tests: mailer-on signup → verify email → referee credited instantly; replay/cron-overlap safe; disabled → no-op.

Product angle: the referee sees "+500 credits 🎁" the moment they land in the app — onboarding moment. The cron stays as the safety net (truth).
Refs #3842, #3814, epic #3808.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions