|
|
@@ -2,7 +2,6 @@ package billing
|
|
|
|
|
|
import (
|
|
|
"net/http"
|
|
|
- "time"
|
|
|
|
|
|
"github.com/porter-dev/porter/api/server/handlers"
|
|
|
"github.com/porter-dev/porter/api/server/shared"
|
|
|
@@ -13,18 +12,6 @@ import (
|
|
|
"github.com/porter-dev/porter/internal/telemetry"
|
|
|
)
|
|
|
|
|
|
-const (
|
|
|
- // referralRewardRequirement is the number of referred users required to
|
|
|
- // be granted a credits reward
|
|
|
- referralRewardRequirement = 5
|
|
|
- // defaultRewardAmountUSD is the default amount in USD rewarded to users
|
|
|
- // who reach the reward requirement
|
|
|
- defaultRewardAmountCents = 2000
|
|
|
- // defaultPaidAmountUSD is the amount paid by the user to get the credits
|
|
|
- // grant, if set to 0 it means they were free
|
|
|
- defaultPaidAmountCents = 0
|
|
|
-)
|
|
|
-
|
|
|
// ListCreditsHandler is a handler for getting available credits
|
|
|
type ListCreditsHandler struct {
|
|
|
handlers.PorterHandlerWriter
|
|
|
@@ -70,70 +57,3 @@ func (c *ListCreditsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
|
c.WriteResult(w, r, credits)
|
|
|
}
|
|
|
-
|
|
|
-// ClaimReferralRewardHandler is a handler for granting credits
|
|
|
-type ClaimReferralRewardHandler struct {
|
|
|
- handlers.PorterHandlerWriter
|
|
|
-}
|
|
|
-
|
|
|
-// NewClaimReferralReward will create a new GrantCreditsHandler
|
|
|
-func NewClaimReferralReward(
|
|
|
- config *config.Config,
|
|
|
- writer shared.ResultWriter,
|
|
|
-) *ClaimReferralRewardHandler {
|
|
|
- return &ClaimReferralRewardHandler{
|
|
|
- PorterHandlerWriter: handlers.NewDefaultPorterHandler(config, nil, writer),
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-func (c *ClaimReferralRewardHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
|
- ctx, span := telemetry.NewSpan(r.Context(), "serve-claim-credits-reward")
|
|
|
- defer span.End()
|
|
|
-
|
|
|
- proj, _ := ctx.Value(types.ProjectScope).(*models.Project)
|
|
|
- user, _ := ctx.Value(types.UserScope).(*models.User)
|
|
|
-
|
|
|
- if !c.Config().BillingManager.MetronomeConfigLoaded || !proj.GetFeatureFlag(models.MetronomeEnabled, c.Config().LaunchDarklyClient) {
|
|
|
- c.WriteResult(w, r, "")
|
|
|
-
|
|
|
- telemetry.WithAttributes(span,
|
|
|
- telemetry.AttributeKV{Key: "metronome-config-exists", Value: c.Config().BillingManager.MetronomeConfigLoaded},
|
|
|
- telemetry.AttributeKV{Key: "metronome-enabled", Value: proj.GetFeatureFlag(models.MetronomeEnabled, c.Config().LaunchDarklyClient)},
|
|
|
- )
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- telemetry.WithAttributes(span,
|
|
|
- telemetry.AttributeKV{Key: "metronome-enabled", Value: true},
|
|
|
- telemetry.AttributeKV{Key: "usage-id", Value: proj.UsageID},
|
|
|
- telemetry.AttributeKV{Key: "referral-code", Value: user.ReferralCode},
|
|
|
- telemetry.AttributeKV{Key: "referral-reward-received", Value: user.ReferralRewardClaimed},
|
|
|
- )
|
|
|
-
|
|
|
- // Check if the user is eligible for the referral reward
|
|
|
- referralCount, err := c.Repo().Referral().GetReferralCountByUserID(user.ID)
|
|
|
- if err != nil {
|
|
|
- c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- if !user.ReferralRewardClaimed && referralCount >= referralRewardRequirement {
|
|
|
- // Metronome requires an expiration to be passed in, so we set it to 5 years which in
|
|
|
- // practice will mean the credits will run out before expiring
|
|
|
- expiresAt := time.Now().AddDate(5, 0, 0).Format(time.RFC3339)
|
|
|
- err := c.Config().BillingManager.MetronomeClient.CreateCreditsGrant(ctx, proj.UsageID, defaultRewardAmountCents, defaultPaidAmountCents, expiresAt)
|
|
|
- if err != nil {
|
|
|
- c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- user.ReferralRewardClaimed = true
|
|
|
- _, err = c.Repo().User().UpdateUser(user)
|
|
|
- if err != nil {
|
|
|
- c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
|
|
|
- return
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- c.WriteResult(w, r, "")
|
|
|
-}
|