Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions config/cloudplans.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
'free' => [
'id' => 'free',
'name' => 'Free',
'token_allowance' => (int) env('CLOUD_PLAN_FREE_TOKEN_ALLOWANCE', 0),
'interval' => 'lifetime',
'features' => [
'Up to 3 wallets',
Expand All @@ -83,6 +84,7 @@
'monthly' => [
'id' => 'monthly',
'name' => 'Monthly',
'token_allowance' => (int) env('CLOUD_PLAN_MONTHLY_TOKEN_ALLOWANCE', 50000),
'interval' => 'month',
'features' => [
'Unlimited categories and wallets',
Expand All @@ -97,6 +99,7 @@
],
'yearly' => [
'id' => 'yearly',
'token_allowance' => (int) env('CLOUD_PLAN_YEARLY_TOKEN_ALLOWANCE', 50000),
'name' => 'Yearly',
'interval' => 'year',
'features' => [
Expand Down
96 changes: 96 additions & 0 deletions src/Support/CloudEntitlements.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
<?php

namespace Trakli\Cloud\Support;

use App\Contracts\Entitlements;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Carbon;

class CloudEntitlements implements Entitlements
{
/**
* Determine if the owner is allowed to use a given feature.
*/
public function allows(?Model $owner, string $feature): bool

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The allows method is currently hardcoded to return true, which bypasses all plan-based feature restrictions. This should delegate to the check method to ensure that entitlements are properly enforced across the application.

Suggested change
public function allows(?Model $owner, string $feature): bool
public function allows(?Model $owner, string $feature): bool
{
return $this->check($owner, $feature)->allowed();
}

{
return true;
}

/**
* Get the limit for a given key.
*/
public function limit(?Model $owner, string $key): ?int
{
return null;
}

/**
* Get the remaining token allowance for the current period.
*/
public function remaining(?Model $owner, string $meter): int|float
{
if ($meter !== 'ai_tokens') {
return INF;
}

// If in freemode, return unlimited tokens
if (config('cloudplans.freemode_enabled', false)) {
return INF;
}

if (!$owner) {
return 0;
}

// Get owner's current plan via Cashier
$planCode = $this->getPlanCode($owner);
if ($planCode === 'free') {
Comment thread
kofimokome marked this conversation as resolved.
Outdated
return INF;
}

$plan = config("cloudplans.plans.{$planCode}");
if (!$plan) {
return 0;
}

$allowance = $plan['token_allowance'] ?? 0;
if ($allowance <= 0) {
return 0;
}

$periodStart = Carbon::now()->startOfMonth();
$used = method_exists($owner, 'tokensUsed') ? $owner->tokensUsed($periodStart) : 0;

return max(0, $allowance - $used);
}

/**
* Consume a given amount of tokens for the current period.
*/
public function consume(?Model $owner, string $meter, int $amount): void
{
// Handled in trakli core via whilesmart/eloquent-agent-metrics
}

/**
* Get the active plan code for the owner via Cashier.
*/
private function getPlanCode(Model $owner): string
{
/** @var \Trakli\Cloud\Models\BillingCustomer|null $billingCustomer */
$billingCustomer = \Trakli\Cloud\Models\BillingCustomer::where('user_id', $owner->getKey())->first();
if ($billingCustomer) {
if ($billingCustomer->subscribed('monthly')) {
return 'monthly';
}
if ($billingCustomer->subscribed('yearly')) {
return 'yearly';
}
return 'free';
}

return 'free';
}
}