id(); $table->foreignId('post_id')->unique()->constrained('posts')->cascadeOnDelete(); // one-to-one with posts, like meetings // Owner profile: User / Organization / Bank / Admin $table->nullableMorphs('pollable'); $table->enum('status', ['draft', 'open', 'closed'])->default('draft'); $table->dateTime('opens_at')->nullable(); $table->dateTime('closes_at')->nullable(); // Voting rules for Organization / Bank / Admin profiles $table->enum('vote_scope', ['per_profile', 'per_user'])->default('per_profile'); $table->enum('member_scope', ['all_users', 'managers_coordinators'])->default('all_users'); $table->boolean('allow_vote_change')->default(false); $table->boolean('anonymous')->default(false); $table->enum('results_visibility', ['never', 'after_vote', 'after_close'])->default('never'); // Targeting (location columns mirror the mailings table) $table->boolean('filter_by_location')->default(false); $table->json('location_country_ids')->nullable(); $table->json('location_division_ids')->nullable(); $table->json('location_city_ids')->nullable(); $table->json('location_district_ids')->nullable(); $table->json('target_profile_types')->nullable(); // null = all profile types $table->date('last_login_from')->nullable(); $table->date('last_login_until')->nullable(); $table->date('registered_from')->nullable(); $table->date('registered_until')->nullable(); $table->timestamps(); $table->softDeletes(); $table->index(['status', 'opens_at', 'closes_at']); }); } public function down(): void { Schema::dropIfExists('polls'); } };