package growth import "slices" type PeerState string const ( PeerReady PeerState = "READY" PeerSuppressed PeerState = "SUPPRESSED" ) type PeerMerchantValue struct { PaidSessions int64 `json:"paidSessions"` SessionCount int64 `json:"sessionCount"` } type PeerInput struct { TerminalScoped bool `json:"terminalScoped"` MerchantPaidSessions int64 `json:"merchantPaidSessions"` Peers []PeerMerchantValue `json:"peers"` } type PeerResult struct { State PeerState `json:"state"` Reason SuppressionReason `json:"reason,omitempty"` EligiblePeerCount int `json:"eligiblePeerCount"` CombinedPeerSessions int64 `json:"combinedPeerSessions"` MedianPaidSessions int64 `json:"medianPaidSessions"` PercentileBPS int64 `json:"percentileBps"` } func EvaluatePeer(input PeerInput) PeerResult { result := PeerResult{State: PeerSuppressed, EligiblePeerCount: len(input.Peers)} if input.TerminalScoped { result.Reason = SuppressionTerminalScope return result } values := make([]int64, 0, len(input.Peers)) for _, peer := range input.Peers { result.CombinedPeerSessions += peer.SessionCount values = append(values, peer.PaidSessions) } if len(values) < 10 || result.CombinedPeerSessions < 1_000 { result.Reason = SuppressionInsufficientCohort return result } slices.Sort(values) result.State = PeerReady result.MedianPaidSessions = median(values) var atOrBelow int64 for _, value := range values { if input.MerchantPaidSessions >= value { atOrBelow++ } } result.PercentileBPS = atOrBelow * 10_000 / int64(len(values)) return result }