id(); // Public identifier to reference documents externally $table->uuid('uuid')->unique(); // Optional human-friendly title and description $table->string('name'); $table->text('description')->nullable(); // Uploader (nullable, to preserve docs if user is removed) $table->foreignId('user_id')->nullable()->constrained('users')->nullOnDelete(); // Polymorphic relation to attach a document to any model (e.g., ClientCase, Contract, etc.) $table->nullableMorphs('documentable'); // creates documentable_type + documentable_id (indexed) // Storage metadata $table->string('disk', 50)->default('public'); $table->string('path', 2048); // relative path within the disk $table->string('file_name'); // stored file name (basename) $table->string('original_name'); // original client file name $table->string('extension', 20)->nullable(); $table->string('mime_type', 100)->nullable(); $table->unsignedBigInteger('size')->nullable(); // bytes $table->string('checksum', 64)->nullable(); // e.g., SHA-256 // Visibility / flags $table->boolean('is_public')->default(false); // Index to speed up path lookups per disk $table->index(['disk', 'path']); $table->timestamps(); $table->softDeletes(); }); } /** * Reverse the migrations. */ public function down(): void { Schema::dropIfExists('documents'); } };