Save workspace changes
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
<?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('creator_ai_biographies', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('user_id')->index();
|
||||
$table->text('text')->nullable();
|
||||
$table->string('source_hash', 64)->nullable()->index();
|
||||
$table->string('model', 120)->nullable();
|
||||
$table->string('status', 30)->default('generated'); // generated|approved|edited|hidden|failed
|
||||
$table->boolean('is_active')->default(false)->index();
|
||||
$table->boolean('is_hidden')->default(false);
|
||||
$table->boolean('is_user_edited')->default(false);
|
||||
$table->timestamp('generated_at')->nullable();
|
||||
$table->timestamp('approved_at')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->foreign('user_id')->references('id')->on('users')->cascadeOnDelete();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('creator_ai_biographies');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
/**
|
||||
* AI Biography v1.1 metadata columns.
|
||||
*
|
||||
* Adds:
|
||||
* prompt_version — which prompt template was used (e.g. "v1.1")
|
||||
* input_quality_tier — classified creator data richness: rich|medium|sparse
|
||||
* generation_reason — why generation was triggered (e.g. "manual_regenerate")
|
||||
* needs_review — flagged for admin inspection (poor output, low-signal, etc.)
|
||||
* last_attempted_at — timestamp of the most recent generation attempt
|
||||
* last_error_code — short machine-readable error code (e.g. "validation_failed")
|
||||
* last_error_reason — human-readable failure description from the last attempt
|
||||
*/
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('creator_ai_biographies', function (Blueprint $table): void {
|
||||
$table->string('prompt_version', 20)->nullable()->after('model');
|
||||
$table->string('input_quality_tier', 20)->nullable()->after('prompt_version');
|
||||
$table->string('generation_reason', 50)->nullable()->after('input_quality_tier');
|
||||
$table->boolean('needs_review')->default(false)->after('is_user_edited');
|
||||
$table->timestamp('last_attempted_at')->nullable()->after('approved_at');
|
||||
$table->string('last_error_code', 30)->nullable()->after('last_attempted_at');
|
||||
$table->text('last_error_reason')->nullable()->after('last_error_code');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('creator_ai_biographies', function (Blueprint $table): void {
|
||||
$table->dropColumn([
|
||||
'prompt_version',
|
||||
'input_quality_tier',
|
||||
'generation_reason',
|
||||
'needs_review',
|
||||
'last_attempted_at',
|
||||
'last_error_code',
|
||||
'last_error_reason',
|
||||
]);
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -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_versions', function (Blueprint $table): void {
|
||||
if (! Schema::hasColumn('artwork_versions', 'snapshot_json')) {
|
||||
$table->json('snapshot_json')->nullable()->after('change_note');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('artwork_versions', function (Blueprint $table): void {
|
||||
if (Schema::hasColumn('artwork_versions', 'snapshot_json')) {
|
||||
$table->dropColumn('snapshot_json');
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,77 @@
|
||||
<?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('worlds', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->string('title', 180);
|
||||
$table->string('slug', 180)->unique();
|
||||
$table->string('tagline', 220)->nullable();
|
||||
$table->string('summary', 320)->nullable();
|
||||
$table->longText('description')->nullable();
|
||||
$table->string('cover_path', 2048)->nullable();
|
||||
$table->string('theme_key', 80)->nullable();
|
||||
$table->string('accent_color', 16)->nullable();
|
||||
$table->string('accent_color_secondary', 16)->nullable();
|
||||
$table->string('background_motif', 80)->nullable();
|
||||
$table->string('icon_name', 120)->nullable();
|
||||
$table->string('status', 24)->default('draft');
|
||||
$table->string('type', 32)->default('seasonal');
|
||||
$table->timestamp('starts_at')->nullable();
|
||||
$table->timestamp('ends_at')->nullable();
|
||||
$table->boolean('is_featured')->default(false);
|
||||
$table->boolean('is_recurring')->default(false);
|
||||
$table->string('recurrence_key', 120)->nullable();
|
||||
$table->string('recurrence_rule', 160)->nullable();
|
||||
$table->unsignedSmallInteger('edition_year')->nullable();
|
||||
$table->string('cta_label', 120)->nullable();
|
||||
$table->string('cta_url', 2048)->nullable();
|
||||
$table->string('badge_label', 120)->nullable();
|
||||
$table->text('badge_description')->nullable();
|
||||
$table->string('badge_url', 2048)->nullable();
|
||||
$table->string('seo_title', 255)->nullable();
|
||||
$table->string('seo_description', 300)->nullable();
|
||||
$table->string('og_image_path', 2048)->nullable();
|
||||
$table->json('related_tags_json')->nullable();
|
||||
$table->json('section_order_json')->nullable();
|
||||
$table->foreignId('parent_world_id')->nullable()->constrained('worlds')->nullOnDelete();
|
||||
$table->foreignId('created_by_user_id')->constrained('users')->cascadeOnDelete();
|
||||
$table->timestamp('published_at')->nullable();
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
|
||||
$table->index(['status', 'is_featured'], 'worlds_status_featured_idx');
|
||||
$table->index(['starts_at', 'ends_at'], 'worlds_window_idx');
|
||||
$table->index(['recurrence_key', 'edition_year'], 'worlds_recurrence_idx');
|
||||
$table->index(['theme_key', 'status'], 'worlds_theme_status_idx');
|
||||
});
|
||||
|
||||
Schema::create('world_relations', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->foreignId('world_id')->constrained('worlds')->cascadeOnDelete();
|
||||
$table->string('related_type', 32);
|
||||
$table->unsignedBigInteger('related_id');
|
||||
$table->string('section_key', 48);
|
||||
$table->string('context_label', 120)->nullable();
|
||||
$table->unsignedInteger('sort_order')->default(0);
|
||||
$table->boolean('is_featured')->default(false);
|
||||
$table->timestamps();
|
||||
|
||||
$table->unique(['world_id', 'section_key', 'related_type', 'related_id'], 'world_relations_unique');
|
||||
$table->index(['world_id', 'section_key', 'sort_order'], 'world_relations_section_sort_idx');
|
||||
$table->index(['related_type', 'related_id'], 'world_relations_entity_idx');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('world_relations');
|
||||
Schema::dropIfExists('worlds');
|
||||
}
|
||||
};
|
||||
@@ -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('worlds', function (Blueprint $table): void {
|
||||
$table->json('section_visibility_json')->nullable()->after('section_order_json');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('worlds', function (Blueprint $table): void {
|
||||
$table->dropColumn('section_visibility_json');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,37 @@
|
||||
<?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('worlds', function (Blueprint $table): void {
|
||||
$table->boolean('accepts_submissions')->default(false)->after('is_featured');
|
||||
$table->timestamp('submission_starts_at')->nullable()->after('ends_at');
|
||||
$table->timestamp('submission_ends_at')->nullable()->after('submission_starts_at');
|
||||
$table->boolean('submission_note_enabled')->default(true)->after('accepts_submissions');
|
||||
$table->boolean('community_section_enabled')->default(true)->after('submission_note_enabled');
|
||||
$table->text('submission_guidelines')->nullable()->after('badge_description');
|
||||
|
||||
$table->index(['accepts_submissions', 'submission_starts_at', 'submission_ends_at'], 'worlds_submission_window_idx');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('worlds', function (Blueprint $table): void {
|
||||
$table->dropIndex('worlds_submission_window_idx');
|
||||
$table->dropColumn([
|
||||
'accepts_submissions',
|
||||
'submission_starts_at',
|
||||
'submission_ends_at',
|
||||
'submission_note_enabled',
|
||||
'community_section_enabled',
|
||||
'submission_guidelines',
|
||||
]);
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,33 @@
|
||||
<?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('world_submissions', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->foreignId('world_id')->constrained('worlds')->cascadeOnDelete();
|
||||
$table->foreignId('artwork_id')->constrained('artworks')->cascadeOnDelete();
|
||||
$table->foreignId('submitted_by_user_id')->constrained('users')->cascadeOnDelete();
|
||||
$table->string('status', 24)->default('pending');
|
||||
$table->text('note')->nullable();
|
||||
$table->text('reviewer_note')->nullable();
|
||||
$table->foreignId('reviewed_by_user_id')->nullable()->constrained('users')->nullOnDelete();
|
||||
$table->timestamp('reviewed_at')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->unique(['world_id', 'artwork_id'], 'world_submissions_world_artwork_unique');
|
||||
$table->index(['world_id', 'status', 'reviewed_at'], 'world_submissions_world_status_idx');
|
||||
$table->index(['artwork_id', 'status'], 'world_submissions_artwork_status_idx');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('world_submissions');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,93 @@
|
||||
<?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('worlds', function (Blueprint $table): void {
|
||||
$table->string('participation_mode', 32)->default('closed')->after('accepts_submissions');
|
||||
$table->boolean('allow_readd_after_removal')->default(true)->after('community_section_enabled');
|
||||
|
||||
$table->index(['participation_mode', 'submission_starts_at', 'submission_ends_at'], 'worlds_participation_mode_window_idx');
|
||||
});
|
||||
|
||||
DB::table('worlds')->orderBy('id')->chunkById(250, function ($rows): void {
|
||||
foreach ($rows as $row) {
|
||||
DB::table('worlds')
|
||||
->where('id', (int) $row->id)
|
||||
->update([
|
||||
'participation_mode' => (bool) $row->accepts_submissions ? 'manual_approval' : 'closed',
|
||||
]);
|
||||
}
|
||||
});
|
||||
|
||||
Schema::table('world_submissions', function (Blueprint $table): void {
|
||||
$table->boolean('is_featured')->default(false)->after('status');
|
||||
$table->string('mode_snapshot', 32)->nullable()->after('is_featured');
|
||||
$table->text('moderation_reason')->nullable()->after('reviewer_note');
|
||||
$table->timestamp('removed_at')->nullable()->after('reviewed_at');
|
||||
$table->timestamp('blocked_at')->nullable()->after('removed_at');
|
||||
$table->timestamp('featured_at')->nullable()->after('blocked_at');
|
||||
|
||||
$table->index(['world_id', 'status', 'is_featured'], 'world_submissions_world_status_featured_idx');
|
||||
});
|
||||
|
||||
DB::table('world_submissions')->orderBy('id')->chunkById(250, function ($rows): void {
|
||||
foreach ($rows as $row) {
|
||||
$status = (string) $row->status;
|
||||
$mappedStatus = match ($status) {
|
||||
'approved', 'featured' => 'live',
|
||||
'rejected' => 'removed',
|
||||
default => 'pending',
|
||||
};
|
||||
|
||||
$isFeatured = $status === 'featured';
|
||||
|
||||
DB::table('world_submissions')
|
||||
->where('id', (int) $row->id)
|
||||
->update([
|
||||
'status' => $mappedStatus,
|
||||
'is_featured' => $isFeatured,
|
||||
'moderation_reason' => $row->reviewer_note,
|
||||
'removed_at' => $mappedStatus === 'removed' ? ($row->reviewed_at ?? now()) : null,
|
||||
'featured_at' => $isFeatured ? ($row->reviewed_at ?? now()) : null,
|
||||
]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
DB::table('world_submissions')->orderBy('id')->chunkById(250, function ($rows): void {
|
||||
foreach ($rows as $row) {
|
||||
$legacyStatus = match ((string) $row->status) {
|
||||
'live' => (bool) $row->is_featured ? 'featured' : 'approved',
|
||||
'removed', 'blocked' => 'rejected',
|
||||
default => 'pending',
|
||||
};
|
||||
|
||||
DB::table('world_submissions')
|
||||
->where('id', (int) $row->id)
|
||||
->update([
|
||||
'status' => $legacyStatus,
|
||||
'reviewer_note' => $row->moderation_reason,
|
||||
]);
|
||||
}
|
||||
});
|
||||
|
||||
Schema::table('world_submissions', function (Blueprint $table): void {
|
||||
$table->dropIndex('world_submissions_world_status_featured_idx');
|
||||
$table->dropColumn(['is_featured', 'mode_snapshot', 'moderation_reason', 'removed_at', 'blocked_at', 'featured_at']);
|
||||
});
|
||||
|
||||
Schema::table('worlds', function (Blueprint $table): void {
|
||||
$table->dropIndex('worlds_participation_mode_window_idx');
|
||||
$table->dropColumn(['participation_mode', 'allow_readd_after_removal']);
|
||||
});
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user