draft
This commit is contained in:
120
internal/modules/common/user_payload.go
Normal file
120
internal/modules/common/user_payload.go
Normal file
@@ -0,0 +1,120 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
"stream.api/internal/database/model"
|
||||
)
|
||||
|
||||
type UserPayload struct {
|
||||
ID string `json:"id"`
|
||||
Email string `json:"email"`
|
||||
Username *string `json:"username,omitempty"`
|
||||
Avatar *string `json:"avatar,omitempty"`
|
||||
Role *string `json:"role,omitempty"`
|
||||
GoogleID *string `json:"google_id,omitempty"`
|
||||
StorageUsed int64 `json:"storage_used"`
|
||||
PlanID *string `json:"plan_id,omitempty"`
|
||||
PlanStartedAt *time.Time `json:"plan_started_at,omitempty"`
|
||||
PlanExpiresAt *time.Time `json:"plan_expires_at,omitempty"`
|
||||
PlanTermMonths *int32 `json:"plan_term_months,omitempty"`
|
||||
PlanPaymentMethod *string `json:"plan_payment_method,omitempty"`
|
||||
PlanExpiringSoon bool `json:"plan_expiring_soon"`
|
||||
WalletBalance float64 `json:"wallet_balance"`
|
||||
Language string `json:"language"`
|
||||
Locale string `json:"locale"`
|
||||
CreatedAt *time.Time `json:"created_at,omitempty"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
func BuildUserPayload(ctx context.Context, db *gorm.DB, user *model.User) (*UserPayload, error) {
|
||||
pref, err := model.FindOrCreateUserPreference(ctx, db, user.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
walletBalance, err := model.GetWalletBalance(ctx, db, user.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
language := strings.TrimSpace(model.StringValue(pref.Language))
|
||||
if language == "" {
|
||||
language = "en"
|
||||
}
|
||||
locale := strings.TrimSpace(model.StringValue(pref.Locale))
|
||||
if locale == "" {
|
||||
locale = language
|
||||
}
|
||||
|
||||
effectivePlanID := user.PlanID
|
||||
var planStartedAt *time.Time
|
||||
var planExpiresAt *time.Time
|
||||
var planTermMonths *int32
|
||||
var planPaymentMethod *string
|
||||
planExpiringSoon := false
|
||||
now := time.Now().UTC()
|
||||
|
||||
subscription, err := model.GetLatestPlanSubscription(ctx, db, user.ID)
|
||||
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, err
|
||||
}
|
||||
if err == nil {
|
||||
startedAt := subscription.StartedAt.UTC()
|
||||
expiresAt := subscription.ExpiresAt.UTC()
|
||||
termMonths := subscription.TermMonths
|
||||
paymentMethod := normalizePlanPaymentMethod(subscription.PaymentMethod)
|
||||
|
||||
planStartedAt = &startedAt
|
||||
planExpiresAt = &expiresAt
|
||||
planTermMonths = &termMonths
|
||||
planPaymentMethod = &paymentMethod
|
||||
|
||||
if expiresAt.After(now) {
|
||||
effectivePlanID = &subscription.PlanID
|
||||
planExpiringSoon = isPlanExpiringSoon(expiresAt, now)
|
||||
} else {
|
||||
effectivePlanID = nil
|
||||
}
|
||||
}
|
||||
|
||||
return &UserPayload{
|
||||
ID: user.ID,
|
||||
Email: user.Email,
|
||||
Username: user.Username,
|
||||
Avatar: user.Avatar,
|
||||
Role: user.Role,
|
||||
GoogleID: user.GoogleID,
|
||||
StorageUsed: user.StorageUsed,
|
||||
PlanID: effectivePlanID,
|
||||
PlanStartedAt: planStartedAt,
|
||||
PlanExpiresAt: planExpiresAt,
|
||||
PlanTermMonths: planTermMonths,
|
||||
PlanPaymentMethod: planPaymentMethod,
|
||||
PlanExpiringSoon: planExpiringSoon,
|
||||
WalletBalance: walletBalance,
|
||||
Language: language,
|
||||
Locale: locale,
|
||||
CreatedAt: user.CreatedAt,
|
||||
UpdatedAt: user.UpdatedAt,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func normalizePlanPaymentMethod(value string) string {
|
||||
switch strings.ToLower(strings.TrimSpace(value)) {
|
||||
case "topup":
|
||||
return "topup"
|
||||
default:
|
||||
return "wallet"
|
||||
}
|
||||
}
|
||||
|
||||
func isPlanExpiringSoon(expiresAt time.Time, now time.Time) bool {
|
||||
hoursUntilExpiry := expiresAt.Sub(now).Hours()
|
||||
const thresholdHours = 7 * 24
|
||||
return hoursUntilExpiry > 0 && hoursUntilExpiry <= thresholdHours
|
||||
}
|
||||
Reference in New Issue
Block a user