**Đóng vai:** Bạn là chuyên gia kiến trúc phần mềm Laravel 13.5 và PostgreSQL. **Nhiệm vụ:** Xây dựng hệ thống Database Migration (8 bảng) cho dự án HQLand dựa trên thiết kế V3. **Thực hiện chính xác các bước sau:** **Bước 1:** Tìm trong `database/migrations/`. Xóa TẤT CẢ các file migration hiện có. (Bắt đầu từ một nền tảng sạch). **Bước 2: Tạo file `2025_01_01_000000_create_projects_table.php`** PHP ``` uuid('id')->primary(); $table->string('name'); $table->string('type'); $table->string('address')->nullable(); $table->timestamps(); }); } public function down(): void { Schema::dropIfExists('projects'); } }; ``` **Bước 3: Tạo file `2025_01_02_000000_create_products_table.php`** PHP ``` uuid('id')->primary(); $table->foreignUuid('project_id')->constrained('projects')->cascadeOnDelete(); $table->string('product_type'); $table->string('code')->unique(); $table->decimal('area', 10, 2); $table->decimal('price_per_unit', 15, 2)->nullable(); $table->decimal('total_price', 15, 2); $table->jsonb('custom_data')->nullable(); // Chứa thông tin tầng, view, hướng... $table->string('status')->default('Đang mở bán'); $table->string('red_book_status')->default('Chưa có dữ liệu'); $table->timestamps(); }); } public function down(): void { Schema::dropIfExists('products'); } }; ``` **Bước 4: Tạo file `2025_01_03_000000_create_customers_table.php`** PHP ``` uuid('id')->primary(); $table->string('cmnd_cccd')->unique(); $table->string('full_name'); $table->string('phone')->nullable(); $table->string('email')->nullable(); $table->jsonb('address')->nullable(); // Lưu cấu trúc: số nhà, phường, quận... $table->date('dob')->nullable(); $table->timestamps(); }); } public function down(): void { Schema::dropIfExists('customers'); } }; ``` **Bước 5: Tạo file `2025_01_04_000000_create_contracts_table.php`** PHP ``` uuid('id')->primary(); $table->foreignUuid('product_id')->constrained('products')->cascadeOnDelete(); $table->integer('transfer_order')->default(0); $table->string('contract_type')->default('HĐMB'); $table->string('contract_number')->unique(); $table->date('signing_date')->nullable(); $table->decimal('total_value', 15, 2); $table->decimal('paid_amount', 15, 2)->default(0); // Cột ảo tự động tính số tiền còn lại, dev không cần query tính toán $table->decimal('remaining_amount', 15, 2)->virtualAs('total_value - paid_amount'); $table->jsonb('metadata')->nullable(); $table->timestamps(); }); } public function down(): void { Schema::dropIfExists('contracts'); } }; ``` **Bước 6: Tạo file `2025_01_05_000000_create_contract_customers_table.php` (Bảng trung gian)** PHP ``` uuid('id')->primary(); $table->foreignUuid('contract_id')->constrained('contracts')->cascadeOnDelete(); $table->foreignUuid('customer_id')->constrained('customers')->cascadeOnDelete(); $table->string('role')->default('CHỦ SH 1'); // Đồng sở hữu $table->integer('transfer_order')->default(0); $table->timestamps(); }); } public function down(): void { Schema::dropIfExists('contract_customers'); } }; ``` **Bước 7: Tạo file `2025_01_06_000000_create_appendices_table.php` (Phụ lục)** PHP ``` uuid('id')->primary(); $table->foreignUuid('contract_id')->constrained('contracts')->cascadeOnDelete(); $table->foreignUuid('product_id')->constrained('products')->cascadeOnDelete(); $table->string('type'); $table->integer('apply_from_order')->default(0); $table->date('signing_date')->nullable(); $table->jsonb('custom_data')->nullable(); $table->timestamps(); }); } public function down(): void { Schema::dropIfExists('appendices'); } }; ``` **Bước 8: Tạo file `2025_01_07_000000_create_settlements_table.php` (Quyết toán)** PHP ``` uuid('id')->primary(); $table->foreignUuid('product_id')->constrained('products')->cascadeOnDelete(); $table->string('type'); // "MÓNG", "THÂN", "CP THI CÔNG" $table->decimal('temp_value', 15, 2)->default(0); $table->decimal('final_value', 15, 2)->default(0); $table->decimal('difference', 15, 2)->virtualAs('final_value - temp_value'); $table->string('red_book_status')->nullable(); $table->date('issue_date')->nullable(); $table->timestamps(); }); } public function down(): void { Schema::dropIfExists('settlements'); } }; ``` **Bước 9: Tạo file `2025_01_08_000000_create_payments_table.php` (Thanh toán / Biên lai)** PHP ``` uuid('id')->primary(); $table->foreignUuid('contract_id')->constrained('contracts')->cascadeOnDelete(); $table->string('payment_type'); $table->integer('installment_no')->default(1); $table->decimal('amount', 15, 2); $table->date('due_date')->nullable(); $table->date('paid_date')->nullable(); $table->string('status')->default('PENDING'); // PENDING, PAID, OVERDUE, CANCELLED $table->string('receipt_number')->nullable(); $table->jsonb('metadata')->nullable(); $table->timestamps(); }); } public function down(): void { Schema::dropIfExists('payments'); } }; ```