id(); $table->uuid()->unique(); $table->foreignId('customer_id')->constrained()->cascadeOnDelete(); $table->foreignId('instance_id')->nullable()->constrained()->nullOnDelete(); $table->string('plan'); $table->string('term')->default('monthly'); // monthly|yearly // ── Snapshot: the conditions this customer is owed ────────────── $table->unsignedInteger('price_cents'); // net, per term $table->string('currency', 3)->default('EUR'); $table->unsignedBigInteger('quota_gb'); $table->unsignedBigInteger('traffic_gb'); $table->unsignedInteger('seats'); $table->unsignedInteger('ram_mb'); $table->unsignedInteger('cores'); $table->unsignedBigInteger('disk_gb'); $table->string('performance')->nullable(); $table->timestamp('started_at'); $table->timestamp('current_period_start'); $table->timestamp('current_period_end'); // A downgrade is scheduled, never immediate: it lands when the term // the customer already paid for runs out. $table->string('pending_plan')->nullable(); $table->timestamp('pending_effective_at')->nullable(); $table->string('status')->default('active'); // active|cancelled $table->timestamp('cancelled_at')->nullable(); $table->timestamps(); $table->index(['customer_id', 'status']); }); } public function down(): void { Schema::dropIfExists('subscriptions'); } };