id(); $t->string('title', 140); $t->string('sub_title', 200)->nullable(); $t->unsignedTinyInteger('type'); $t->boolean('status')->default(false); $t->unsignedBigInteger('start_time'); $t->unsignedBigInteger('end_time'); $t->string('lang', 10)->default('zh'); $t->unsignedInteger('sort')->default(0); $t->text('params'); $t->text('content')->nullable(); $t->string('image', 2048)->nullable(); $t->json('publish_platforms')->nullable(); $t->json('register_platforms')->nullable(); $t->boolean('register_time_limited')->default(false); $t->dateTime('register_start_time')->nullable(); $t->dateTime('register_end_time')->nullable(); $t->boolean('deposit_limited')->default(false); $t->decimal('deposit_min', 24, 2)->nullable(); $t->decimal('deposit_max', 24, 2)->nullable(); $t->boolean('show_ineligible')->default(true); $t->boolean('quota_enabled')->default(true); $t->unsignedInteger('reward_quota')->nullable(); $t->unsignedInteger('rewarded_count')->default(0); $t->decimal('budget', 24, 2)->nullable(); $t->decimal('budget_used', 24, 2)->default(0); $t->index(['type', 'status', 'lang']); $t->timestamps(); }); Schema::create('promotion_campaigns', function (Blueprint $t) { $t->unsignedBigInteger('activity_id')->primary(); $t->dateTime('first_published_at')->nullable(); $t->timestamps(); }); Schema::create('promotion_accounts', function (Blueprint $t) { $t->id(); $t->unsignedBigInteger('activity_id'); $t->unsignedBigInteger('user_id'); $t->unsignedInteger('round_no')->default(1); $t->unsignedInteger('spins')->default(0); $t->dateTime('applied_at')->nullable(); $t->text('application_snapshot')->nullable(); $t->unique(['activity_id', 'user_id']); $t->timestamps(); }); Schema::create('promotion_rounds', function (Blueprint $t) { $t->id(); $t->unsignedBigInteger('account_id'); $t->unsignedInteger('round_no'); $t->unsignedInteger('coins_cents')->default(0); $t->string('status', 16)->default('active'); $t->dateTime('started_at'); $t->unsignedBigInteger('deposit_cursor')->default(0); $t->text('bet_cursors'); $t->text('completed_tasks'); $t->dateTime('claimed_at')->nullable(); $t->unique(['account_id', 'round_no']); $t->timestamps(); }); Schema::create('promotion_task_grants', function (Blueprint $t) { $t->id(); $t->unsignedBigInteger('account_id'); $t->unsignedInteger('round_no'); $t->string('task', 24); $t->string('event_key', 80); $t->text('evidence'); $t->unique(['account_id', 'task', 'event_key'], 'promotion_task_event'); $t->timestamps(); }); Schema::create('promotion_spins', function (Blueprint $t) { $t->id(); $t->unsignedBigInteger('account_id'); $t->unsignedInteger('round_no'); $t->string('request_key', 64); $t->unsignedTinyInteger('prize_index'); $t->unsignedInteger('amount_cents'); $t->unsignedInteger('coins_cents'); $t->boolean('conditions_complete'); $t->decimal('probability', 5, 2); $t->unique(['account_id', 'request_key']); $t->timestamps(); }); Schema::create('promotion_rewards', function (Blueprint $t) { $t->id(); $t->unsignedBigInteger('activity_id'); $t->unsignedBigInteger('user_id'); $t->unsignedBigInteger('account_id'); $t->unsignedInteger('round_no'); $t->decimal('amount', 24, 2); $t->decimal('required_flow', 24, 2)->default(0); $t->string('status', 16); $t->unsignedBigInteger('credited_log_id')->nullable(); $t->unsignedBigInteger('unlocked_log_id')->nullable(); $t->text('rule_snapshot'); $t->text('flow_snapshot')->nullable(); $t->dateTime('unlocked_at')->nullable(); $t->unique(['account_id', 'round_no']); $t->timestamps(); }); Schema::create('promotion_first_deposits', function (Blueprint $t) { $t->unsignedBigInteger('user_id')->primary(); $t->unsignedBigInteger('deposit_log_id')->unique(); $t->timestamps(); }); Schema::create('promotion_presence', function (Blueprint $t) { $t->id(); $t->unsignedBigInteger('user_id'); $t->string('session_hash', 64); $t->dateTime('observed_at'); $t->index(['user_id', 'observed_at']); $t->unique(['user_id', 'session_hash', 'observed_at'], 'promotion_presence_dedup'); }); } public function down(): void { foreach (['promotion_presence', 'promotion_first_deposits', 'promotion_rewards', 'promotion_spins', 'promotion_task_grants', 'promotion_rounds', 'promotion_accounts', 'promotion_campaigns', 'promotion_activities'] as $table) Schema::dropIfExists($table); } };