Initialer Laravel Commit für BetiX
This commit is contained in:
129
database/migrations/2026_01_01_000008_create_bonus_tables.php
Normal file
129
database/migrations/2026_01_01_000008_create_bonus_tables.php
Normal file
@@ -0,0 +1,129 @@
|
||||
<?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
|
||||
{
|
||||
// ---------------------------------------------------------------
|
||||
// VIP REWARDS (claimed level-up rewards)
|
||||
// ---------------------------------------------------------------
|
||||
Schema::create('vip_rewards', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
|
||||
$table->integer('level');
|
||||
$table->decimal('amount', 10, 2);
|
||||
$table->timestamp('claimed_at');
|
||||
$table->timestamps();
|
||||
|
||||
$table->unique(['user_id', 'level']); // Prevent double-claiming
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// BONUSES (admin-created bonus campaigns)
|
||||
// ---------------------------------------------------------------
|
||||
Schema::create('bonuses', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('title');
|
||||
$table->string('type')->nullable(); // welcome | reload | spins
|
||||
$table->decimal('amount_value', 18, 8)->nullable();
|
||||
$table->string('amount_unit', 32)->nullable(); // USD | BTC | PERCENT | SPINS
|
||||
$table->decimal('min_deposit', 18, 8)->nullable();
|
||||
$table->decimal('max_amount', 18, 8)->nullable();
|
||||
$table->string('currency', 16)->nullable();
|
||||
$table->string('code')->nullable();
|
||||
$table->string('status')->default('draft'); // draft | active | paused | expired
|
||||
$table->timestamp('starts_at')->nullable();
|
||||
$table->timestamp('expires_at')->nullable();
|
||||
$table->json('rules')->nullable();
|
||||
$table->text('description')->nullable();
|
||||
$table->foreignId('created_by')->nullable()->constrained('users')->nullOnDelete();
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
|
||||
$table->index(['status', 'starts_at', 'expires_at']);
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// PROMOS (promo code system)
|
||||
// ---------------------------------------------------------------
|
||||
Schema::create('promos', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('code')->unique(); // Uppercase normalized
|
||||
$table->string('description')->nullable();
|
||||
$table->decimal('bonus_amount', 16, 4)->default(0);
|
||||
$table->unsignedInteger('wager_multiplier')->default(0);
|
||||
$table->unsignedInteger('per_user_limit')->default(1);
|
||||
$table->unsignedInteger('global_limit')->nullable();
|
||||
$table->timestamp('starts_at')->nullable();
|
||||
$table->timestamp('ends_at')->nullable();
|
||||
$table->decimal('min_deposit', 16, 4)->nullable();
|
||||
$table->unsignedInteger('bonus_expires_days')->nullable();
|
||||
$table->boolean('is_active')->default(true);
|
||||
$table->timestamps();
|
||||
|
||||
$table->index(['is_active', 'starts_at', 'ends_at']);
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// PROMO USAGES (per-use audit)
|
||||
// ---------------------------------------------------------------
|
||||
Schema::create('promo_usages', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('promo_id')->constrained('promos')->cascadeOnDelete();
|
||||
$table->foreignId('user_id')->constrained('users')->cascadeOnDelete();
|
||||
$table->timestamp('used_at');
|
||||
$table->string('ip', 45)->nullable();
|
||||
$table->text('user_agent')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->unique(['promo_id', 'user_id', 'used_at']);
|
||||
$table->index(['user_id', 'promo_id']);
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// PROMO CLAIMS (anti-abuse: one entry per user per promo)
|
||||
// ---------------------------------------------------------------
|
||||
Schema::create('promo_claims', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
|
||||
$table->foreignId('promo_id')->constrained()->cascadeOnDelete();
|
||||
$table->string('ip_address')->nullable();
|
||||
$table->string('device_hash')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->index(['user_id', 'promo_id']);
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// USER BONUSES (active bonus progress per user)
|
||||
// ---------------------------------------------------------------
|
||||
Schema::create('user_bonuses', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('user_id')->constrained('users')->cascadeOnDelete();
|
||||
$table->foreignId('promo_id')->nullable()->constrained('promos')->nullOnDelete();
|
||||
$table->decimal('amount', 16, 4);
|
||||
$table->decimal('wager_required', 16, 4)->default(0);
|
||||
$table->decimal('wager_progress', 16, 4)->default(0);
|
||||
$table->timestamp('expires_at')->nullable();
|
||||
$table->boolean('is_active')->default(true);
|
||||
$table->timestamp('completed_at')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->index(['user_id', 'is_active']);
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('user_bonuses');
|
||||
Schema::dropIfExists('promo_claims');
|
||||
Schema::dropIfExists('promo_usages');
|
||||
Schema::dropIfExists('promos');
|
||||
Schema::dropIfExists('bonuses');
|
||||
Schema::dropIfExists('vip_rewards');
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user