update
This commit is contained in:
1
database/data/countries-fallback.json
Normal file
1
database/data/countries-fallback.json
Normal file
File diff suppressed because one or more lines are too long
38
database/factories/CountryFactory.php
Normal file
38
database/factories/CountryFactory.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Models\Country;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
/**
|
||||
* @extends Factory<Country>
|
||||
*/
|
||||
class CountryFactory extends Factory
|
||||
{
|
||||
protected $model = Country::class;
|
||||
|
||||
public function definition(): array
|
||||
{
|
||||
$iso2 = fake()->unique()->lexify('??');
|
||||
$iso3 = fake()->unique()->lexify('???');
|
||||
|
||||
return [
|
||||
'iso2' => strtoupper($iso2),
|
||||
'iso3' => strtoupper($iso3),
|
||||
'numeric_code' => str_pad((string) fake()->numberBetween(1, 999), 3, '0', STR_PAD_LEFT),
|
||||
'name_common' => fake()->unique()->country(),
|
||||
'name_official' => fake()->company().' Republic',
|
||||
'region' => fake()->randomElement(['Europe', 'Americas', 'Africa', 'Asia', 'Oceania']),
|
||||
'subregion' => fake()->randomElement(['Central Europe', 'North America', 'Western Africa', 'Eastern Asia']),
|
||||
'flag_svg_url' => 'https://example.test/flags/'.strtolower($iso2).'.svg',
|
||||
'flag_png_url' => 'https://example.test/flags/'.strtolower($iso2).'.png',
|
||||
'flag_emoji' => null,
|
||||
'active' => true,
|
||||
'sort_order' => 1000,
|
||||
'is_featured' => false,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -40,13 +40,18 @@ return new class extends Migration
|
||||
});
|
||||
|
||||
if (Schema::hasColumn('stories', 'author_id') && Schema::hasTable('stories_authors')) {
|
||||
DB::statement(<<<'SQL'
|
||||
UPDATE stories s
|
||||
INNER JOIN stories_authors sa ON sa.id = s.author_id
|
||||
SET s.creator_id = sa.user_id
|
||||
WHERE s.creator_id IS NULL
|
||||
AND sa.user_id IS NOT NULL
|
||||
SQL);
|
||||
DB::table('stories')
|
||||
->join('stories_authors', 'stories_authors.id', '=', 'stories.author_id')
|
||||
->whereNull('stories.creator_id')
|
||||
->whereNotNull('stories_authors.user_id')
|
||||
->select(['stories.id as story_id', 'stories_authors.user_id as creator_id'])
|
||||
->orderBy('stories.id')
|
||||
->get()
|
||||
->each(function ($row): void {
|
||||
DB::table('stories')
|
||||
->where('id', (int) $row->story_id)
|
||||
->update(['creator_id' => (int) $row->creator_id]);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table): void {
|
||||
$table->unsignedInteger('xp')->default(0)->after('allow_messages_from');
|
||||
$table->unsignedInteger('level')->default(1)->after('xp');
|
||||
$table->string('rank', 50)->default('Newbie')->after('level');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table): void {
|
||||
$table->dropColumn(['xp', 'level', 'rank']);
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('user_xp_logs', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->foreignId('user_id')->constrained('users')->cascadeOnDelete();
|
||||
$table->string('action', 100);
|
||||
$table->unsignedInteger('xp');
|
||||
$table->unsignedBigInteger('reference_id')->nullable();
|
||||
$table->timestamp('created_at')->nullable();
|
||||
|
||||
$table->index(['user_id', 'created_at']);
|
||||
$table->index(['user_id', 'action']);
|
||||
$table->index(['user_id', 'reference_id']);
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('user_xp_logs');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,181 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('achievements', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->string('name');
|
||||
$table->string('slug')->unique();
|
||||
$table->string('description');
|
||||
$table->string('icon', 80);
|
||||
$table->unsignedInteger('xp_reward')->default(0);
|
||||
$table->string('type', 40);
|
||||
$table->string('condition_type', 40);
|
||||
$table->unsignedInteger('condition_value');
|
||||
$table->timestamps();
|
||||
|
||||
$table->index(['type', 'condition_type']);
|
||||
});
|
||||
|
||||
DB::table('achievements')->insert([
|
||||
[
|
||||
'name' => 'First Upload',
|
||||
'slug' => 'first-upload',
|
||||
'description' => 'Publish your first artwork.',
|
||||
'icon' => 'fa-image',
|
||||
'xp_reward' => 100,
|
||||
'type' => 'Uploads',
|
||||
'condition_type' => 'upload_count',
|
||||
'condition_value' => 1,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
],
|
||||
[
|
||||
'name' => '10 Uploads',
|
||||
'slug' => 'ten-uploads',
|
||||
'description' => 'Publish 10 artworks.',
|
||||
'icon' => 'fa-layer-group',
|
||||
'xp_reward' => 250,
|
||||
'type' => 'Uploads',
|
||||
'condition_type' => 'upload_count',
|
||||
'condition_value' => 10,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
],
|
||||
[
|
||||
'name' => '100 Uploads',
|
||||
'slug' => 'hundred-uploads',
|
||||
'description' => 'Publish 100 artworks.',
|
||||
'icon' => 'fa-fire',
|
||||
'xp_reward' => 1200,
|
||||
'type' => 'Uploads',
|
||||
'condition_type' => 'upload_count',
|
||||
'condition_value' => 100,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
],
|
||||
[
|
||||
'name' => 'First Like Received',
|
||||
'slug' => 'first-like-received',
|
||||
'description' => 'Receive your first artwork like.',
|
||||
'icon' => 'fa-heart',
|
||||
'xp_reward' => 75,
|
||||
'type' => 'Engagement',
|
||||
'condition_type' => 'likes_received',
|
||||
'condition_value' => 1,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
],
|
||||
[
|
||||
'name' => '100 Likes',
|
||||
'slug' => 'hundred-likes-received',
|
||||
'description' => 'Receive 100 artwork likes.',
|
||||
'icon' => 'fa-heart-circle-check',
|
||||
'xp_reward' => 300,
|
||||
'type' => 'Engagement',
|
||||
'condition_type' => 'likes_received',
|
||||
'condition_value' => 100,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
],
|
||||
[
|
||||
'name' => '1000 Likes',
|
||||
'slug' => 'thousand-likes-received',
|
||||
'description' => 'Receive 1000 artwork likes.',
|
||||
'icon' => 'fa-heart-circle-bolt',
|
||||
'xp_reward' => 1500,
|
||||
'type' => 'Engagement',
|
||||
'condition_type' => 'likes_received',
|
||||
'condition_value' => 1000,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
],
|
||||
[
|
||||
'name' => 'First Follower',
|
||||
'slug' => 'first-follower',
|
||||
'description' => 'Earn your first follower.',
|
||||
'icon' => 'fa-user-plus',
|
||||
'xp_reward' => 100,
|
||||
'type' => 'Social',
|
||||
'condition_type' => 'followers_count',
|
||||
'condition_value' => 1,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
],
|
||||
[
|
||||
'name' => '100 Followers',
|
||||
'slug' => 'hundred-followers',
|
||||
'description' => 'Earn 100 followers.',
|
||||
'icon' => 'fa-users',
|
||||
'xp_reward' => 500,
|
||||
'type' => 'Social',
|
||||
'condition_type' => 'followers_count',
|
||||
'condition_value' => 100,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
],
|
||||
[
|
||||
'name' => 'First Story',
|
||||
'slug' => 'first-story',
|
||||
'description' => 'Publish your first story.',
|
||||
'icon' => 'fa-feather-pointed',
|
||||
'xp_reward' => 100,
|
||||
'type' => 'Stories',
|
||||
'condition_type' => 'stories_published',
|
||||
'condition_value' => 1,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
],
|
||||
[
|
||||
'name' => '10 Stories',
|
||||
'slug' => 'ten-stories',
|
||||
'description' => 'Publish 10 stories.',
|
||||
'icon' => 'fa-book-open-reader',
|
||||
'xp_reward' => 350,
|
||||
'type' => 'Stories',
|
||||
'condition_type' => 'stories_published',
|
||||
'condition_value' => 10,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
],
|
||||
[
|
||||
'name' => 'Reached Level 5',
|
||||
'slug' => 'level-five',
|
||||
'description' => 'Reach level 5 in the XP system.',
|
||||
'icon' => 'fa-star',
|
||||
'xp_reward' => 400,
|
||||
'type' => 'Milestones',
|
||||
'condition_type' => 'level_reached',
|
||||
'condition_value' => 5,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
],
|
||||
[
|
||||
'name' => 'Reached Level 7',
|
||||
'slug' => 'level-seven',
|
||||
'description' => 'Reach level 7 in the XP system.',
|
||||
'icon' => 'fa-crown',
|
||||
'xp_reward' => 1200,
|
||||
'type' => 'Milestones',
|
||||
'condition_type' => 'level_reached',
|
||||
'condition_value' => 7,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('achievements');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('user_achievements', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->foreignId('user_id')->constrained('users')->cascadeOnDelete();
|
||||
$table->foreignId('achievement_id')->constrained('achievements')->cascadeOnDelete();
|
||||
$table->timestamp('unlocked_at');
|
||||
|
||||
$table->unique(['user_id', 'achievement_id']);
|
||||
$table->index(['user_id', 'unlocked_at']);
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('user_achievements');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('leaderboards', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->string('type', 20);
|
||||
$table->unsignedBigInteger('entity_id');
|
||||
$table->decimal('score', 14, 2)->default(0);
|
||||
$table->string('period', 20);
|
||||
$table->timestamps();
|
||||
|
||||
$table->unique(['type', 'period', 'entity_id']);
|
||||
$table->index(['type', 'period', 'score']);
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('leaderboards');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,48 @@
|
||||
<?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
|
||||
{
|
||||
if (! Schema::hasTable('story_comments')) {
|
||||
Schema::create('story_comments', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->foreignId('story_id')->constrained('stories')->cascadeOnDelete();
|
||||
$table->foreignId('user_id')->constrained('users')->cascadeOnDelete();
|
||||
$table->foreignId('parent_id')->nullable()->constrained('story_comments')->nullOnDelete();
|
||||
$table->text('content')->nullable();
|
||||
$table->longText('raw_content')->nullable();
|
||||
$table->longText('rendered_content')->nullable();
|
||||
$table->boolean('is_approved')->default(true);
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
|
||||
$table->index(['story_id', 'created_at']);
|
||||
$table->index(['story_id', 'parent_id', 'is_approved']);
|
||||
$table->index(['user_id', 'created_at']);
|
||||
});
|
||||
}
|
||||
|
||||
if (! Schema::hasTable('story_bookmarks')) {
|
||||
Schema::create('story_bookmarks', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->foreignId('story_id')->constrained('stories')->cascadeOnDelete();
|
||||
$table->foreignId('user_id')->constrained('users')->cascadeOnDelete();
|
||||
$table->timestamps();
|
||||
|
||||
$table->unique(['story_id', 'user_id']);
|
||||
$table->index(['user_id', 'created_at']);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('story_bookmarks');
|
||||
Schema::dropIfExists('story_comments');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,28 @@
|
||||
<?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
|
||||
{
|
||||
if (! Schema::hasTable('artwork_bookmarks')) {
|
||||
Schema::create('artwork_bookmarks', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->foreignId('artwork_id')->constrained('artworks')->cascadeOnDelete();
|
||||
$table->foreignId('user_id')->constrained('users')->cascadeOnDelete();
|
||||
$table->timestamps();
|
||||
|
||||
$table->unique(['artwork_id', 'user_id']);
|
||||
$table->index(['user_id', 'created_at']);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('artwork_bookmarks');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration {
|
||||
public function up(): void
|
||||
{
|
||||
if (! Schema::hasTable('countries')) {
|
||||
$this->createCountriesTable();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (Schema::hasColumn('countries', 'id') && Schema::hasColumn('countries', 'iso2')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$legacyCountries = DB::table('countries')->get();
|
||||
Schema::drop('countries');
|
||||
$this->createCountriesTable();
|
||||
|
||||
foreach ($legacyCountries as $country) {
|
||||
$iso2 = strtoupper(trim((string) ($country->iso ?? '')));
|
||||
|
||||
if ($iso2 === '' || ! preg_match('/^[A-Z]{2}$/', $iso2)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DB::table('countries')->insert([
|
||||
'iso' => $iso2,
|
||||
'iso2' => $iso2,
|
||||
'name' => $country->name ?? null,
|
||||
'native' => $country->native ?? null,
|
||||
'phone' => $country->phone ?? null,
|
||||
'continent' => $country->continent ?? null,
|
||||
'capital' => $country->capital ?? null,
|
||||
'currency' => $country->currency ?? null,
|
||||
'languages' => $country->languages ?? null,
|
||||
'name_common' => $country->name ?? $iso2,
|
||||
'name_official' => $country->native ?? null,
|
||||
'active' => true,
|
||||
'sort_order' => 1000,
|
||||
'is_featured' => false,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('countries');
|
||||
}
|
||||
|
||||
private function createCountriesTable(): void
|
||||
{
|
||||
Schema::create('countries', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->char('iso', 2)->nullable()->unique();
|
||||
$table->char('iso2', 2)->unique();
|
||||
$table->char('iso3', 3)->nullable()->index();
|
||||
$table->string('numeric_code', 3)->nullable();
|
||||
$table->string('name', 255)->nullable();
|
||||
$table->string('native', 255)->nullable();
|
||||
$table->string('phone', 50)->nullable();
|
||||
$table->char('continent', 2)->nullable();
|
||||
$table->string('capital', 255)->nullable();
|
||||
$table->string('currency', 32)->nullable();
|
||||
$table->string('languages', 255)->nullable();
|
||||
$table->string('name_common', 255);
|
||||
$table->string('name_official', 255)->nullable();
|
||||
$table->string('region', 120)->nullable();
|
||||
$table->string('subregion', 120)->nullable();
|
||||
$table->text('flag_svg_url')->nullable();
|
||||
$table->text('flag_png_url')->nullable();
|
||||
$table->string('flag_emoji', 16)->nullable();
|
||||
$table->boolean('active')->default(true);
|
||||
$table->unsignedInteger('sort_order')->default(1000);
|
||||
$table->boolean('is_featured')->default(false);
|
||||
$table->timestamps();
|
||||
|
||||
$table->index('active');
|
||||
$table->index('name_common');
|
||||
$table->index(['is_featured', 'sort_order']);
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
<?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
|
||||
{
|
||||
if (Schema::hasColumn('users', 'country_id')) {
|
||||
return;
|
||||
}
|
||||
|
||||
Schema::table('users', function (Blueprint $table): void {
|
||||
$table->foreignId('country_id')->nullable()->constrained('countries')->nullOnDelete();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
if (! Schema::hasColumn('users', 'country_id')) {
|
||||
return;
|
||||
}
|
||||
|
||||
Schema::table('users', function (Blueprint $table): void {
|
||||
$table->dropConstrainedForeignId('country_id');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,26 @@
|
||||
<?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
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table): void {
|
||||
if (! Schema::hasColumn('users', 'last_received_comment_read_at')) {
|
||||
$table->timestamp('last_received_comment_read_at')->nullable()->after('allow_messages_from');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table): void {
|
||||
if (Schema::hasColumn('users', 'last_received_comment_read_at')) {
|
||||
$table->dropColumn('last_received_comment_read_at');
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,27 @@
|
||||
<?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
|
||||
{
|
||||
Schema::create('user_received_comment_reads', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
|
||||
$table->foreignId('artwork_comment_id')->constrained('artwork_comments')->cascadeOnDelete();
|
||||
$table->timestamp('read_at');
|
||||
$table->timestamps();
|
||||
|
||||
$table->unique(['user_id', 'artwork_comment_id'], 'ucr_user_comment_unique');
|
||||
$table->index(['user_id', 'read_at'], 'ucr_user_read_at_index');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('user_received_comment_reads');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,26 @@
|
||||
<?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
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table): void {
|
||||
if (Schema::hasColumn('users', 'last_received_comment_read_at')) {
|
||||
$table->dropColumn('last_received_comment_read_at');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table): void {
|
||||
if (! Schema::hasColumn('users', 'last_received_comment_read_at')) {
|
||||
$table->timestamp('last_received_comment_read_at')->nullable()->after('allow_messages_from');
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration {
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('dashboard_preferences', function (Blueprint $table): void {
|
||||
$table->unsignedBigInteger('user_id')->primary();
|
||||
$table->json('pinned_spaces')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->foreign('user_id')->references('id')->on('users')->cascadeOnDelete();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('dashboard_preferences');
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user