File: /home/xedaptot/ai.naniguide.com/database/seeders/Demo/Stage06_CustomerInfraSeeder.php
<?php
namespace Database\Seeders\Demo;
use App\Model\EmailVerificationServer;
use App\Model\Sender;
use App\Model\SendingIdentity;
use App\Model\SendingServer;
use App\Model\Signature;
use App\Model\TrackingDomain;
use App\SendingServers\DomainVerification\CheckStatus;
use App\SendingServers\DomainVerification\DnsRecord;
use App\SendingServers\DomainVerification\RecordPurpose;
use App\SendingServers\Identities\IdentityKind;
use App\SendingServers\Identities\IdentityStatus;
use App\SendingServers\Identities\ManagementMode;
/**
* Stage 06 — per-customer sending infrastructure.
*
* For each demo customer creates:
* - 1-2 customer-owned sending servers (only for plans that allow `own`)
* - 1-2 sending domains (with placeholder DKIM)
* - 1 tracking domain
* - 2-3 verified senders
* - 1 signature (default)
*/
class Stage06_CustomerInfraSeeder extends AbstractDemoSeeder
{
protected int $fakerOffset = 6;
public function run(): void
{
$customers = Stage03_CustomersSeeder::$created;
$f = $this->faker();
foreach (DemoConfig::customers() as $cfg) {
$customer = $customers[$cfg['key']] ?? null;
if (!$customer) continue;
$companySlug = preg_replace('/[^a-z0-9]/', '', strtolower($cfg['company']));
$domain = $companySlug . '.demo';
// ─── customer-owned sending servers (Pro/Growth/Enterprise only) ──
if (in_array($cfg['plan_key'], ['growth', 'pro', 'enterprise'], true)) {
$count = $cfg['plan_key'] === 'enterprise' ? 2 : 1;
for ($i = 0; $i < $count; $i++) {
$type = $f->randomElement([
SendingServer::TYPE_SMTP,
SendingServer::TYPE_MAILGUN_SMTP,
SendingServer::TYPE_SENDGRID_SMTP,
]);
$s = new SendingServer();
$s->customer_id = $customer->id;
$s->type = $type;
$s->name = $cfg['company'] . ' SMTP ' . ($i + 1);
// Vendor keys live in JSON config since the driver-pattern refactor.
$s->setConfig('host', 'smtp.' . $domain);
$s->setConfig('smtp_username', 'mailer@' . $domain);
$s->setConfig('smtp_password', 'demo-password');
$s->setConfig('smtp_port', '587');
$s->setConfig('smtp_protocol', 'tls');
$s->status = SendingServer::STATUS_ACTIVE;
$s->quota_value = 5000;
$s->quota_base = 1;
$s->quota_unit = 'hour';
$s->save();
}
}
// ─── sending identities (LOCAL_DKIM, server-less) ────────────────
for ($i = 0; $i < 2; $i++) {
$domainName = ($i === 0 ? '' : 'mail.') . $domain;
$statusEnum = $f->randomElement([
IdentityStatus::VERIFIED,
IdentityStatus::VERIFIED,
IdentityStatus::VERIFIED,
IdentityStatus::PENDING,
]);
$recordStatus = $statusEnum === IdentityStatus::VERIFIED ? CheckStatus::PASSED : CheckStatus::PENDING;
$records = [
new DnsRecord(RecordPurpose::OWNERSHIP, 'TXT', "_acelle.{$domainName}", base64_encode(md5('SALT!' . $domainName)), $recordStatus),
new DnsRecord(RecordPurpose::DKIM, 'TXT', "acelle._domainkey.{$domainName}", 'v=DKIM1; k=rsa; p=DEMO_PUBLIC_KEY_PLACEHOLDER;', $recordStatus, 'acelle'),
];
$sd = new SendingIdentity();
$sd->sending_server_id = null;
$sd->customer_id = $customer->id;
$sd->kind = IdentityKind::DOMAIN;
$sd->value = $domainName;
$sd->status = $statusEnum;
$sd->management_mode = ManagementMode::LOCAL_DKIM;
$sd->shared = false;
$sd->enabled = true;
$sd->dkim_private = "-----BEGIN PRIVATE KEY-----\nDEMO_PRIVATE_KEY_PLACEHOLDER\n-----END PRIVATE KEY-----";
$sd->dkim_public = 'DEMO_PUBLIC_KEY_PLACEHOLDER';
$sd->dkim_selector = 'acelle';
$sd->signing_enabled = true;
$sd->verification_records = array_map(fn (DnsRecord $r) => $r->toArray(), $records);
$sd->save();
}
// ─── tracking domain ──────────────────────────────────────────────
$td = new TrackingDomain();
$td->customer_id = $customer->id;
$td->name = 'click.' . $domain;
$td->scheme = 'https';
$td->verification_method = 'cname';
$td->status = 'verified';
$td->save();
// ─── verified senders ─────────────────────────────────────────────
$senders = [
['name' => $cfg['first_name'] . ' ' . $cfg['last_name'], 'email' => 'hello@' . $domain],
['name' => $cfg['company'] . ' Team', 'email' => 'team@' . $domain],
['name' => 'Newsletter', 'email' => 'news@' . $domain],
];
foreach ($senders as $i => $sCfg) {
$sender = new Sender();
$sender->customer_id = $customer->id;
$sender->name = $sCfg['name'];
$sender->email = $sCfg['email'];
$sender->status = $i === 0 ? Sender::STATUS_VERIFIED : $f->randomElement([Sender::STATUS_VERIFIED, Sender::STATUS_PENDING]);
$sender->save();
}
// ─── customer-owned email verification server (Pro/Growth/Enterprise) ──
if (in_array($cfg['plan_key'], ['growth', 'pro', 'enterprise'], true)) {
$evs = new EmailVerificationServer();
$evs->customer_id = $customer->id;
$evs->name = $cfg['company'] . ' Verifier';
$evs->type = 'kickbox.io'; // service id from config/verification.php
$evs->options = json_encode(['api_key' => 'demo_kickbox_key_' . $companySlug]);
$evs->status = EmailVerificationServer::STATUS_ACTIVE;
$evs->save();
}
// ─── signature ────────────────────────────────────────────────────
$sig = new Signature();
$sig->customer_id = $customer->id;
$sig->name = 'Default Signature';
$sig->content = sprintf(
"<p><strong>%s</strong><br>%s<br><a href=\"https://%s\">https://%s</a></p>",
$cfg['first_name'] . ' ' . $cfg['last_name'],
$cfg['company'],
$domain,
$domain
);
$sig->status = 'active';
$sig->is_default = true;
$sig->save();
$this->log("customer infra ready: {$cfg['key']} ({$cfg['company']})");
}
}
}