messages implemented
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
<?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('artwork_comments', function (Blueprint $table) {
|
||||
// raw_content stores user-submitted markdown/plain text
|
||||
// rendered_content stores the sanitized HTML cache
|
||||
$table->mediumText('raw_content')->nullable()->after('content');
|
||||
$table->mediumText('rendered_content')->nullable()->after('raw_content');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('artwork_comments', function (Blueprint $table) {
|
||||
$table->dropColumn(['raw_content', 'rendered_content']);
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Allowed reaction slugs → emoji mapping (authoritative list lives in ReactionType).
|
||||
* Stored as VARCHAR to avoid MySQL ENUM emoji encoding issues.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('artwork_reactions', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('artwork_id');
|
||||
$table->unsignedBigInteger('user_id');
|
||||
// slug: thumbs_up | heart | fire | laugh | clap | wow
|
||||
$table->string('reaction', 20);
|
||||
$table->timestamp('created_at')->useCurrent();
|
||||
|
||||
$table->unique(['artwork_id', 'user_id', 'reaction'], 'artwork_reactions_unique');
|
||||
$table->index('artwork_id');
|
||||
$table->index('user_id');
|
||||
|
||||
$table->foreign('artwork_id')->references('id')->on('artworks')->onDelete('cascade');
|
||||
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
|
||||
});
|
||||
|
||||
Schema::create('comment_reactions', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('comment_id');
|
||||
$table->unsignedBigInteger('user_id');
|
||||
// slug: thumbs_up | heart | fire | laugh | clap | wow
|
||||
$table->string('reaction', 20);
|
||||
$table->timestamp('created_at')->useCurrent();
|
||||
|
||||
$table->unique(['comment_id', 'user_id', 'reaction'], 'comment_reactions_unique');
|
||||
$table->index('comment_id');
|
||||
$table->index('user_id');
|
||||
|
||||
$table->foreign('comment_id')->references('id')->on('artwork_comments')->onDelete('cascade');
|
||||
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('comment_reactions');
|
||||
Schema::dropIfExists('artwork_reactions');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
/**
|
||||
* Upgrade legacy TEXT columns to MEDIUMTEXT so large imported comments
|
||||
* (incl. spam-heavy legacy rows) do not cause truncation errors.
|
||||
*
|
||||
* TEXT = 65,535 bytes (~64 KB)
|
||||
* MEDIUMTEXT = 16,777,215 bytes (~16 MB)
|
||||
*/
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('artwork_comments', function (Blueprint $table) {
|
||||
$table->mediumText('content')->nullable()->change();
|
||||
});
|
||||
|
||||
Schema::table('forum_posts', function (Blueprint $table) {
|
||||
$table->mediumText('content')->nullable()->change();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('artwork_comments', function (Blueprint $table) {
|
||||
$table->text('content')->nullable()->change();
|
||||
});
|
||||
|
||||
Schema::table('forum_posts', function (Blueprint $table) {
|
||||
$table->text('content')->nullable()->change();
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
/**
|
||||
* Modernized replacement for the legacy `favourites` table.
|
||||
*
|
||||
* What changed from the legacy schema:
|
||||
* - Renamed table: favourites → artwork_favourites
|
||||
* - `favourite_id` → `id` (bigint unsigned, auto-increment)
|
||||
* - `datum` → `created_at` / `updated_at` via timestamps()
|
||||
* - `user_type` dropped — membership tier is not a property of the
|
||||
* favourite relationship; query via users.role if needed
|
||||
* - `author_id` dropped — always derivable via artworks.user_id
|
||||
* - Both FKs are constrained with cascadeOnDelete so orphaned rows are
|
||||
* automatically cleaned up when an artwork or user is hard-deleted
|
||||
* - `legacy_id` tracks the original favourite_id for idempotent re-imports
|
||||
*/
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('artwork_favourites', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
|
||||
$table->foreignId('user_id')
|
||||
->constrained('users')
|
||||
->cascadeOnDelete();
|
||||
|
||||
$table->foreignId('artwork_id')
|
||||
->constrained('artworks')
|
||||
->cascadeOnDelete();
|
||||
|
||||
// Preserve original legacy PK for idempotent re-imports.
|
||||
// NULL for favourites created natively in the new system.
|
||||
$table->unsignedInteger('legacy_id')->nullable()->unique();
|
||||
|
||||
$table->timestamps();
|
||||
|
||||
// Prevent duplicate favourites
|
||||
$table->unique(['user_id', 'artwork_id'], 'artwork_favourites_unique_user_artwork');
|
||||
|
||||
// Fast lookup: "how many favourites does this artwork have?"
|
||||
$table->index('artwork_id');
|
||||
// Fast lookup: "which artworks has this user favourited?"
|
||||
$table->index('user_id');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('artwork_favourites');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
/**
|
||||
* Consolidate onto artwork_favourites.
|
||||
*
|
||||
* Any rows in the interim user_favorites table (created 2026-02-07) that are
|
||||
* not already present in artwork_favourites are copied over, then
|
||||
* user_favorites is dropped so only one favourites table remains.
|
||||
*/
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
if (! Schema::hasTable('user_favorites')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Copy any rows not yet in artwork_favourites, using insertOrIgnore so the
|
||||
// unique (user_id, artwork_id) constraint silently skips duplicates.
|
||||
// chunk() avoids memory spikes on large tables.
|
||||
DB::table('user_favorites')->orderBy('id')->chunk(500, function ($rows) {
|
||||
DB::table('artwork_favourites')->insertOrIgnore(
|
||||
$rows->map(fn ($r) => [
|
||||
'user_id' => $r->user_id,
|
||||
'artwork_id' => $r->artwork_id,
|
||||
'created_at' => $r->created_at,
|
||||
'updated_at' => $r->created_at,
|
||||
])->all()
|
||||
);
|
||||
});
|
||||
|
||||
Schema::drop('user_favorites');
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
if (Schema::hasTable('user_favorites')) {
|
||||
return;
|
||||
}
|
||||
|
||||
Schema::create('user_favorites', function ($table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('user_id');
|
||||
$table->unsignedBigInteger('artwork_id');
|
||||
$table->timestamp('created_at')->nullable();
|
||||
$table->unique(['user_id', 'artwork_id']);
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,40 @@
|
||||
<?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
|
||||
{
|
||||
Schema::table('user_statistics', function (Blueprint $table) {
|
||||
$table->unsignedInteger('followers_count')->default(0)->after('profile_views');
|
||||
$table->unsignedInteger('following_count')->default(0)->after('followers_count');
|
||||
});
|
||||
|
||||
// Backfill follow counters using subquery syntax (compatible with MySQL + SQLite).
|
||||
DB::statement("
|
||||
UPDATE user_statistics
|
||||
SET followers_count = (
|
||||
SELECT COUNT(*) FROM user_followers
|
||||
WHERE user_followers.user_id = user_statistics.user_id
|
||||
)
|
||||
");
|
||||
|
||||
DB::statement("
|
||||
UPDATE user_statistics
|
||||
SET following_count = (
|
||||
SELECT COUNT(*) FROM user_followers
|
||||
WHERE user_followers.follower_id = user_statistics.user_id
|
||||
)
|
||||
");
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('user_statistics', function (Blueprint $table) {
|
||||
$table->dropColumn(['followers_count', 'following_count']);
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,134 @@
|
||||
<?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;
|
||||
|
||||
/**
|
||||
* User Statistics v2 – in-place schema upgrade.
|
||||
*
|
||||
* Renames legacy columns, widens all counters to unsignedBigInteger,
|
||||
* and adds creator-received metrics + activity timestamps.
|
||||
*
|
||||
* Mapping:
|
||||
* uploads → uploads_count
|
||||
* downloads → downloads_received_count
|
||||
* pageviews → artwork_views_received_count
|
||||
* awards → awards_received_count
|
||||
* profile_views → profile_views_count
|
||||
*
|
||||
* New columns added:
|
||||
* favorites_received_count, comments_received_count,
|
||||
* reactions_received_count, last_upload_at, last_active_at
|
||||
*
|
||||
* followers_count / following_count already exist with correct naming – only
|
||||
* widened to bigint.
|
||||
*/
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
// ── 1. Rename legacy columns ─────────────────────────────────────────
|
||||
Schema::table('user_statistics', function (Blueprint $table) {
|
||||
if (Schema::hasColumn('user_statistics', 'uploads')) {
|
||||
$table->renameColumn('uploads', 'uploads_count');
|
||||
}
|
||||
if (Schema::hasColumn('user_statistics', 'downloads')) {
|
||||
$table->renameColumn('downloads', 'downloads_received_count');
|
||||
}
|
||||
if (Schema::hasColumn('user_statistics', 'pageviews')) {
|
||||
$table->renameColumn('pageviews', 'artwork_views_received_count');
|
||||
}
|
||||
if (Schema::hasColumn('user_statistics', 'awards')) {
|
||||
$table->renameColumn('awards', 'awards_received_count');
|
||||
}
|
||||
if (Schema::hasColumn('user_statistics', 'profile_views')) {
|
||||
$table->renameColumn('profile_views', 'profile_views_count');
|
||||
}
|
||||
});
|
||||
|
||||
// ── 2. Widen to unsignedBigInteger + add new columns ─────────────────
|
||||
Schema::table('user_statistics', function (Blueprint $table) {
|
||||
// Widen existing counters
|
||||
$table->unsignedBigInteger('uploads_count')->default(0)->change();
|
||||
$table->unsignedBigInteger('downloads_received_count')->default(0)->change();
|
||||
$table->unsignedBigInteger('artwork_views_received_count')->default(0)->change();
|
||||
$table->unsignedBigInteger('awards_received_count')->default(0)->change();
|
||||
$table->unsignedBigInteger('profile_views_count')->default(0)->change();
|
||||
$table->unsignedBigInteger('followers_count')->default(0)->change();
|
||||
$table->unsignedBigInteger('following_count')->default(0)->change();
|
||||
|
||||
// Add new creator-received counters
|
||||
if (! Schema::hasColumn('user_statistics', 'favorites_received_count')) {
|
||||
$table->unsignedBigInteger('favorites_received_count')->default(0)->after('awards_received_count');
|
||||
}
|
||||
if (! Schema::hasColumn('user_statistics', 'comments_received_count')) {
|
||||
$table->unsignedBigInteger('comments_received_count')->default(0)->after('favorites_received_count');
|
||||
}
|
||||
if (! Schema::hasColumn('user_statistics', 'reactions_received_count')) {
|
||||
$table->unsignedBigInteger('reactions_received_count')->default(0)->after('comments_received_count');
|
||||
}
|
||||
|
||||
// Activity timestamps
|
||||
if (! Schema::hasColumn('user_statistics', 'last_upload_at')) {
|
||||
$table->timestamp('last_upload_at')->nullable()->after('reactions_received_count');
|
||||
}
|
||||
if (! Schema::hasColumn('user_statistics', 'last_active_at')) {
|
||||
$table->timestamp('last_active_at')->nullable()->after('last_upload_at');
|
||||
}
|
||||
});
|
||||
|
||||
// ── 3. Optional: indexes for creator ranking ─────────────────────────
|
||||
try {
|
||||
Schema::table('user_statistics', function (Blueprint $table) {
|
||||
$table->index('awards_received_count', 'idx_us_awards');
|
||||
});
|
||||
} catch (\Throwable) {}
|
||||
|
||||
try {
|
||||
Schema::table('user_statistics', function (Blueprint $table) {
|
||||
$table->index('favorites_received_count', 'idx_us_favorites');
|
||||
});
|
||||
} catch (\Throwable) {}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
// Remove added columns
|
||||
Schema::table('user_statistics', function (Blueprint $table) {
|
||||
foreach (['favorites_received_count', 'comments_received_count', 'reactions_received_count', 'last_upload_at', 'last_active_at'] as $col) {
|
||||
if (Schema::hasColumn('user_statistics', $col)) {
|
||||
$table->dropColumn($col);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Drop indexes
|
||||
Schema::table('user_statistics', function (Blueprint $table) {
|
||||
try { $table->dropIndex('idx_us_awards'); } catch (\Throwable) {}
|
||||
try { $table->dropIndex('idx_us_favorites'); } catch (\Throwable) {}
|
||||
});
|
||||
|
||||
// Rename back
|
||||
Schema::table('user_statistics', function (Blueprint $table) {
|
||||
if (Schema::hasColumn('user_statistics', 'uploads_count')) {
|
||||
$table->renameColumn('uploads_count', 'uploads');
|
||||
}
|
||||
if (Schema::hasColumn('user_statistics', 'downloads_received_count')) {
|
||||
$table->renameColumn('downloads_received_count', 'downloads');
|
||||
}
|
||||
if (Schema::hasColumn('user_statistics', 'artwork_views_received_count')) {
|
||||
$table->renameColumn('artwork_views_received_count', 'pageviews');
|
||||
}
|
||||
if (Schema::hasColumn('user_statistics', 'awards_received_count')) {
|
||||
$table->renameColumn('awards_received_count', 'awards');
|
||||
}
|
||||
if (Schema::hasColumn('user_statistics', 'profile_views_count')) {
|
||||
$table->renameColumn('profile_views_count', 'profile_views');
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -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('conversations', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->enum('type', ['direct', 'group'])->default('direct');
|
||||
$table->string('title')->nullable();
|
||||
$table->unsignedBigInteger('created_by');
|
||||
$table->timestamp('last_message_at')->nullable()->index();
|
||||
$table->timestamps();
|
||||
|
||||
$table->foreign('created_by')->references('id')->on('users')->onDelete('cascade');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('conversations');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,32 @@
|
||||
<?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('conversation_participants', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('conversation_id')->constrained()->onDelete('cascade');
|
||||
$table->foreignId('user_id')->constrained()->onDelete('cascade');
|
||||
$table->enum('role', ['member', 'admin'])->default('member');
|
||||
$table->timestamp('last_read_at')->nullable();
|
||||
$table->boolean('is_muted')->default(false);
|
||||
$table->boolean('is_archived')->default(false);
|
||||
$table->timestamp('joined_at')->useCurrent();
|
||||
$table->timestamp('left_at')->nullable();
|
||||
|
||||
$table->unique(['conversation_id', 'user_id']);
|
||||
$table->index('user_id');
|
||||
$table->index('conversation_id');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('conversation_participants');
|
||||
}
|
||||
};
|
||||
@@ -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
|
||||
{
|
||||
Schema::create('messages', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('conversation_id')->constrained()->onDelete('cascade');
|
||||
$table->foreignId('sender_id')->references('id')->on('users')->onDelete('cascade');
|
||||
$table->mediumText('body');
|
||||
$table->timestamp('edited_at')->nullable();
|
||||
$table->softDeletes();
|
||||
$table->timestamps();
|
||||
|
||||
$table->index(['conversation_id', 'created_at']);
|
||||
$table->index('sender_id');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('messages');
|
||||
}
|
||||
};
|
||||
@@ -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('message_reactions', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('message_id')->constrained()->onDelete('cascade');
|
||||
$table->foreignId('user_id')->constrained()->onDelete('cascade');
|
||||
$table->string('reaction', 32);
|
||||
$table->timestamp('created_at')->useCurrent();
|
||||
|
||||
$table->unique(['message_id', 'user_id', 'reaction']);
|
||||
$table->index('message_id');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('message_reactions');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,24 @@
|
||||
<?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) {
|
||||
$table->enum('allow_messages_from', ['everyone', 'followers', 'mutual_followers', 'nobody'])
|
||||
->default('everyone')
|
||||
->after('role');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->dropColumn('allow_messages_from');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,32 @@
|
||||
<?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('notifications')) {
|
||||
return;
|
||||
}
|
||||
|
||||
Schema::create('notifications', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
|
||||
$table->string('type', 32);
|
||||
$table->json('data');
|
||||
$table->timestamp('read_at')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->index('user_id');
|
||||
$table->index('read_at');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('notifications');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,35 @@
|
||||
<?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('conversation_participants', function (Blueprint $table): void {
|
||||
if (! Schema::hasColumn('conversation_participants', 'is_pinned')) {
|
||||
$table->boolean('is_pinned')->default(false)->after('is_archived');
|
||||
}
|
||||
|
||||
if (! Schema::hasColumn('conversation_participants', 'pinned_at')) {
|
||||
$table->timestamp('pinned_at')->nullable()->after('is_pinned');
|
||||
}
|
||||
|
||||
$table->index(['user_id', 'is_pinned']);
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('conversation_participants', function (Blueprint $table): void {
|
||||
if (Schema::hasColumn('conversation_participants', 'pinned_at')) {
|
||||
$table->dropColumn('pinned_at');
|
||||
}
|
||||
if (Schema::hasColumn('conversation_participants', 'is_pinned')) {
|
||||
$table->dropColumn('is_pinned');
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,34 @@
|
||||
<?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('message_attachments', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->foreignId('message_id')->constrained()->cascadeOnDelete();
|
||||
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
|
||||
$table->enum('type', ['image', 'file']);
|
||||
$table->string('mime', 191);
|
||||
$table->unsignedBigInteger('size_bytes');
|
||||
$table->unsignedInteger('width')->nullable();
|
||||
$table->unsignedInteger('height')->nullable();
|
||||
$table->string('sha256', 64)->nullable();
|
||||
$table->string('original_name', 255);
|
||||
$table->string('storage_path', 500);
|
||||
$table->timestamp('created_at')->useCurrent();
|
||||
|
||||
$table->index('message_id');
|
||||
$table->index('user_id');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('message_attachments');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,35 @@
|
||||
<?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('reports')) {
|
||||
return;
|
||||
}
|
||||
|
||||
Schema::create('reports', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->foreignId('reporter_id')->constrained('users')->cascadeOnDelete();
|
||||
$table->enum('target_type', ['message', 'conversation', 'user']);
|
||||
$table->unsignedBigInteger('target_id');
|
||||
$table->string('reason', 120);
|
||||
$table->text('details')->nullable();
|
||||
$table->enum('status', ['open', 'reviewing', 'closed'])->default('open');
|
||||
$table->timestamps();
|
||||
|
||||
$table->index(['target_type', 'target_id']);
|
||||
$table->index('status');
|
||||
$table->index('reporter_id');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('reports');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
<?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('message_reactions', function (Blueprint $table): void {
|
||||
$table->index('user_id');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('message_reactions', function (Blueprint $table): void {
|
||||
$table->dropIndex(['user_id']);
|
||||
});
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user