diff --git a/app/Console/Commands/SendPriceExperimentFunnelReportCommand.php b/app/Console/Commands/SendPriceExperimentFunnelReportCommand.php index c5842838..e5ac0554 100644 --- a/app/Console/Commands/SendPriceExperimentFunnelReportCommand.php +++ b/app/Console/Commands/SendPriceExperimentFunnelReportCommand.php @@ -154,8 +154,8 @@ class SendPriceExperimentFunnelReportCommand extends Command continue; } - [$low, $high2] = $this->significance->wilsonInterval($k, $n); - $lines[] = sprintf(' %-8s %6s [%6s – %6s] (n=%d)', $label, $this->percent($k / $n), $this->percent($low), $this->percent($high2), $n); + [$lower, $upper] = $this->significance->wilsonInterval($k, $n); + $lines[] = sprintf(' %-8s %6s [%6s – %6s] (n=%d)', $label, $this->percent($k / $n), $this->percent($lower), $this->percent($upper), $n); $arms[$key] = new BinomialProportion($label, $k, $n); } @@ -171,12 +171,19 @@ class SendPriceExperimentFunnelReportCommand extends Command return $lines; } + /** + * @param array $row + */ private function cmMean(array $row): float { return $row['assignedMature'] > 0 ? (float) $row['contributionMarginCents'] / $row['assignedMature'] : 0.0; } - /** Sample variance (nāˆ’1) of per-user CM, from the accumulated moments. */ + /** + * Sample variance (nāˆ’1) of per-user CM, from the accumulated moments. + * + * @param array $row + */ private function cmVariance(array $row): float { $n = (int) $row['assignedMature']; diff --git a/app/Services/Stats/PriceExperimentFunnelCollector.php b/app/Services/Stats/PriceExperimentFunnelCollector.php index c658c9b0..aa10547a 100644 --- a/app/Services/Stats/PriceExperimentFunnelCollector.php +++ b/app/Services/Stats/PriceExperimentFunnelCollector.php @@ -31,23 +31,6 @@ use Laravel\Cashier\Subscription; * Enable Banking actually bills us; API-key providers are free). It is symmetric * across arms, so it biases absolute CM but not the between-arm comparison. Make it * per-provider only if absolute margin ever needs to be trusted. - * - * @param int $costPerConnectionCents flat estimated monthly cost per active connection - * @return array{ - * startedAt: ?CarbonImmutable, - * currency: string, - * revenueAvailable: bool, - * costPerConnectionCents: int, - * decisionWindowDays: int, - * variants: array - * } */ class PriceExperimentFunnelCollector { @@ -56,6 +39,24 @@ class PriceExperimentFunnelCollector public function __construct(private MonthlyEquivalentPrices $prices) {} + /** + * @param int $costPerConnectionCents flat estimated monthly cost per active connection + * @return array{ + * startedAt: ?CarbonImmutable, + * currency: string, + * revenueAvailable: bool, + * costPerConnectionCents: int, + * decisionWindowDays: int, + * variants: array + * } + */ public function collect(int $costPerConnectionCents = 40): array { $startedValue = config('subscriptions.price_experiment.started_at');