From c85b4acbc3476e4c6b8d7854efa388d10fe5a907 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Fri, 19 Jun 2026 11:36:27 +0300 Subject: [PATCH] =?UTF-8?q?feat(G3):=20=D1=83=D0=B1=D1=80=D0=B0=D1=82?= =?UTF-8?q?=D1=8C=20=D0=B2=D0=B5=D1=82=D0=BA=D1=83=20reminder=20=D0=B8?= =?UTF-8?q?=D0=B7=20NotificationService?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 --- app/app/Services/NotificationService.php | 45 ------------------- .../Notifications/InAppNotificationTest.php | 4 +- 2 files changed, 2 insertions(+), 47 deletions(-) diff --git a/app/app/Services/NotificationService.php b/app/app/Services/NotificationService.php index ac4446e7..b8aeb80a 100644 --- a/app/app/Services/NotificationService.php +++ b/app/app/Services/NotificationService.php @@ -6,13 +6,11 @@ namespace App\Services; use App\Mail\InvoicePaidNotification; use App\Mail\NewLeadsDigestMail; -use App\Mail\ReminderDueNotification; use App\Mail\TopupSuccessNotification; use App\Mail\ZeroBalancePausedMail; use App\Models\Deal; use App\Models\InAppNotification; use App\Models\Project; -use App\Models\Reminder; use App\Models\Tenant; use App\Models\User; use Illuminate\Support\Collection; @@ -27,7 +25,6 @@ use Throwable; * Матрица 8 событий × 3 каналов (inapp / push / email) хранится в * `users.notification_preferences` JSONB. По умолчанию (см. schema.sql:699): * new_lead {inapp:true, push:true, email:false} - * reminder {inapp:true, push:true, email:true} * low_balance {email:true} * zero_balance {email:true} * topup_success {email:true} @@ -44,8 +41,6 @@ class NotificationService { public const EVENT_NEW_LEAD = 'new_lead'; - public const EVENT_REMINDER = 'reminder'; - public const EVENT_LOW_BALANCE = 'low_balance'; public const EVENT_ZERO_BALANCE = 'zero_balance'; @@ -60,7 +55,6 @@ class NotificationService public const ALL_EVENTS = [ self::EVENT_NEW_LEAD, - self::EVENT_REMINDER, self::EVENT_LOW_BALANCE, self::EVENT_ZERO_BALANCE, self::EVENT_TOPUP_SUCCESS, @@ -115,45 +109,6 @@ class NotificationService } } - /** - * Уведомление о наступлении срока напоминания. Получатели: - * — assignee_id, если задан и активен; - * — иначе created_by (создатель напоминания). - * - * Каналы: email + inapp по prefs пользователя. Триггер — Artisan - * команда `reminders:dispatch-due`. - */ - public function notifyReminder(Reminder $reminder): void - { - $recipientId = $reminder->assignee_id ?? $reminder->created_by; - $recipient = User::query() - ->where('id', $recipientId) - ->where('tenant_id', $reminder->tenant_id) - ->where('is_active', true) - ->whereNull('deleted_at') - ->first(); - - if ($recipient === null) { - // Получатель удалён/деактивирован — некому слать. - return; - } - - $shortText = $reminder->text ? mb_substr($reminder->text, 0, 80) : 'Срок касания клиента'; - $title = "Напоминание — {$shortText}"; - $body = 'Сделка #'.$reminder->deal_id; - - if ($this->prefEnabled($recipient, self::EVENT_REMINDER, self::CHANNEL_EMAIL)) { - $this->sendEmail($recipient, self::EVENT_REMINDER, new ReminderDueNotification($recipient, $reminder)); - } - - if ($this->prefEnabled($recipient, self::EVENT_REMINDER, self::CHANNEL_INAPP)) { - $this->notifyInApp($recipient, self::EVENT_REMINDER, $title, $body, [ - 'reminder_id' => $reminder->id, - 'deal_id' => $reminder->deal_id, - ]); - } - } - /** * Уведомление об auto-pause проекта на нулевом балансе (Plan 4 Task 6). * diff --git a/app/tests/Feature/Notifications/InAppNotificationTest.php b/app/tests/Feature/Notifications/InAppNotificationTest.php index e050c072..0089037f 100644 --- a/app/tests/Feature/Notifications/InAppNotificationTest.php +++ b/app/tests/Feature/Notifications/InAppNotificationTest.php @@ -26,11 +26,11 @@ test('NotificationService::notifyInApp: вызов напрямую создаё $user = User::factory()->create(['tenant_id' => $tenant->id]); $service = app(NotificationService::class); - $service->notifyInApp($user, 'reminder', 'Срок касания', 'Перезвонить клиенту через 30 мин', ['deal_id' => 42]); + $service->notifyInApp($user, 'new_lead', 'Срок касания', 'Перезвонить клиенту через 30 мин', ['deal_id' => 42]); $notif = InAppNotification::query()->first(); expect($notif)->not->toBeNull(); - expect($notif->event)->toBe('reminder'); + expect($notif->event)->toBe('new_lead'); expect($notif->title)->toBe('Срок касания'); expect($notif->body)->toBe('Перезвонить клиенту через 30 мин'); expect($notif->deal_id)->toBe(42);