Skip to content

Commit

Permalink
feat: #200 reset deployments quota each day
Browse files Browse the repository at this point in the history
  • Loading branch information
bohdan-shulha committed Sep 24, 2024
1 parent 9e815d7 commit a6490df
Show file tree
Hide file tree
Showing 9 changed files with 86 additions and 29 deletions.
1 change: 1 addition & 0 deletions app/Http/Controllers/TeamQuotasController.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public function index(Team $team)
'currentUsage' => $quota->currentUsage(),
'maxUsage' => $quota->maxUsage,
'isSoftQuota' => $quota->isSoftQuota,
'resetPeriod' => $quota->resetPeriod,
'almostQuotaReached' => $quota->almostQuotaReached(),
'isIntrinsic' => $key === 'swarms', // Mark swarms as intrinsic
];
Expand Down
3 changes: 2 additions & 1 deletion app/Models/PricingPlan/ItemQuota.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ public function __construct(
public string $name,
public int $maxUsage,
protected Closure $getCurrentUsage,
public bool $isSoftQuota = false
public bool $isSoftQuota = false,
public ?string $resetPeriod = null
) {}

public function ensureQuota(): void
Expand Down
14 changes: 9 additions & 5 deletions app/Models/Team.php
Original file line number Diff line number Diff line change
Expand Up @@ -186,25 +186,29 @@ public function quotas(): UsageQuotas
name: 'Nodes',
maxUsage: max($plan->quotas['nodes']['limit'], $override->nodes),
getCurrentUsage: fn () => $this->nodes()->count(),
isSoftQuota: $plan->quotas['nodes']['soft']
isSoftQuota: $plan->quotas['nodes']['soft'],
resetPeriod: $plan->quotas['nodes']['reset_period']
),
new ItemQuota(
name: 'Swarms',
maxUsage: max($plan->quotas['swarms']['limit'], $override->swarms),
getCurrentUsage: fn () => $this->swarms()->count(),
isSoftQuota: $plan->quotas['swarms']['soft']
isSoftQuota: $plan->quotas['swarms']['soft'],
resetPeriod: $plan->quotas['swarms']['reset_period']
),
new ItemQuota(
name: 'Services',
maxUsage: max($plan->quotas['services']['limit'], $override->services),
getCurrentUsage: fn () => $this->services()->count(),
isSoftQuota: $plan->quotas['services']['soft']
isSoftQuota: $plan->quotas['services']['soft'],
resetPeriod: $plan->quotas['services']['reset_period']
),
new ItemQuota(
name: 'Deployments',
maxUsage: max($plan->quotas['deployments']['limit'], $override->deployments),
getCurrentUsage: fn () => $this->deployments()->count(),
isSoftQuota: $plan->quotas['deployments']['soft']
getCurrentUsage: fn () => $this->deployments()->where('created_at', '>=', now()->startOfDay())->count(),
isSoftQuota: $plan->quotas['deployments']['soft'],
resetPeriod: $plan->quotas['deployments']['reset_period']
)
);
}
Expand Down
36 changes: 18 additions & 18 deletions config/billing.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@
'description' => 'Perfect plan to try the service or host non-critical applications',
'product_id' => env('PADDLE_PLAN_HOBBY_PRODUCT_ID'),
'price_id' => env('PADDLE_PLAN_HOBBY_PRICE_ID'),
'billing_cycle' => 'yearly', // Added billing cycle
'billing_cycle' => 'yearly',
'quotas' => [
'nodes' => ['limit' => 1, 'soft' => false],
'swarms' => ['limit' => 1, 'soft' => false],
'services' => ['limit' => 20, 'soft' => true],
'deployments' => ['limit' => 100, 'soft' => true],
'nodes' => ['limit' => 1, 'soft' => false, 'reset_period' => null],
'swarms' => ['limit' => 1, 'soft' => false, 'reset_period' => null],
'services' => ['limit' => 20, 'soft' => true, 'reset_period' => null],
'deployments' => ['limit' => 100, 'soft' => true, 'reset_period' => 'daily'],
],
],
[
Expand All @@ -25,12 +25,12 @@
'description' => 'Need more power or an additional features? This is your choice!',
'product_id' => env('PADDLE_PLAN_STARTUP_PRODUCT_ID'),
'price_id' => env('PADDLE_PLAN_STARTUP_PRICE_ID'),
'billing_cycle' => 'monthly', // Added billing cycle
'billing_cycle' => 'monthly',
'quotas' => [
'nodes' => ['limit' => 5, 'soft' => true],
'swarms' => ['limit' => 1, 'soft' => false],
'services' => ['limit' => 10, 'soft' => true],
'deployments' => ['limit' => 100, 'soft' => true],
'nodes' => ['limit' => 5, 'soft' => true, 'reset_period' => null],
'swarms' => ['limit' => 1, 'soft' => false, 'reset_period' => null],
'services' => ['limit' => 10, 'soft' => true, 'reset_period' => null],
'deployments' => ['limit' => 100, 'soft' => true, 'reset_period' => 'daily'],
],
],
],
Expand All @@ -41,10 +41,10 @@
'product_id' => null,
'price_id' => null,
'quotas' => [
'nodes' => ['limit' => 1, 'soft' => false],
'swarms' => ['limit' => 1, 'soft' => false],
'services' => ['limit' => 3, 'soft' => false],
'deployments' => ['limit' => 20, 'soft' => false],
'nodes' => ['limit' => 1, 'soft' => false, 'reset_period' => null],
'swarms' => ['limit' => 1, 'soft' => false, 'reset_period' => null],
'services' => ['limit' => 3, 'soft' => false, 'reset_period' => null],
'deployments' => ['limit' => 20, 'soft' => false, 'reset_period' => 'daily'],
],
],
'selfHostedPlan' => [
Expand All @@ -54,10 +54,10 @@
'product_id' => null,
'price_id' => null,
'quotas' => [
'nodes' => ['limit' => 1000, 'soft' => true],
'swarms' => ['limit' => 1, 'soft' => false],
'services' => ['limit' => 5000, 'soft' => true],
'deployments' => ['limit' => 100000, 'soft' => true],
'nodes' => ['limit' => 1000, 'soft' => true, 'reset_period' => null],
'swarms' => ['limit' => 1, 'soft' => false, 'reset_period' => null],
'services' => ['limit' => 5000, 'soft' => true, 'reset_period' => null],
'deployments' => ['limit' => 100000, 'soft' => true, 'reset_period' => 'daily'],
],
],
],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
public function up(): void
{
Schema::table('teams', function (Blueprint $table) {
// Change the column type to jsonb
$table->jsonb('quotas_override')->default(json_encode([
'nodes' => 0,
'swarms' => 0,
'services' => 0,
'deployments' => 0,
]))->change();
});
}

public function down(): void
{
Schema::table('teams', function (Blueprint $table) {
// Revert the column type back to json
$table->json('quotas_override')->default(json_encode([
'nodes' => 0,
'swarms' => 0,
'services' => 0,
'deployments' => 0,
]))->change();
});
}
};
5 changes: 4 additions & 1 deletion resources/js/Pages/Nodes/Partials/DockerRegistries.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ const props = defineProps({
const { encrypt } = useCrypto();
const form = useForm({
registries: props.swarm.data.registries,
registries: props.swarm.data.registries.map((registry) => ({
...registry,
password: null,
})),
});
const makeId = (prefix) => prefix + "-" + Math.random().toString(36).slice(2);
Expand Down
5 changes: 4 additions & 1 deletion resources/js/Pages/Nodes/Partials/S3Storages.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ const props = defineProps({
const { encrypt } = useCrypto();
const form = useForm({
s3Storages: props.swarm.data.s3Storages,
s3Storages: props.swarm.data.s3Storages.map((storage) => ({
...storage,
secretKey: null,
})),
});
const addStorage = () => {
Expand Down
16 changes: 13 additions & 3 deletions resources/js/Pages/Teams/Quotas.vue
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,12 @@ const quotaDescriptions = {
swarms: "The maximum number of swarms you can create for your team.",
services:
"The maximum number of services you can deploy across all swarms.",
deployments: "The maximum number of deployments you can perform.",
deployments: "The maximum number of deployments you can perform per day.",
};
function getResetPeriodText(quota: ItemQuota): string | null {
return quota.resetPeriod === "daily" ? "Resets daily" : null;
}
</script>

<template>
Expand Down Expand Up @@ -116,7 +120,7 @@ const quotaDescriptions = {
</span>
</div>
<div
class="mt-1 text-xs text-gray-500 dark:text-gray-400"
class="mt-1 text-xs text-gray-500 dark:text-gray-400 flex items-center"
>
{{
quotaDescriptions[
Expand All @@ -130,14 +134,20 @@ const quotaDescriptions = {
contact
<a
href="mailto:[email protected]"
class="text-blue-600 hover:text-blue-800"
class="text-blue-600 hover:text-blue-800 ml-1"
>[email protected]</a
>.
</span>
<span v-if="quota.isIntrinsic">
This limit is set by the system architecture and
cannot be increased.
</span>
<span
v-if="getResetPeriodText(quota)"
class="ml-2 px-2 py-0.5 bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-300 rounded-full font-medium"
>
{{ getResetPeriodText(quota) }}
</span>
</div>
<div class="mt-2">
<div
Expand Down
1 change: 1 addition & 0 deletions resources/js/types/quotas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export interface ItemQuota {
isSoftQuota: boolean;
almostQuotaReached: boolean;
isIntrinsic: boolean;
resetPeriod: string;
}

export interface UsageQuotas {
Expand Down

0 comments on commit a6490df

Please sign in to comment.