Commit Graph

8 Commits

Author SHA1 Message Date
Дмитрий 48b88737e7 feat(прогрев ф2 этап D): backend СМС-канала — свой список sms-firms + счётчик «Отправлено N» (+ план этапа D)
Фаза 2 Этап D, Task D1. Новый эндпоинт GET /api/sales/ad-audience/sms-firms
(только head) отдаёт фирмы со строкой firm_channels(channel='sms'). Хелпер
smsSentCounts считает по каждой фирме число боевых СМС (sales_sms_messages
status='sent') по её номерам; fake_sent (песочница) не считается. firmRow получил
поле sms_sent_count (0 если не слали), проброшено и в firms/allFirms. СМС строкой
всегда loaded, сроками не греется — только чтение sales_sms_messages для счётчика,
тарификация/провайдер/запись кампаний не тронуты. Bump baseline (actingAs-ложняк).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-22 18:28:43 +03:00
Дмитрий b5e6051803 feat(прогрев ф2 этап C): экран канала — выбор + «Греть»/«Убрать», убран тоггл «Греть здесь»
Фаза 2 Этап C, Task C4 (Vue + tiny backend). SalesWarmingView переделан под модель
«фирма×канал»: галочки = выбор (без сети), кнопка «Греть» открывает модалку —
«По воронке» или «Простой срок [N] дней» (1–365) → warmFirms; кнопка «Убрать»
(массово с подтверждением + построчная иконка) → unassignFirms. Тоггл «Греть здесь»
и toggleWarmingFirm удалены. Загруженные (ещё не греются) показаны серым чипом
«Ждёт запуска» — для этого firmRow отдаёт channel_status (loaded|warming|null),
api-строка получила поле channel_status. Vuetify (v-dialog/v-text-field), палитра
проекта, переиспользованы существующие чипы sm-*. Vitest 20 (экран) + 1482 фронт,
build ✓, backend 46 GREEN, larastan 0. Bump baseline (actingAs-ложняк).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-22 18:16:48 +03:00
Дмитрий 6775f58003 feat(прогрев ф2 этап C): показ по каналам — firms/бейджи/числа из firm_channels (+ план этапа C)
Фаза 2 Этап C, Task C1. Вкладка канала показывает ТОЛЬКО свой состав: firms({platform})
фильтрует по наличию строки firm_channels(channel) (loaded или warming). Бейджи
warming_channels строятся из строк firm_channels (yandex/vk/mts по строкам, sms по
факту рассылки), а не из ch_*. Числа вкладки (in_ads/expiring_week/waiting_sync)
считаются по фирмам со строкой firm_channels(channel, status='warming') — loaded в
рекламе не участвует. Это чинит поломку после этапа B (заезд не пишет ch_* ⇒ старые
ch_*-подсчёты давали 0/пусто у новых фирм). channelColumn удалён (сирота).
allFirms/toggle/mtsFile/движок/заливки не тронуты. ch_* не удаляем (откат).
Тесты мигрированы. Bump baseline (actingAs-ложняки).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-22 17:38:15 +03:00
Дмитрий e15a4d8a69 feat(прогрев ф2): тоггл «Греть здесь» и firmRow — на строки firm_channels
Фаза 2 Этап A, Task 8. toggle пишет строку firm_channels(channel, status=warming,
mode=funnel, warming_started_at=firm.warmup_started_at, warmed_times++) вместо
булева ch_*; off удаляет строку (инкремент двумя шагами, без raw). firmRow на
вкладке площадки считает state/warming_active по строке канала через
decideForChannelRow (нет строки или loaded → stopped/false). firms() eager-грузит
firmChannels (против N+1). Границы этапа A: warming_channels-бейджи, platformState,
channelColumn, allFirms и показ всех фирм — без изменений (ch_*, показ состава →
этап C). ch_* колонки не удаляются. Бамп baseline (+9 actingAs-ложняков).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-22 16:08:35 +03:00
Дмитрий 10ea2f6295 feat(прогрев): строка фирмы показывает состояние по срокам площадки
state/stop_reason/resume_at/warming_active на вкладке площадки
(GET /api/sales/warming/{platform}/firms) теперь считаются
PlatformWarmingDecider по срокам ИМЕННО этой площадки, а не сводкой
по phone.state/firm.stopped_at — та же фирма может быть active на
yandex и уже stopped на vk. allFirms() (СМС-подборщик) сохраняет
старую сводную логику без изменений.
2026-07-22 11:27:09 +03:00
Дмитрий 71c93477b8 feat(прогрев): значок sms в warming_channels по отправленной рассылке 2026-07-21 16:07:20 +03:00
Дмитрий f93ab67e7e feat(прогрев): платформо-независимый маршрут назначения менеджера (для экрана СМС) 2026-07-21 16:00:36 +03:00
Дмитрий fbe4701399 feat(прогрев): firmRow отдаёт нишу, дату запуска, менеджера и состояние прогрева
Task 1 плана «кусок B». firmRow() в SalesAdAudienceController (firms()/allFirms())
теперь отдаёт rubric, warmup_started_at (ISO8601), manager_id/manager_name (через
prospect.sales_user_id) и агрегаты warming_active/warming_channels (yandex/vk/mts/sms).
Заглушка smsWarmedFirmIds() — Task 3 наполнит связью с СМС-рассылкой.

Тест AdAudienceWarmingFieldsTest — TDD (failing → green), плюс regression-прогон
72 тестов AdAudience* и composer stan (0 ошибок, phpstan-baseline.neon дополнен
записью под Pest actingAs() в новом тестовом файле — по конвенции остальных тестов).
2026-07-21 15:53:10 +03:00