feat: Add tagging system for SMS logs and templates

- Introduced a `tag` field in the `SmsLog` entity to categorize SMS messages.
- Updated the `SmsService` to handle the new `tag` parameter during SMS dispatch.
- Implemented a `SmsTextResolver` service to resolve SMS message templates based on tags.
- Created a new `SmsMessageTemplate` entity for editable SMS templates with placeholders.
- Added endpoints for managing SMS message templates in the admin panel.
- Enhanced existing SMS dispatching methods across various controllers to utilize the tagging system.
- Migrated the database to include the new `tag` field and created a seeding command for default SMS templates.
- Updated admin API to filter SMS logs by tag and include tag information in responses.
This commit is contained in:
hamed
2026-06-19 20:42:04 +03:30
parent da57c554c1
commit fa332f7fa1
22 changed files with 846 additions and 35 deletions
@@ -26,6 +26,7 @@ class NotificationMobileController extends BaseController
private readonly DoctorRepository $doctorRepo,
private readonly ClinicRepository $clinicRepo,
private readonly SmsService $smsService,
private readonly \App\Sms\Service\SmsTextResolver $smsText,
) {}
// ── Request OTP ───────────────────────────────────────────────────────────
@@ -60,9 +61,13 @@ class NotificationMobileController extends BaseController
$this->em->flush();
// ارسال SMS
$message = $this->smsText->resolve(\App\Sms\Entity\SmsLog::TAG_NOTIFICATION_MOBILE, [
'code' => $otp->getOtpCode(),
]);
$this->smsService->dispatchAsync(
$mobile,
"کد تأیید شماره اعلان شما: {$otp->getOtpCode()}\nاعتبار: ۵ دقیقه"
$message,
tag: \App\Sms\Entity\SmsLog::TAG_NOTIFICATION_MOBILE,
);
return $this->success([
@@ -33,6 +33,7 @@ class PreRegistrationController extends BaseController
private readonly ClinicRepository $clinicRepo,
private readonly UserPasswordHasherInterface $hasher,
private readonly SmsService $sms,
private readonly \App\Sms\Service\SmsTextResolver $smsText,
private readonly LoggerInterface $logger,
) {}
@@ -154,13 +155,15 @@ class PreRegistrationController extends BaseController
$this->em->flush();
try {
$message = $this->smsText->resolve(\App\Sms\Entity\SmsLog::TAG_PRE_REGISTRATION, [
'username' => $preReg->getMobile(),
'password' => $password,
'link' => 'https://clinic-pro.ddev.site/admin',
]);
$this->sms->dispatchAsync(
$preReg->getMobile(),
sprintf(
'به کلینیک پرو خوش آمدید! شماره‌کاربری: %s | رمز عبور: %s | لینک ورود: https://clinic-pro.ddev.site/admin',
$preReg->getMobile(),
$password
)
$message,
tag: \App\Sms\Entity\SmsLog::TAG_PRE_REGISTRATION,
);
} catch (\Throwable $e) {
$this->logger->warning('PreRegistration SMS failed', ['uuid' => $uuid, 'error' => $e->getMessage()]);
+10 -7
View File
@@ -4,18 +4,20 @@ namespace App\Auth\Service;
use App\Shared\Constant\ErrorCodes;
use App\Shared\Exception\AppException;
use App\Shared\Message\SendSmsMessage;
use Symfony\Component\Messenger\MessageBusInterface;
use App\Sms\Entity\SmsLog;
use App\Sms\Service\SmsService;
use App\Sms\Service\SmsTextResolver;
use Symfony\Component\Uid\Uuid;
use Symfony\Contracts\Cache\CacheInterface;
class OtpService
{
public function __construct(
private readonly CacheInterface $cache,
private readonly MessageBusInterface $bus,
private readonly int $otpTtl = 1200,
private readonly string $appEnv = 'dev',
private readonly CacheInterface $cache,
private readonly SmsService $sms,
private readonly SmsTextResolver $smsText,
private readonly int $otpTtl = 1200,
private readonly string $appEnv = 'dev',
) {}
private function key(string $uuid): string
@@ -37,7 +39,8 @@ class OtpService
$this->cache->save($item);
if ($this->appEnv !== 'dev') {
$this->bus->dispatch(new SendSmsMessage($mobile, "کد تأیید شما: {$code}"));
$message = $this->smsText->resolve(SmsLog::TAG_OTP, ['code' => $code]);
$this->sms->dispatchAsync($mobile, $message, tag: SmsLog::TAG_OTP);
}
return $uuid;