id(); $table->foreignId('organization_id')->constrained()->cascadeOnDelete(); $table->foreignId('folder_id')->nullable(); // self-referencing folder tree, FK added after table exists $table->string('name'); $table->longText('content')->nullable(); // rich text body (Tiptap JSON/HTML) $table->string('file_path')->nullable(); // for uploaded (non rich-text) documents $table->unsignedInteger('current_version')->default(1); $table->foreignId('created_by')->nullable()->constrained('users')->nullOnDelete(); $table->timestamps(); $table->softDeletes(); }); Schema::table('documents', function (Blueprint $table) { $table->foreign('folder_id')->references('id')->on('documents')->nullOnDelete(); }); Schema::create('document_versions', function (Blueprint $table) { $table->id(); $table->foreignId('document_id')->constrained()->cascadeOnDelete(); $table->unsignedInteger('version'); $table->longText('content')->nullable(); $table->foreignId('created_by')->nullable()->constrained('users')->nullOnDelete(); $table->timestamp('created_at')->useCurrent(); }); } public function down(): void { Schema::dropIfExists('document_versions'); Schema::dropIfExists('documents'); } };