feat: implement AI styling foundation and billing scope rework
This commit is contained in:
67
app/Services/AiEditing/AiUsageLedgerService.php
Normal file
67
app/Services/AiEditing/AiUsageLedgerService.php
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\AiEditing;
|
||||
|
||||
use App\Models\AiEditRequest;
|
||||
use App\Models\AiUsageLedger;
|
||||
use App\Models\Event;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class AiUsageLedgerService
|
||||
{
|
||||
public function __construct(private readonly AiStylingEntitlementService $entitlements) {}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $metadata
|
||||
*/
|
||||
public function recordDebitForRequest(AiEditRequest $request, ?float $costUsd = null, array $metadata = []): AiUsageLedger
|
||||
{
|
||||
return DB::transaction(function () use ($request, $costUsd, $metadata): AiUsageLedger {
|
||||
$lockedRequest = AiEditRequest::query()
|
||||
->whereKey($request->id)
|
||||
->lockForUpdate()
|
||||
->firstOrFail();
|
||||
|
||||
$existing = AiUsageLedger::query()
|
||||
->where('request_id', $lockedRequest->id)
|
||||
->where('entry_type', AiUsageLedger::TYPE_DEBIT)
|
||||
->first();
|
||||
if ($existing) {
|
||||
return $existing;
|
||||
}
|
||||
|
||||
$resolvedCost = $costUsd;
|
||||
if ($resolvedCost === null || $resolvedCost < 0) {
|
||||
$resolvedCost = (float) config('ai-editing.billing.default_unit_cost_usd', 0.01);
|
||||
}
|
||||
|
||||
$event = Event::query()->find($lockedRequest->event_id);
|
||||
$entitlement = $event ? $this->entitlements->resolveForEvent($event) : [
|
||||
'allowed' => false,
|
||||
'granted_by' => null,
|
||||
];
|
||||
|
||||
$packageContext = $entitlement['granted_by'] === 'package'
|
||||
? 'package_included'
|
||||
: ($entitlement['granted_by'] === 'addon' ? 'addon_unlock' : 'unentitled');
|
||||
|
||||
return AiUsageLedger::query()->create([
|
||||
'tenant_id' => $lockedRequest->tenant_id,
|
||||
'event_id' => $lockedRequest->event_id,
|
||||
'request_id' => $lockedRequest->id,
|
||||
'entry_type' => AiUsageLedger::TYPE_DEBIT,
|
||||
'quantity' => 1,
|
||||
'unit_cost_usd' => $resolvedCost,
|
||||
'amount_usd' => $resolvedCost,
|
||||
'currency' => 'USD',
|
||||
'package_context' => $packageContext,
|
||||
'recorded_at' => now(),
|
||||
'metadata' => array_merge([
|
||||
'provider' => $lockedRequest->provider,
|
||||
'provider_model' => $lockedRequest->provider_model,
|
||||
'granted_by' => $entitlement['granted_by'],
|
||||
], $metadata),
|
||||
]);
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user