feat: add bylaw management features including documents, legal authorities, subject categories, and nodes

This commit is contained in:
2026-06-26 13:49:50 +03:30
parent 2e26bd229b
commit 9cf6957675
113 changed files with 1112 additions and 358 deletions

View File

@@ -0,0 +1,128 @@
<?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
{
DB::statement('SET FOREIGN_KEY_CHECKS=0');
Schema::create('bylaw_legal_authorities', function (Blueprint $table) {
$table->increments('id');
$table->string('name')->unique();
$table->enum('authority_type', ['executive', 'judicial', 'legislative', 'administrative', 'other']);
$table->text('description')->nullable();
$table->timestamps();
});
Schema::create('bylaw_subject_categories', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('parent_id')->nullable();
$table->string('name');
$table->string('slug')->unique();
$table->integer('sort_order')->default(0);
$table->timestamps();
$table->foreign('parent_id')->references('id')->on('bylaw_subject_categories')->nullOnDelete();
});
Schema::create('bylaw_documents', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('title', 1000);
$table->unsignedInteger('category_id')->nullable();
$table->unsignedInteger('approval_authority_id')->nullable();
$table->date('approval_date')->nullable();
$table->unsignedInteger('promulgation_authority_id')->nullable();
$table->date('promulgation_date')->nullable();
$table->string('promulgation_number', 100)->nullable();
$table->string('official_gazette_number', 100)->nullable();
$table->date('official_gazette_date')->nullable();
$table->date('execution_date')->nullable();
$table->enum('bylaw_type', ['executive', 'delegated', 'independent']);
$table->enum('global_status', ['valid', 'explicitly_repealed', 'implicitly_repealed', 'annulled', 'expired', 'draft'])->default('valid');
$table->string('pdf_file_path', 500)->nullable();
$table->boolean('is_published')->default(true);
$table->text('description')->nullable();
$table->timestamps();
$table->foreign('category_id')->references('id')->on('bylaw_subject_categories')->nullOnDelete();
$table->foreign('approval_authority_id')->references('id')->on('bylaw_legal_authorities')->nullOnDelete();
$table->foreign('promulgation_authority_id')->references('id')->on('bylaw_legal_authorities')->nullOnDelete();
$table->index(['approval_date', 'promulgation_date'], 'idx_bylaw_dates');
$table->index('global_status', 'idx_bylaw_status');
});
Schema::create('bylaw_node_types', function (Blueprint $table) {
$table->increments('id');
$table->string('name', 50)->unique();
$table->integer('hierarchy_level');
$table->timestamps();
});
Schema::create('bylaw_nodes', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('document_id');
$table->unsignedBigInteger('parent_id')->nullable();
$table->unsignedInteger('node_type_id');
$table->string('node_identifier', 50)->nullable();
$table->string('title', 500)->nullable();
$table->longText('node_content')->nullable();
$table->integer('sort_order')->default(0);
$table->date('valid_from')->nullable();
$table->date('valid_to')->nullable();
$table->enum('node_status', ['valid', 'repealed', 'annulled', 'amended', 'suspended'])->default('valid');
$table->timestamps();
$table->foreign('document_id')->references('id')->on('bylaw_documents')->cascadeOnDelete();
$table->foreign('parent_id')->references('id')->on('bylaw_nodes')->cascadeOnDelete();
$table->foreign('node_type_id')->references('id')->on('bylaw_node_types')->restrictOnDelete();
$table->index(['document_id', 'parent_id'], 'idx_node_tree');
$table->index(['node_status', 'valid_from', 'valid_to'], 'idx_node_temporal');
});
Schema::table('bylaw_nodes', function (Blueprint $table) {
$table->fullText(['node_content', 'title'], 'ft_idx_content');
});
Schema::create('bylaw_codification_links', function (Blueprint $table) {
$table->bigIncrements('id');
$table->enum('source_entity_type', ['bylaw_node', 'bylaw_doc', 'law_doc', 'court_verdict', 'advisory_opinion']);
$table->unsignedBigInteger('source_entity_id');
$table->enum('target_entity_type', ['bylaw_node', 'bylaw_doc', 'law_doc', 'court_verdict', 'advisory_opinion']);
$table->unsignedBigInteger('target_entity_id');
$table->enum('link_type', ['repeals_explicitly', 'repeals_implicitly', 'annuls_entirely', 'annuls_partially', 'amends', 'adds_to', 'interprets', 'is_executive_bylaw_of']);
$table->date('effective_date')->nullable();
$table->text('justification')->nullable();
$table->timestamp('created_at')->useCurrent();
$table->unique(['source_entity_type', 'source_entity_id', 'target_entity_type', 'target_entity_id', 'link_type'], 'idx_unique_link');
$table->index(['target_entity_type', 'target_entity_id'], 'idx_target_search');
});
DB::table('bylaw_node_types')->insertOrIgnore([
['id' => 1, 'name' => 'متن کامل آیین‌نامه', 'hierarchy_level' => 1, 'created_at' => now(), 'updated_at' => now()],
]);
DB::table('bylaw_subject_categories')->insertOrIgnore([
['id' => 9, 'name' => 'آیین نامه ها', 'slug' => 'bylaws', 'sort_order' => 0, 'created_at' => now(), 'updated_at' => now()],
]);
DB::statement('SET FOREIGN_KEY_CHECKS=1');
}
public function down(): void
{
DB::statement('SET FOREIGN_KEY_CHECKS=0');
Schema::dropIfExists('bylaw_codification_links');
Schema::dropIfExists('bylaw_nodes');
Schema::dropIfExists('bylaw_node_types');
Schema::dropIfExists('bylaw_documents');
Schema::dropIfExists('bylaw_subject_categories');
Schema::dropIfExists('bylaw_legal_authorities');
DB::statement('SET FOREIGN_KEY_CHECKS=1');
}
};