removed all references to credits. now credits are completely replaced by addons.

This commit is contained in:
Codex Agent
2025-12-01 15:50:17 +01:00
parent b8e515a03c
commit 28539754a7
76 changed files with 97 additions and 2533 deletions

View File

@@ -17,7 +17,6 @@ class PurchaseHistoryFactory extends Factory
'id' => (string) Str::uuid(),
'tenant_id' => Tenant::factory(),
'package_id' => $this->faker->randomElement(['starter', 'pro', 'enterprise']),
'credits_added' => $this->faker->numberBetween(1, 10),
'price' => $this->faker->randomFloat(2, 9, 199),
'currency' => 'EUR',
'platform' => $this->faker->randomElement(['tenant-app', 'ios', 'android']),

View File

@@ -20,7 +20,6 @@ class TenantFactory extends Factory
'name' => $name,
'slug' => $slug,
'contact_email' => $contactEmail,
'event_credits_balance' => $this->faker->numberBetween(1, 20),
'subscription_tier' => $this->faker->randomElement(['free', 'starter', 'pro']),
'subscription_expires_at' => $this->faker->dateTimeBetween('now', '+1 year'),
'is_active' => true,
@@ -62,9 +61,6 @@ class TenantFactory extends Factory
public function withLowCredits(): static
{
return $this->state(fn (array $attributes) => [
'event_credits_balance' => 1,
]);
return $this->state(fn (array $attributes) => $attributes);
}
}

View File

@@ -18,8 +18,6 @@ return new class extends Migration
$table->string('contact_name')->nullable();
$table->string('contact_email')->nullable();
$table->string('contact_phone')->nullable();
$table->integer('event_credits_balance')->default(1);
$table->timestamp('free_event_granted_at')->nullable();
$table->integer('max_photos_per_event')->default(500);
$table->integer('max_storage_mb')->default(1024);
$table->json('features')->nullable();
@@ -39,6 +37,11 @@ return new class extends Migration
$table->string('email')->nullable()->after('contact_phone');
});
}
if (Schema::hasColumn('tenants', 'event_credits_balance')) {
Schema::table('tenants', function (Blueprint $table) {
$table->dropColumn(['event_credits_balance', 'free_event_granted_at']);
});
}
if (!Schema::hasColumn('tenants', 'stripe_account_id')) {
Schema::table('tenants', function (Blueprint $table) {
$table->string('stripe_account_id')->nullable()->after('features');
@@ -106,4 +109,4 @@ return new class extends Migration
Schema::dropIfExists('tenants');
}
}
};
};

View File

@@ -141,7 +141,6 @@ return new class extends Migration
$table->bigIncrements('id');
$table->foreignId('tenant_id')->constrained('tenants');
$table->unsignedBigInteger('package_id');
$table->integer('credits_added')->default(0);
$table->decimal('price', 10, 2)->default(0);
$table->string('currency', 3)->default('EUR');
$table->string('platform', 50);
@@ -158,7 +157,7 @@ return new class extends Migration
if (Schema::hasTable('tenants')) {
if (! Schema::hasColumn('tenants', 'subscription_tier')) {
Schema::table('tenants', function (Blueprint $table) {
$table->string('subscription_tier')->default('free')->after('event_credits_balance');
$table->string('subscription_tier')->default('free')->after('email');
});
}
if (! Schema::hasColumn('tenants', 'subscription_status')) {
@@ -178,82 +177,8 @@ return new class extends Migration
}
}
// Idempotent migration from credits to packages (only if old tables exist and new don't have data)
if (Schema::hasTable('event_credits_ledger') && DB::table('tenant_packages')->count() == 0) {
// Migrate tenant credits to tenant_packages (Free package)
$freePackageId = DB::table('packages')->where('name', 'Free/Test')->value('id');
if ($freePackageId) {
DB::table('tenants')->where('event_credits_balance', '>', 0)->chunk(100, function ($tenants) use ($freePackageId) {
foreach ($tenants as $tenant) {
DB::table('tenant_packages')->insertOrIgnore([
'tenant_id' => $tenant->id,
'package_id' => $freePackageId,
'price' => 0.00,
'purchased_at' => $tenant->free_event_granted_at ?? now(),
'expires_at' => now()->addDays(30),
'used_events' => min($tenant->event_credits_balance, 1),
'active' => true,
'created_at' => now(),
'updated_at' => now(),
]);
DB::table('package_purchases')->insertOrIgnore([
'tenant_id' => $tenant->id,
'event_id' => null,
'package_id' => $freePackageId,
'provider_id' => 'migration_free',
'price' => 0.00,
'type' => 'reseller_subscription',
'metadata' => json_encode(['migrated_from_credits' => $tenant->event_credits_balance]),
'ip_address' => null,
'user_agent' => null,
'refunded' => false,
'created_at' => now(),
'updated_at' => now(),
]);
}
});
// Migrate event purchases if old data exists
if (Schema::hasTable('event_purchases')) {
DB::table('event_purchases')->join('events', 'event_purchases.event_id', '=', 'events.id')->chunk(100, function ($purchases) use ($freePackageId) {
foreach ($purchases as $purchase) {
DB::table('event_packages')->insertOrIgnore([
'event_id' => $purchase->event_id,
'package_id' => $freePackageId,
'purchased_price' => $purchase->amount ?? 0.00,
'purchased_at' => $purchase->purchased_at ?? now(),
'used_photos' => 0,
'created_at' => now(),
'updated_at' => now(),
]);
DB::table('package_purchases')->insertOrIgnore([
'tenant_id' => $purchase->tenant_id,
'event_id' => $purchase->event_id,
'package_id' => $freePackageId,
'provider_id' => $purchase->provider ?? 'migration',
'price' => $purchase->amount ?? 0.00,
'type' => 'endcustomer_event',
'metadata' => json_encode(['migrated_from_event_purchases' => true]),
'ip_address' => null,
'user_agent' => null,
'refunded' => false,
'created_at' => now(),
'updated_at' => now(),
]);
}
});
}
}
}
// Conditional drop of old credits tables and fields (only if migration happened or old structures exist)
if (Schema::hasTable('event_credits_ledger')) {
Schema::dropIfExists('event_credits_ledger');
}
// Keep legacy event_purchases table for compatibility with existing flows/resources.
if (Schema::hasTable('purchase_history') && DB::table('package_purchases')->count() > 0) { // Only drop if new data exists
Schema::dropIfExists('event_credits_ledger');
if (Schema::hasTable('purchase_history') && DB::table('package_purchases')->count() > 0) {
Schema::dropIfExists('purchase_history');
}
@@ -279,7 +204,6 @@ return new class extends Migration
$table->id();
$table->foreignId('tenant_id')->constrained()->cascadeOnDelete();
$table->string('package_id', 255);
$table->integer('credits_added')->default(0);
$table->decimal('price', 10, 2)->default(0);
$table->string('provider_id');
$table->timestamps();

View File

@@ -70,7 +70,6 @@ class DemoTenantSeeder extends Seeder
'email' => $user->email,
'is_active' => true,
'is_suspended' => false,
'event_credits_balance' => 0,
'subscription_tier' => $package->type,
'subscription_status' => 'active',
'settings' => [

View File

@@ -120,7 +120,6 @@ class DemoLifecycleSeeder extends Seeder
$tenant = $this->createTenant('storycraft-weddings', [
'name' => 'Storycraft Weddings',
'contact_email' => 'hello@storycraft-weddings.demo',
'event_credits_balance' => 0,
'subscription_tier' => 'free',
'subscription_status' => 'free',
'subscription_expires_at' => null,
@@ -135,7 +134,6 @@ class DemoLifecycleSeeder extends Seeder
$tenant = $this->createTenant('lumen-moments', [
'name' => 'Lumen Moments',
'contact_email' => 'hello@lumen-moments.demo',
'event_credits_balance' => 2,
'subscription_tier' => 'starter',
'subscription_status' => 'active',
'is_active' => true,
@@ -200,7 +198,6 @@ class DemoLifecycleSeeder extends Seeder
$tenant = $this->createTenant('viewfinder-studios', [
'name' => 'Viewfinder Studios',
'contact_email' => 'team@viewfinder.demo',
'event_credits_balance' => 0,
'subscription_tier' => 'reseller',
'subscription_status' => 'active',
'is_active' => true,
@@ -272,7 +269,6 @@ class DemoLifecycleSeeder extends Seeder
'subscription_expires_at' => Carbon::now()->subMonths(2),
'is_active' => false,
'is_suspended' => false,
'event_credits_balance' => 0,
]);
$this->createTenantAdmin($tenant, 'support@pixelco.demo', role: 'member');