데이터 사용량 월별 보정 기준을 보강함

This commit is contained in:
seo
2026-07-02 12:50:04 +09:00
parent 89c33eba87
commit da4f48630a
2 changed files with 64 additions and 8 deletions
+61 -7
View File
@@ -28,6 +28,7 @@ const RECEIVE_GAP_LIMIT_SEC = 60;
// carrier_total_bytes / meter_adjusted_bytes 로 보정 배율을 역산해 통신사 과금 단위 계측값에 적용한다.
const DATA_CURRENT_BILLING_USAGE_BYTES = [
'2026-06' => ['total_bytes' => 120064512, 'meter_adjusted_bytes' => 129148416, 'included_bytes' => 104857600, 'coupon_registered_at' => null],
'2026-07' => ['total_bytes' => 6549504, 'meter_adjusted_bytes' => 7169536, 'included_bytes' => 104857600, 'coupon_registered_at' => null],
];
function car_db(): PDO
@@ -245,13 +246,14 @@ function monthly_data_usage(PDO $pdo): array
}
$measuredSeconds = max(1, $now->getTimestamp() - $projectionStart);
$currentBilling = current_billing_usage($monthStart->format('Y-m'));
$billingScale = billing_meter_scale($currentBilling);
$billingScaleInfo = billing_meter_scale_info($monthStart->format('Y-m'), $currentBilling);
$billingScale = $billingScaleInfo['scale'];
$billingCurrentBytes = (int)round($carrierAdjustedTotalBytes * $billingScale);
$projectedBytes = (int)round($carrierAdjustedTotalBytes / $measuredSeconds * $monthSeconds);
$billingProjectedBytes = $carrierAdjustedTotalBytes > 0
? max((int)round($projectedBytes * $billingScale), $billingCurrentBytes)
: 0;
$calibration = billing_calibration($currentBilling, $billingScale);
$calibration = billing_calibration($currentBilling, $billingScaleInfo);
if ($billingProjectedBytes <= 0) {
$billingProjectedBytes = $calibration['projected_total_bytes'];
}
@@ -315,6 +317,8 @@ function monthly_data_usage(PDO $pdo): array
'projected_service_fee_krw' => floor_krw_10($fixedFeeKrw + $projectedOverFeeKrw),
'billing_estimated_current_bytes' => $billingCurrentBytes,
'billing_meter_scale' => round($billingScale, 6),
'billing_meter_scale_source' => $billingScaleInfo['source'],
'billing_meter_scale_source_month' => $billingScaleInfo['source_month'],
'billing_remaining_bytes' => max(DATA_MONTHLY_INCLUDED_BYTES - $billingCurrentBytes, 0),
'billing_over_bytes' => $billingCurrentOverBytes,
'billing_over_fee_raw_krw' => round($billingCurrentOverFeeKrw, 2),
@@ -551,17 +555,67 @@ function billing_meter_scale(?array $currentBilling): float
return (int)($currentBilling['total_bytes'] ?? 0) / $meterAdjustedBytes;
}
function billing_calibration(?array $currentBilling, float $billingScale): array
function billing_meter_scale_info(string $month, ?array $currentBilling): array
{
$currentScale = billing_meter_scale($currentBilling);
if ($currentBilling && $currentScale > 0) {
return [
'scale' => $currentScale,
'source' => 'current_month_anchor',
'source_month' => $month,
'source_billing' => $currentBilling,
];
}
$fallbackMonth = null;
$fallbackBilling = null;
foreach (DATA_CURRENT_BILLING_USAGE_BYTES as $billingMonth => $row) {
if ($billingMonth >= $month || ($row['meter_adjusted_bytes'] ?? 0) <= 0) {
continue;
}
if ($fallbackMonth === null || $billingMonth > $fallbackMonth) {
$fallbackMonth = $billingMonth;
$fallbackBilling = current_billing_usage($billingMonth);
}
}
$fallbackScale = billing_meter_scale($fallbackBilling);
if ($fallbackBilling && $fallbackScale > 0) {
return [
'scale' => $fallbackScale,
'source' => 'previous_month_anchor',
'source_month' => $fallbackMonth,
'source_billing' => $fallbackBilling,
];
}
return [
'scale' => 1.0,
'source' => 'meter_adjusted_usage',
'source_month' => null,
'source_billing' => null,
];
}
function billing_calibration(?array $currentBilling, array $billingScaleInfo): array
{
$estimatedCurrentBytes = $currentBilling ? (int)$currentBilling['total_bytes'] : 0;
$source = $currentBilling ? 'carrier_scaled_meter_usage' : 'meter_adjusted_usage';
$billingScale = (float)($billingScaleInfo['scale'] ?? 1.0);
$source = $billingScaleInfo['source'] ?? 'meter_adjusted_usage';
$sourceBilling = $billingScaleInfo['source_billing'] ?? null;
$note = match ($source) {
'current_month_anchor' => 'T world 현재월 사용량으로 0.5KB 올림 TCP 세션 누적값의 보정 배율을 역산합니다. TCP payload 계측값도 별도로 유지합니다.',
'previous_month_anchor' => '현재월 T world 기준점이 아직 없어서 가장 최근 월 보정 배율을 임시로 사용합니다. 현재월 기준점이 기록되면 그 배율로 다시 계산합니다.',
default => '통신사형 사용량은 과금 대상 TCP 세션을 0.5KB 단위로 올림 처리합니다. 순수 연결 실패와 긴 수신 공백은 제외합니다.',
};
return [
'mode' => $source,
'note' => $currentBilling
? 'Carrier portal current usage is used to reverse-calculate a billing scale for 0.5KB rounded TCP session usage. Payload metered usage remains available separately.'
: 'Carrier-like usage rounds each billable TCP session to the 0.5KB billing unit. Pure connect failures and longer receive gaps are excluded.',
'note' => $note,
'current_billing' => $currentBilling,
'scale_source_billing' => $sourceBilling,
'billing_meter_scale_source' => $source,
'billing_meter_scale_source_month' => $billingScaleInfo['source_month'] ?? null,
'billing_meter_scale' => round($billingScale, 6),
'projected_total_bytes' => 0,
'projected_total_mb' => 0.0,