Files
clinicpro/docs/tasks/task-17-sms/implementation_notes.md
T
hamed de1a78a235 feat: Implement SMS sending functionality with KavehNegar and Rangineh providers
- Add SendSmsMessage class for encapsulating SMS message data.
- Create KavehNegarProvider and RanginehProvider classes implementing SmsProviderInterface for sending SMS.
- Implement SmsLogRepository and SmsTemplateRepository for managing SMS logs and templates.
- Develop SendSmsHandler for handling SMS sending messages.
- Create SmsService to manage SMS dispatching and logging.
- Add UserProfileController for managing user profiles with CRUD operations.
- Implement UserProfile entity and repository for user profile data management.
- Update symfony.lock and bootstrap.php for project dependencies and environment setup.
2026-06-09 22:00:34 +03:30

1.8 KiB

نکات پیاده‌سازی — تسک ۱۷: ماژول پیامک

API Endpoints

GET /api/v1/sms/balance

// Response 200:
{
  "owner_id": 29,
  "owner_type": "doctor",
  "balance": 850
}

// Error 404: حساب پیامک وجود ندارد
// Error 401: احراز هویت لازم است

POST /api/v1/sms/queue

// Request:
{
  "recipient_mobile": "09121234567",
  "message": "یادآوری: نوبت شما فردا ساعت ۱۰:۰۰ است",
  "scheduled_at": "2025-06-15T09:00:00+03:30"
}

// Response 201:
{
  "id": 1,
  "status": "queued",
  "scheduled_at": 1749970200,
  "remaining_balance": 849
}

// Error 402: موجودی ناکافی
// Error 400: شماره موبایل یا پیام نامعتبر

منطق کسر موجودی (atomic)

// در SmsService.php:
$this->entityManager->beginTransaction();
$account = $this->smsAccountRepo->findByOwner($ownerType, $ownerId);
if ($account->getBalance() <= 0) {
    throw new InsufficientBalanceException();
}
$account->decrementBalance();
// add to queue
$this->entityManager->commit();

تشخیص owner از JWT token

// کاربر لاگین‌شده → چک کن دکتر است یا کلینیک
$user = $this->getUser();
if ($user->hasRole('ROLE_DOCTOR')) {
    $doctor = $this->doctorRepo->findByUser($user);
    $ownerType = 'doctor'; $ownerId = $doctor->getId();
} elseif ($user->hasRole('ROLE_CLINIC')) {
    $clinic = $this->clinicRepo->findByUser($user);
    $ownerType = 'clinic'; $ownerId = $clinic->getId();
}

نکته: ارسال واقعی پیامک

پیامک‌ها توسط یک Job/Command ارسال می‌شوند (نه در همان request):

php bin/console sms:send-queued

این command پیامک‌هایی با status=queued و scheduled_at <= now را ارسال می‌کند.