Add AST JSON files for NotificationMobileController and manifest.json; create SmsServiceLookupOnlyTest for SMS service functionality

This commit is contained in:
hamed
2026-07-07 14:41:22 +03:30
parent 57d081246f
commit 4ee1524f31
50 changed files with 7945 additions and 2676 deletions
+8 -12
View File
@@ -63,18 +63,9 @@ class SmsController extends BaseController
#[Route('/api/v1/sms/send', methods: ['POST'])]
public function send(Request $request): JsonResponse
{
$data = json_decode($request->getContent(), true) ?? [];
$mobile = trim($data['mobile'] ?? '');
$message = trim($data['message'] ?? '');
$provider = $data['provider'] ?? 'kavenegar';
if (empty($mobile) || empty($message)) {
return $this->error(ErrorCodes::ERR_VALIDATION_002, 'mobile و message الزامی است', 422);
}
$this->smsService->dispatchAsync($mobile, $message, $provider, tag: \App\Sms\Entity\SmsLog::TAG_USER_TEMPLATE);
return $this->success(['message' => 'پیامک در صف ارسال قرار گرفت']);
// سیاست lookup-only: ارسال متن آزاد با sms/send.json مجاز نیست (در ایران فیلتر می‌شود).
// برای ارسال دستی از تمپلیت تأییدشده استفاده کنید: POST /api/v1/sms/send-via-template
return $this->error(ErrorCodes::ERR_VALIDATION_001, 'ارسال متن آزاد مجاز نیست؛ از تمپلیت تأییدشده (VerifyLookup) استفاده کنید', 422);
}
// ── Templates ─────────────────────────────────────────────────────────────
@@ -484,6 +475,11 @@ class SmsController extends BaseController
return $this->error(ErrorCodes::ERR_VALIDATION_001, 'تمپلیت هنوز تأیید نشده است', 422);
}
// سیاست lookup-only: بدون کد VerifyLookup کاوه‌نگار قابل ارسال نیست.
if (!$template->getProviderCode()) {
return $this->error(ErrorCodes::ERR_VALIDATION_001, 'این تمپلیت کد VerifyLookup کاوه‌نگار ندارد و قابل ارسال نیست', 422);
}
$message = $template->renderBody($vars);
$this->smsService->dispatchAsync(
$mobile, $message, $provider, $template->getUuid(),
+16 -4
View File
@@ -10,6 +10,7 @@ use App\Sms\Provider\RanginehProvider;
use App\Sms\Provider\SmsProviderInterface;
use App\Sms\Repository\SmsLogRepository;
use App\Sms\Repository\SmsMessageTemplateRepository;
use Psr\Log\LoggerInterface;
use Symfony\Component\Messenger\MessageBusInterface;
class SmsService
@@ -23,6 +24,7 @@ class SmsService
private readonly MessageBusInterface $bus,
private readonly SmsMessageTemplateRepository $messageTemplateRepo,
private readonly SmsTextResolver $textResolver,
private readonly LoggerInterface $logger,
) {
$this->providers = [
'kavenegar' => $kavenegar,
@@ -46,8 +48,12 @@ class SmsService
$message = $this->textResolver->resolve($tag, $vars);
// سیاست lookup-only: بدون الگوی کاوه‌نگار نباید با sms/send.json خام ارسال شود.
if ($kaveTemplate === null || $tokenMap === []) {
$this->dispatchAsync($mobile, $message, $provider, tag: $tag);
$this->logger->error(sprintf('SMS tag "%s" has no Kavenegar template/token_map; refusing raw send', $tag), [
'tag' => $tag, 'mobile' => $mobile,
]);
$this->logRepo->save(new SmsLog($mobile, $message, $provider, false, $tag));
return;
}
@@ -79,9 +85,15 @@ class SmsService
{
$provider = $this->resolveProvider($msg->provider);
$success = ($msg->templateCode !== null)
? $provider->sendTemplate($msg->mobile, $msg->templateCode, $msg->templateVars)
: $provider->send($msg->mobile, $msg->message);
// سیاست lookup-only: پیام بدون templateCode نباید با sms/send.json خام برود.
if ($msg->templateCode === null) {
$this->logger->error('SMS refused: no templateCode (lookup-only policy)', [
'mobile' => $msg->mobile, 'tag' => $msg->tag,
]);
$success = false;
} else {
$success = $provider->sendTemplate($msg->mobile, $msg->templateCode, $msg->templateVars);
}
$log = new SmsLog($msg->mobile, $msg->message, $provider->getName(), $success, $msg->tag);
if ($msg->templateUuid) $log->setTemplateUuid($msg->templateUuid);