update email template

This commit is contained in:
baodev0
2026-09-09 16:56:22 +07:00
parent d3d9f76ba0
commit 2365ef72e9
210 changed files with 6335 additions and 4688 deletions
@@ -0,0 +1,17 @@
<?php
namespace App\Integrations\Domain\DTOs;
class DnsDomainData
{
public function __construct(
public readonly int $legacyId,
public readonly ?string $domainName,
public readonly ?int $dnsManagerServerId,
public readonly int $isCreated,
public readonly ?int $pleskId,
public readonly ?string $createdAt,
public readonly ?string $updatedAt,
) {
}
}
@@ -0,0 +1,14 @@
<?php
namespace App\Integrations\Domain\DTOs;
class DnsDomainUserData
{
public function __construct(
public readonly ?int $domainId,
public readonly ?int $customerId,
public readonly ?string $createdAt,
public readonly ?string $updatedAt,
) {
}
}
@@ -0,0 +1,24 @@
<?php
namespace App\Integrations\Domain\DTOs;
class DnsRecordData
{
public function __construct(
public readonly int $legacyId,
public readonly ?int $dnsManagerDomainId,
public readonly ?string $name,
public readonly string $type,
public readonly ?string $serviceName,
public readonly ?string $protocol,
public readonly ?string $priority,
public readonly ?string $weight,
public readonly ?string $port,
public readonly ?string $value,
public readonly ?int $pleskId,
public readonly int $ttl,
public readonly ?string $createdAt,
public readonly ?string $updatedAt,
) {
}
}
@@ -0,0 +1,19 @@
<?php
namespace App\Integrations\Domain\DTOs;
class DnsServerData
{
public function __construct(
public readonly int $legacyId,
public readonly ?string $name,
public readonly string $ipAddress,
public readonly string $username,
public readonly string $password,
public readonly ?string $apiKey,
public readonly string $status,
public readonly ?string $createdAt,
public readonly ?string $updatedAt,
) {
}
}
@@ -0,0 +1,14 @@
<?php
namespace App\Integrations\Domain\Extractors;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\LazyCollection;
class DnsDomainExtractor
{
public function extract(): LazyCollection
{
return DB::connection('domain')->table('dns_manager_domain')->orderBy('id')->cursor();
}
}
@@ -0,0 +1,14 @@
<?php
namespace App\Integrations\Domain\Extractors;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\LazyCollection;
class DnsDomainUserExtractor
{
public function extract(): LazyCollection
{
return DB::connection('domain')->table('dns_domain_user')->orderBy('id')->cursor();
}
}
@@ -0,0 +1,14 @@
<?php
namespace App\Integrations\Domain\Extractors;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\LazyCollection;
class DnsRecordExtractor
{
public function extract(): LazyCollection
{
return DB::connection('domain')->table('dns_manager_ns')->orderBy('id')->cursor();
}
}
@@ -0,0 +1,14 @@
<?php
namespace App\Integrations\Domain\Extractors;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\LazyCollection;
class DnsServerExtractor
{
public function extract(): LazyCollection
{
return DB::connection('domain')->table('dns_manager_servers')->orderBy('id')->cursor();
}
}
@@ -0,0 +1,19 @@
<?php
namespace App\Integrations\Domain\Support;
use Illuminate\Support\Facades\DB;
/** Resolves a source `dns_manager_domain.id` to the local row via `legacy_id`. */
class DnsDomainIdResolver
{
/** @var array<int, int>|null */
private static ?array $map = null;
public function resolve(int $legacyDomainId): ?int
{
self::$map ??= DB::table('dns_manager_domain')->whereNotNull('legacy_id')->pluck('id', 'legacy_id')->all();
return self::$map[$legacyDomainId] ?? null;
}
}
@@ -0,0 +1,19 @@
<?php
namespace App\Integrations\Domain\Support;
use Illuminate\Support\Facades\DB;
/** Resolves a source `dns_manager_servers.id` to the local row via `legacy_id`. */
class DnsServerIdResolver
{
/** @var array<int, int>|null */
private static ?array $map = null;
public function resolve(int $legacyServerId): ?int
{
self::$map ??= DB::table('dns_manager_servers')->whereNotNull('legacy_id')->pluck('id', 'legacy_id')->all();
return self::$map[$legacyServerId] ?? null;
}
}
@@ -0,0 +1,57 @@
<?php
namespace App\Integrations\Domain\Support;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
/**
* Resolves a source (tgs_domain_prod) `users.id` to a local `customers.id`, matched by email.
* Creates the customer if no match exists — customers.username/type/email_verified_at were
* added specifically to carry this data (see migration add_admin_zonedns_fields_to_customers_table).
*/
class DomainUserResolver
{
/** @var array<int, ?int> source user id => customer id */
private static array $cache = [];
public function resolve(int $sourceUserId): ?int
{
if (array_key_exists($sourceUserId, self::$cache)) {
return self::$cache[$sourceUserId];
}
$user = DB::connection('domain')->table('users')->where('id', $sourceUserId)->first();
if (! $user) {
return self::$cache[$sourceUserId] = null;
}
$email = strtolower($user->email);
$customer = DB::table('customers')->where('email', $email)->first();
if ($customer) {
DB::table('customers')->where('id', $customer->id)->update([
'username' => $customer->username ?? $user->username,
'type' => $user->type,
]);
return self::$cache[$sourceUserId] = $customer->id;
}
$customerId = DB::table('customers')->insertGetId([
'uuid' => (string) Str::uuid(),
'fullname' => $user->name,
'username' => $user->username,
'email' => $email,
'email_verified_at' => $user->email_verified_at,
// source hashes are Laravel bcrypt (self-contained, no APP_KEY needed), safe to copy as-is
'password' => $user->password,
'type' => $user->type,
'status' => 1,
'created_at' => $user->created_at,
'updated_at' => $user->updated_at,
]);
return self::$cache[$sourceUserId] = $customerId;
}
}
@@ -0,0 +1,37 @@
<?php
namespace App\Integrations\Domain\Transformers;
use App\Integrations\Domain\DTOs\DnsDomainData;
use App\Integrations\Domain\Support\DnsServerIdResolver;
class DnsDomainTransformer
{
public function __construct(private DnsServerIdResolver $servers)
{
}
public function transform(array|object $row): DnsDomainData
{
$row = (array) $row;
return new DnsDomainData(
legacyId: (int) $row['id'],
domainName: $row['domain_name'] ?: null,
dnsManagerServerId: $this->servers->resolve((int) $row['dns_manager_server_id']),
isCreated: (int) $row['is_created'],
pleskId: $row['plesk_id'] !== null ? (int) $row['plesk_id'] : null,
createdAt: $this->nullableDate($row['created_at'] ?? null),
updatedAt: $this->nullableDate($row['updated_at'] ?? null),
);
}
private function nullableDate(?string $value): ?string
{
if (! $value || (int) substr($value, 0, 4) < 1970) {
return null;
}
return $value;
}
}
@@ -0,0 +1,37 @@
<?php
namespace App\Integrations\Domain\Transformers;
use App\Integrations\Domain\DTOs\DnsDomainUserData;
use App\Integrations\Domain\Support\DnsDomainIdResolver;
use App\Integrations\Domain\Support\DomainUserResolver;
class DnsDomainUserTransformer
{
public function __construct(
private DnsDomainIdResolver $domains,
private DomainUserResolver $users,
) {
}
public function transform(array|object $row): DnsDomainUserData
{
$row = (array) $row;
return new DnsDomainUserData(
domainId: $this->domains->resolve((int) $row['domain_id']),
customerId: $this->users->resolve((int) $row['user_id']),
createdAt: $this->nullableDate($row['created_at'] ?? null),
updatedAt: $this->nullableDate($row['updated_at'] ?? null),
);
}
private function nullableDate(?string $value): ?string
{
if (! $value || (int) substr($value, 0, 4) < 1970) {
return null;
}
return $value;
}
}
@@ -0,0 +1,44 @@
<?php
namespace App\Integrations\Domain\Transformers;
use App\Integrations\Domain\DTOs\DnsRecordData;
use App\Integrations\Domain\Support\DnsDomainIdResolver;
class DnsRecordTransformer
{
public function __construct(private DnsDomainIdResolver $domains)
{
}
public function transform(array|object $row): DnsRecordData
{
$row = (array) $row;
return new DnsRecordData(
legacyId: (int) $row['id'],
dnsManagerDomainId: $this->domains->resolve((int) $row['dns_manager_domain_id']),
name: $row['name'] ?: null,
type: $row['type'] ?: 'A',
serviceName: $row['service_name'] ?: null,
protocol: $row['protocol'] ?: null,
priority: $row['priority'] ?? '0',
weight: $row['weight'] ?? '0',
port: $row['port'] ?? '0',
value: $row['value'] ?: null,
pleskId: $row['plesk_id'] !== null ? (int) $row['plesk_id'] : null,
ttl: (int) ($row['ttl'] ?: 300),
createdAt: $this->nullableDate($row['created_at'] ?? null),
updatedAt: $this->nullableDate($row['updated_at'] ?? null),
);
}
private function nullableDate(?string $value): ?string
{
if (! $value || (int) substr($value, 0, 4) < 1970) {
return null;
}
return $value;
}
}
@@ -0,0 +1,35 @@
<?php
namespace App\Integrations\Domain\Transformers;
use App\Integrations\Domain\DTOs\DnsServerData;
class DnsServerTransformer
{
public function transform(array|object $row): DnsServerData
{
$row = (array) $row;
return new DnsServerData(
legacyId: (int) $row['id'],
name: $row['name'] ?: null,
ipAddress: $row['ip_address'],
username: $row['username'] ?: 'root',
// source ciphertext was encrypted with a different app's APP_KEY, Crypt::decryptString() will fail until re-entered
password: $row['password'],
apiKey: $row['api_key'] ?: null,
status: $row['status'] ?: 'activated',
createdAt: $this->nullableDate($row['created_at'] ?? null),
updatedAt: $this->nullableDate($row['updated_at'] ?? null),
);
}
private function nullableDate(?string $value): ?string
{
if (! $value || (int) substr($value, 0, 4) < 1970) {
return null;
}
return $value;
}
}
@@ -0,0 +1,30 @@
<?php
namespace App\Integrations\Domain\Writers;
use App\Integrations\Domain\DTOs\DnsDomainUserData;
use Illuminate\Support\Facades\DB;
class DnsDomainUserWriter
{
/**
* Skips pairs whose domain or customer couldn't be resolved — both columns are NOT NULL.
* Matched on (domain_id, user_id), the pivot's own unique key — no legacy_id needed.
*/
public function write(DnsDomainUserData $data): bool
{
if ($data->domainId === null || $data->customerId === null) {
return false;
}
DB::table('dns_domain_user')->updateOrInsert(
['domain_id' => $data->domainId, 'user_id' => $data->customerId],
[
'created_at' => $data->createdAt,
'updated_at' => $data->updatedAt,
]
);
return true;
}
}
@@ -0,0 +1,33 @@
<?php
namespace App\Integrations\Domain\Writers;
use App\Integrations\Domain\DTOs\DnsDomainData;
use Illuminate\Support\Facades\DB;
class DnsDomainWriter
{
/**
* Skips domains whose server couldn't be resolved — dns_manager_domain.dns_manager_server_id is NOT NULL.
*/
public function write(DnsDomainData $data): bool
{
if ($data->dnsManagerServerId === null) {
return false;
}
DB::table('dns_manager_domain')->updateOrInsert(
['legacy_id' => $data->legacyId],
[
'domain_name' => $data->domainName,
'dns_manager_server_id' => $data->dnsManagerServerId,
'is_created' => $data->isCreated,
'plesk_id' => $data->pleskId,
'created_at' => $data->createdAt,
'updated_at' => $data->updatedAt,
]
);
return true;
}
}
@@ -0,0 +1,40 @@
<?php
namespace App\Integrations\Domain\Writers;
use App\Integrations\Domain\DTOs\DnsRecordData;
use Illuminate\Support\Facades\DB;
class DnsRecordWriter
{
/**
* Skips records whose domain couldn't be resolved — dns_manager_ns.dns_manager_domain_id is NOT NULL.
*/
public function write(DnsRecordData $data): bool
{
if ($data->dnsManagerDomainId === null) {
return false;
}
DB::table('dns_manager_ns')->updateOrInsert(
['legacy_id' => $data->legacyId],
[
'dns_manager_domain_id' => $data->dnsManagerDomainId,
'name' => $data->name,
'type' => $data->type,
'service_name' => $data->serviceName,
'protocol' => $data->protocol,
'priority' => $data->priority,
'weight' => $data->weight,
'port' => $data->port,
'value' => $data->value,
'plesk_id' => $data->pleskId,
'ttl' => $data->ttl,
'created_at' => $data->createdAt,
'updated_at' => $data->updatedAt,
]
);
return true;
}
}
@@ -0,0 +1,27 @@
<?php
namespace App\Integrations\Domain\Writers;
use App\Integrations\Domain\DTOs\DnsServerData;
use Illuminate\Support\Facades\DB;
class DnsServerWriter
{
public function write(DnsServerData $data): void
{
DB::table('dns_manager_servers')->updateOrInsert(
['legacy_id' => $data->legacyId],
[
'name' => $data->name,
'ip_address' => $data->ipAddress,
'username' => $data->username,
'password' => $data->password,
'api_key' => $data->apiKey,
'status' => $data->status,
'type' => 'domain',
'created_at' => $data->createdAt,
'updated_at' => $data->updatedAt,
]
);
}
}