From eea2a25aadd52dd3a2d5c264176c2b063da4c4dc Mon Sep 17 00:00:00 2001 From: Mauricio Araujo Date: Wed, 1 May 2024 09:50:18 -0400 Subject: [PATCH] Add max reward limit --- api/server/handlers/billing/create.go | 16 ++----- api/server/handlers/project/referrals.go | 10 ++-- dashboard/src/lib/billing/types.tsx | 27 ++++++----- .../home/project-settings/ReferralsPage.tsx | 47 ++++++++++--------- internal/billing/metronome.go | 29 +++++++++--- 5 files changed, 72 insertions(+), 57 deletions(-) diff --git a/api/server/handlers/billing/create.go b/api/server/handlers/billing/create.go index bc4e1d0f1d..881d8856d8 100644 --- a/api/server/handlers/billing/create.go +++ b/api/server/handlers/billing/create.go @@ -17,17 +17,6 @@ import ( "github.com/porter-dev/porter/internal/telemetry" ) -const ( - // defaultRewardAmountCents is the default amount in USD cents rewarded to users - // who successfully refer a new user - defaultRewardAmountCents = 1000 - // defaultPaidAmountCents is the amount paid by the user to get the credits - // grant, if set to 0 it means they are free - defaultPaidAmountCents = 0 - // maxReferralRewards is the maximum number of referral rewards a user can receive - maxReferralRewards = 10 -) - // CreateBillingHandler is a handler for creating payment methods type CreateBillingHandler struct { handlers.PorterHandlerWriter @@ -147,6 +136,7 @@ func (c *CreateBillingHandler) grantRewardIfReferral(ctx context.Context, referr return telemetry.Error(ctx, span, err, "failed to get referral count by referrer id") } + maxReferralRewards := c.Config().BillingManager.MetronomeClient.MaxReferralRewards if referralCount >= maxReferralRewards { return nil } @@ -161,7 +151,9 @@ func (c *CreateBillingHandler) grantRewardIfReferral(ctx context.Context, referr // practice will mean the credits will most likely run out before expiring expiresAt := time.Now().AddDate(5, 0, 0).Format(time.RFC3339) reason := "Referral reward" - err := c.Config().BillingManager.MetronomeClient.CreateCreditsGrant(ctx, referrerProject.UsageID, reason, defaultRewardAmountCents, defaultPaidAmountCents, expiresAt) + rewardAmount := c.Config().BillingManager.MetronomeClient.DefaultRewardAmountCents + paidAmount := c.Config().BillingManager.MetronomeClient.DefaultPaidAmountCents + err := c.Config().BillingManager.MetronomeClient.CreateCreditsGrant(ctx, referrerProject.UsageID, reason, rewardAmount, paidAmount, expiresAt) if err != nil { return telemetry.Error(ctx, span, err, "failed to grand credits reward") } diff --git a/api/server/handlers/project/referrals.go b/api/server/handlers/project/referrals.go index c8d3030f72..80669a2f95 100644 --- a/api/server/handlers/project/referrals.go +++ b/api/server/handlers/project/referrals.go @@ -68,11 +68,13 @@ func (c *GetProjectReferralDetailsHandler) ServeHTTP(w http.ResponseWriter, r *h } referralCodeResponse := struct { - Code string `json:"code"` - ReferralCount int64 `json:"referral_count"` + Code string `json:"code"` + ReferralCount int64 `json:"referral_count"` + MaxAllowedRewards int64 `json:"max_allowed_referrals"` }{ - Code: proj.ReferralCode, - ReferralCount: referralCount, + Code: proj.ReferralCode, + ReferralCount: referralCount, + MaxAllowedRewards: c.Config().BillingManager.MetronomeClient.MaxReferralRewards, } c.WriteResult(w, r, referralCodeResponse) diff --git a/dashboard/src/lib/billing/types.tsx b/dashboard/src/lib/billing/types.tsx index 9a64261975..5228fc835a 100644 --- a/dashboard/src/lib/billing/types.tsx +++ b/dashboard/src/lib/billing/types.tsx @@ -17,13 +17,15 @@ const TrialValidator = z.object({ }); export type Plan = z.infer; -export const PlanValidator = z.object({ - id: z.string(), - plan_name: z.string(), - plan_description: z.string(), - starting_on: z.string(), - trial_info: TrialValidator, -}).nullable(); +export const PlanValidator = z + .object({ + id: z.string(), + plan_name: z.string(), + plan_description: z.string(), + starting_on: z.string(), + trial_info: TrialValidator, + }) + .nullable(); export type UsageMetric = z.infer; export const UsageMetricValidator = z.object({ @@ -52,7 +54,10 @@ export const CreditGrantsValidator = z.object({ export const ClientSecretResponse = z.string(); export type ReferralDetails = z.infer; -export const ReferralDetailsValidator = z.object({ - code: z.string(), - referral_count: z.number(), -}).nullable(); +export const ReferralDetailsValidator = z + .object({ + code: z.string(), + referral_count: z.number(), + max_allowed_referrals: z.number(), + }) + .nullable(); diff --git a/dashboard/src/main/home/project-settings/ReferralsPage.tsx b/dashboard/src/main/home/project-settings/ReferralsPage.tsx index 226ca0b238..2f2a19cef9 100644 --- a/dashboard/src/main/home/project-settings/ReferralsPage.tsx +++ b/dashboard/src/main/home/project-settings/ReferralsPage.tsx @@ -1,35 +1,36 @@ import React from "react"; + +import Link from "components/porter/Link"; import Spacer from "components/porter/Spacer"; import Text from "components/porter/Text"; import { useReferralDetails } from "lib/hooks/useStripe"; -import Link from "components/porter/Link"; function ReferralsPage(): JSX.Element { - const { referralDetails } = useReferralDetails(); - const baseUrl = window.location.origin; + const { referralDetails } = useReferralDetails(); + const baseUrl = window.location.origin; - return ( + return ( + <> + Referrals + + Refer people to Porter to earn credits. + + {referralDetails !== null && ( <> - Referrals - - - Refer people to Porter to earn credits. - - - {referralDetails !== null && ( - <> - - Your referral link is {" "} - -