feat: Add DNS management resources and importer
- Implemented DomainCollection, DomainDetailResource, DomainNSCollection, DomainNSResource, and DomainResource for handling DNS domain and record data. - Created VpsServiceCollection and VpsServiceResource for VPS service management. - Added DnsManagerNS and DnsManagerUser models to represent DNS records and user associations. - Developed AdminZoneDnsSqlImporter for importing DNS data from SQL dumps, including customer and DNS domain records. - Added migration scripts to update the customers table with new fields and sync foreign key references for DNS tables. - Created a migration preview document outlining the mapping and schema changes for the admin zone DNS import.
This commit is contained in:
@@ -0,0 +1,197 @@
|
||||
# Preview: admin_zonedns -> customers
|
||||
|
||||
## Nguon doi chieu
|
||||
|
||||
- SQL dump: `portal/admin_zonedns (1).sql`
|
||||
- DB hien tai tu `portal/.env`: `tgs_portal`
|
||||
- Model doi chieu: `portal/app/Models/Customer.php`
|
||||
|
||||
## Xac nhan mapping
|
||||
|
||||
- `tbl.users` trong file SQL duoc map sang bang `customers` cua portal.
|
||||
- Vi vay, khong tao bang `users` moi trong portal.
|
||||
- Muc tieu la:
|
||||
- giu `dns_domain_user`, `dns_manager_domain`, `dns_manager_ns`
|
||||
- bo sung cac field con thieu cho `customers`
|
||||
- cap nhat `Customer.php` chi o phan replace/createUpdate
|
||||
|
||||
## Ket qua doi chieu cac bang duoc yeu cau
|
||||
|
||||
| Bang/nguon | Trong SQL | Trong DB `tgs_portal` | Ket luan |
|
||||
|---|---:|---:|---|
|
||||
| `users` | Co | Khong | Khong can tao, vi duoc map vao `customers` |
|
||||
| `customers` | Khong | Co | La bang dich de nhan schema tu `tbl.users` |
|
||||
| `dns_domain_users` | Khong | Khong | Dump va DB dang dung `dns_domain_user` |
|
||||
| `dns_domain_user` | Co | Co | Da ton tai |
|
||||
| `dns_manager_domain` | Co | Co | Da ton tai |
|
||||
| `dns_manager_ns` | Co | Co | Da ton tai |
|
||||
|
||||
## Lech schema hien tai
|
||||
|
||||
### `tbl.users` trong SQL
|
||||
|
||||
```text
|
||||
id
|
||||
name
|
||||
username
|
||||
email
|
||||
email_verified_at
|
||||
password
|
||||
type
|
||||
status
|
||||
remember_token
|
||||
created_at
|
||||
updated_at
|
||||
```
|
||||
|
||||
### `customers` hien tai
|
||||
|
||||
```text
|
||||
id
|
||||
uuid
|
||||
fullname
|
||||
avatar
|
||||
gender
|
||||
address
|
||||
state
|
||||
city
|
||||
postcode
|
||||
country
|
||||
company
|
||||
phone
|
||||
email
|
||||
email_verify
|
||||
email_hash
|
||||
email_marketing
|
||||
receive_deposit
|
||||
password
|
||||
credit
|
||||
total
|
||||
total_pending
|
||||
identity_number
|
||||
front_identity_number
|
||||
back_identity_number
|
||||
province_code
|
||||
ward_code
|
||||
remember_token
|
||||
status
|
||||
created_at
|
||||
updated_at
|
||||
deleted_at
|
||||
```
|
||||
|
||||
### Field can bo sung vao `customers` tu `tbl.users`
|
||||
|
||||
| Field tu SQL `users` | Cach map vao `customers` | Trang thai |
|
||||
|---|---|---|
|
||||
| `name` | map vao `fullname` | Da co, khong tao moi |
|
||||
| `username` | tao cot `username` | Thieu |
|
||||
| `email` | giu `email` | Da co |
|
||||
| `email_verified_at` | tao cot `email_verified_at` | Thieu |
|
||||
| `password` | giu `password` | Da co |
|
||||
| `type` | tao cot `type` | Thieu |
|
||||
| `status` | giu `status` | Da co |
|
||||
| `remember_token` | giu `remember_token` | Da co |
|
||||
| `created_at` | giu `created_at` | Da co |
|
||||
| `updated_at` | giu `updated_at` | Da co |
|
||||
|
||||
## Lech schema cac bang DNS
|
||||
|
||||
### `dns_manager_domain`
|
||||
|
||||
- SQL dump:
|
||||
- `id`, `domain_name`, `dns_manager_server_id`, `is_created`, `plesk_id`, `created_at`, `updated_at`
|
||||
- DB hien tai:
|
||||
- co them `user_id`
|
||||
- Ket luan:
|
||||
- khong thieu bang
|
||||
- khong nen remove `user_id`
|
||||
|
||||
### `dns_manager_ns`
|
||||
|
||||
- SQL dump:
|
||||
- `id`, `dns_manager_domain_id`, `name`, `type`, `service_name`, `protocol`, `priority`, `weight`, `port`, `value`, `plesk_id`, `ttl`, `created_at`, `updated_at`
|
||||
- DB hien tai:
|
||||
- co them `type_valid`
|
||||
- Ket luan:
|
||||
- khong thieu bang
|
||||
- khong nen remove `type_valid`
|
||||
|
||||
### `dns_domain_user`
|
||||
|
||||
- SQL dump va DB hien tai deu dang dung `dns_domain_user`
|
||||
- Khong co bang `dns_domain_users`
|
||||
- Neu ban muon chuyen qua ten plural, can migration rieng
|
||||
|
||||
## Preview migration cho `customers`
|
||||
|
||||
```php
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('customers', function (Blueprint $table) {
|
||||
if (! Schema::hasColumn('customers', 'username')) {
|
||||
$table->string('username', 50)->nullable()->after('fullname');
|
||||
}
|
||||
|
||||
if (! Schema::hasColumn('customers', 'email_verified_at')) {
|
||||
$table->timestamp('email_verified_at')->nullable()->after('email');
|
||||
}
|
||||
|
||||
if (! Schema::hasColumn('customers', 'type')) {
|
||||
$table->string('type')->default('guest')->after('password');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('customers', function (Blueprint $table) {
|
||||
if (Schema::hasColumn('customers', 'type')) {
|
||||
$table->dropColumn('type');
|
||||
}
|
||||
|
||||
if (Schema::hasColumn('customers', 'email_verified_at')) {
|
||||
$table->dropColumn('email_verified_at');
|
||||
}
|
||||
|
||||
if (Schema::hasColumn('customers', 'username')) {
|
||||
$table->dropColumn('username');
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
## Preview cap nhat `Customer.php`
|
||||
|
||||
### Replace
|
||||
|
||||
- Dung `fullname` thay cho `users.name`
|
||||
- Khong tao them cot `name`
|
||||
|
||||
### Them vao `$fillable`
|
||||
|
||||
```php
|
||||
'username',
|
||||
'email_verified_at',
|
||||
'type',
|
||||
```
|
||||
|
||||
### Them vao `$updatable`
|
||||
|
||||
```php
|
||||
'username',
|
||||
```
|
||||
|
||||
## Tom tat sau khi duyet preview
|
||||
|
||||
1. Khong tao bang `users`.
|
||||
2. Tao 1 migration add field vao `customers`: `username`, `email_verified_at`, `type`.
|
||||
3. Khong tao moi `dns_domain_user`, `dns_manager_domain`, `dns_manager_ns`.
|
||||
4. Chi cap nhat `Customer.php` o phan fillable/updatable va replace mapping `name` -> `fullname`.
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$hasUsername = Schema::hasColumn('customers', 'username');
|
||||
$hasEmailVerifiedAt = Schema::hasColumn('customers', 'email_verified_at');
|
||||
$hasType = Schema::hasColumn('customers', 'type');
|
||||
|
||||
if (! $hasUsername || ! $hasEmailVerifiedAt || ! $hasType) {
|
||||
Schema::table('customers', function (Blueprint $table) use ($hasUsername, $hasEmailVerifiedAt, $hasType) {
|
||||
if (! $hasUsername) {
|
||||
$table->string('username', 50)->nullable()->after('fullname');
|
||||
$table->unique('username');
|
||||
}
|
||||
|
||||
if (! $hasEmailVerifiedAt) {
|
||||
$table->timestamp('email_verified_at')->nullable()->after('email');
|
||||
}
|
||||
|
||||
if (! $hasType) {
|
||||
$table->string('type', 255)->default('guest')->after('password');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
$hasUsername = Schema::hasColumn('customers', 'username');
|
||||
$hasEmailVerifiedAt = Schema::hasColumn('customers', 'email_verified_at');
|
||||
$hasType = Schema::hasColumn('customers', 'type');
|
||||
|
||||
if (! $hasUsername && ! $hasEmailVerifiedAt && ! $hasType) {
|
||||
return;
|
||||
}
|
||||
|
||||
Schema::table('customers', function (Blueprint $table) use ($hasUsername, $hasEmailVerifiedAt, $hasType) {
|
||||
if ($hasUsername) {
|
||||
$table->dropUnique('customers_username_unique');
|
||||
}
|
||||
|
||||
$columns = [];
|
||||
|
||||
if ($hasUsername) {
|
||||
$columns[] = 'username';
|
||||
}
|
||||
|
||||
if ($hasEmailVerifiedAt) {
|
||||
$columns[] = 'email_verified_at';
|
||||
}
|
||||
|
||||
if ($hasType) {
|
||||
$columns[] = 'type';
|
||||
}
|
||||
|
||||
if ($columns !== []) {
|
||||
$table->dropColumn($columns);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$serverId = $this->resolveCanonicalServerId();
|
||||
|
||||
if ($serverId === null) {
|
||||
throw new RuntimeException('Không tìm thấy dns_manager_servers để sync foreign key.');
|
||||
}
|
||||
|
||||
DB::statement("
|
||||
UPDATE dns_manager_domain d
|
||||
LEFT JOIN dns_manager_servers s ON s.id = d.dns_manager_server_id
|
||||
SET d.dns_manager_server_id = {$serverId}
|
||||
WHERE d.dns_manager_server_id = 0 OR s.id IS NULL
|
||||
");
|
||||
|
||||
DB::statement('ALTER TABLE dns_manager_domain MODIFY dns_manager_server_id BIGINT UNSIGNED NOT NULL');
|
||||
DB::statement('ALTER TABLE dns_manager_ns MODIFY dns_manager_domain_id BIGINT UNSIGNED NOT NULL');
|
||||
|
||||
$this->addForeignKeyIfMissing(
|
||||
'dns_manager_domain',
|
||||
'dns_manager_domain_dns_manager_server_id_foreign',
|
||||
'ALTER TABLE dns_manager_domain
|
||||
ADD CONSTRAINT dns_manager_domain_dns_manager_server_id_foreign
|
||||
FOREIGN KEY (dns_manager_server_id) REFERENCES dns_manager_servers(id)
|
||||
ON UPDATE CASCADE
|
||||
ON DELETE RESTRICT'
|
||||
);
|
||||
|
||||
$this->addForeignKeyIfMissing(
|
||||
'dns_domain_user',
|
||||
'dns_domain_user_domain_id_foreign',
|
||||
'ALTER TABLE dns_domain_user
|
||||
ADD CONSTRAINT dns_domain_user_domain_id_foreign
|
||||
FOREIGN KEY (domain_id) REFERENCES dns_manager_domain(id)
|
||||
ON UPDATE CASCADE
|
||||
ON DELETE CASCADE'
|
||||
);
|
||||
|
||||
$this->addForeignKeyIfMissing(
|
||||
'dns_domain_user',
|
||||
'dns_domain_user_user_id_foreign',
|
||||
'ALTER TABLE dns_domain_user
|
||||
ADD CONSTRAINT dns_domain_user_user_id_foreign
|
||||
FOREIGN KEY (user_id) REFERENCES customers(id)
|
||||
ON UPDATE CASCADE
|
||||
ON DELETE CASCADE'
|
||||
);
|
||||
|
||||
$this->addForeignKeyIfMissing(
|
||||
'dns_manager_ns',
|
||||
'dns_manager_ns_dns_manager_domain_id_foreign',
|
||||
'ALTER TABLE dns_manager_ns
|
||||
ADD CONSTRAINT dns_manager_ns_dns_manager_domain_id_foreign
|
||||
FOREIGN KEY (dns_manager_domain_id) REFERENCES dns_manager_domain(id)
|
||||
ON UPDATE CASCADE
|
||||
ON DELETE CASCADE'
|
||||
);
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
$this->dropForeignKeyIfExists('dns_manager_ns', 'dns_manager_ns_dns_manager_domain_id_foreign');
|
||||
$this->dropForeignKeyIfExists('dns_domain_user', 'dns_domain_user_user_id_foreign');
|
||||
$this->dropForeignKeyIfExists('dns_domain_user', 'dns_domain_user_domain_id_foreign');
|
||||
$this->dropForeignKeyIfExists('dns_manager_domain', 'dns_manager_domain_dns_manager_server_id_foreign');
|
||||
|
||||
DB::statement('ALTER TABLE dns_manager_ns MODIFY dns_manager_domain_id INT NOT NULL');
|
||||
DB::statement('ALTER TABLE dns_manager_domain MODIFY dns_manager_server_id INT NOT NULL DEFAULT 0');
|
||||
}
|
||||
|
||||
private function resolveCanonicalServerId(): ?int
|
||||
{
|
||||
$server = DB::table('dns_manager_servers')
|
||||
->select('id')
|
||||
->orderByRaw('CASE WHEN id = 1 THEN 0 ELSE 1 END')
|
||||
->orderBy('id')
|
||||
->first();
|
||||
|
||||
return $server ? (int) $server->id : null;
|
||||
}
|
||||
|
||||
private function addForeignKeyIfMissing(string $table, string $constraint, string $statement): void
|
||||
{
|
||||
$exists = DB::table('information_schema.TABLE_CONSTRAINTS')
|
||||
->whereRaw('TABLE_SCHEMA = DATABASE()')
|
||||
->where('TABLE_NAME', $table)
|
||||
->where('CONSTRAINT_NAME', $constraint)
|
||||
->where('CONSTRAINT_TYPE', 'FOREIGN KEY')
|
||||
->exists();
|
||||
|
||||
if (! $exists) {
|
||||
DB::statement($statement);
|
||||
}
|
||||
}
|
||||
|
||||
private function dropForeignKeyIfExists(string $table, string $constraint): void
|
||||
{
|
||||
$exists = DB::table('information_schema.TABLE_CONSTRAINTS')
|
||||
->whereRaw('TABLE_SCHEMA = DATABASE()')
|
||||
->where('TABLE_NAME', $table)
|
||||
->where('CONSTRAINT_NAME', $constraint)
|
||||
->where('CONSTRAINT_TYPE', 'FOREIGN KEY')
|
||||
->exists();
|
||||
|
||||
if ($exists) {
|
||||
DB::statement("ALTER TABLE {$table} DROP FOREIGN KEY {$constraint}");
|
||||
}
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user