id(); // Storage info $table->string('disk')->default('s3'); // Laravel filesystem disk $table->string('bucket')->nullable(); // optional if disk implies it $table->string('path'); // S3 object key (unique) // File metadata $table->string('original_name')->nullable(); $table->string('mime_type'); $table->unsignedBigInteger('size'); // bytes $table->unsignedInteger('width')->nullable(); $table->unsignedInteger('height')->nullable(); // Variants (thumb/web versions) $table->json('variants')->nullable(); // example: // { // "thumb": "crews/1/completions/4/thumb.webp", // "web": "crews/1/completions/4/web.webp" // } // Visibility $table->string('visibility')->default('private'); // private | public // Security / dedupe $table->string('checksum')->nullable(); // sha256 $table->boolean('exif_stripped')->default(true); // Ownership $table->foreignId('uploaded_by_user_id') ->constrained('users') ->cascadeOnDelete(); $table->timestamps(); $table->unique(['disk', 'path']); }); Schema::table('users', function (Blueprint $table) { $table->foreignId('avatar_image_id') ->nullable() ->constrained('images') ->nullOnDelete(); }); } /** * Reverse the migrations. */ public function down(): void { Schema::dropIfExists('images'); } };