Files
BetiX/database/migrations/2026_01_01_000008_create_bonus_tables.php
Dolo 0280278978
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (8.4) (push) Has been cancelled
tests / ci (8.5) (push) Has been cancelled
Initialer Laravel Commit für BetiX
2026-04-04 18:01:50 +02:00

130 lines
5.8 KiB
PHP

<?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');
}
};