Пилот по стоматологиям: скан кода сайтов (коллтрекинг Calltouch/Comagic/
Callibri/Roistat/Mango + пиксели VK-myTarget/Google Ads/Meta) плюс Яндекс.Директ
через Keys.so API (ключи, объявления, бюджет), склейка в Excel. Две фазы:
сайты параллельно, затем чистый проход по API с повторами. Тесты 16/16.
Спека и план — docs/superpowers. Данные Спарка, результаты и токен Keys.so —
вне git (личная папка + .gitignore).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- «Вход в личный кабинет» (nav a.navlogin) ПЕРЕД «Попробовать бесплатно»,
ghost-стиль; на мобиле сокращается до «Вход» (.lg-full/.lg-short)
- секции получили класс navsec (скрыты на мобиле), логин остаётся
- обе кнопки шапки + финальная CTA ведут на https://lk.liderra.ru/
(адрес-заглушка, подтвердить у владельца); у #cta убран preventDefault
- флоу: liderra.ru = лендинг, портал → lk.liderra.ru
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- телефон (≤760px) → flat-режим: секции в столбик, chap-cap сверху (order:-1),
карточки/чипы полной ширины; размеры/отступы под мобилку, «листайте» скрыт
- фон анимируется через лёгкий flatLoop (bg-only, цвет по общему скроллу,
портал у верха/низа)
- шапка: текст-меню скрыто, яркая кнопка «Попробовать бесплатно» остаётся
- fix: старый баг flat-режима — блок стартовал до объявления canvas-переменных
(init2D падал на undefined.style); перенёс перед boot
- проверено на 390×844: hero/поле/поток/CRM/финал, 0 ошибок консоли
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- новый экран между «Конкурентным полем» и CRM: «Один номер — один раз»,
летящие плашки-номера (новые светятся, дубли гаснут/зачёркнуты),
подпись конкурента-источника, живой счётчик, зелёно-мадженовая глава
- перенумерация глав 01–04, пункт меню «Поток»
- «Проба» → яркая кнопка-пилюля «Попробовать бесплатно»
- красный пик палитры остаётся на «Успехе» (crmP≈0.713, проверено)
- передача 2026-07-07-HANDOFF-landing-v5.md обновлена
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Решение заказчика 03.07.2026: два вида тарифа вместо трёх — суточный
оклад daily_salary и процент от пополнений topup_step. Убраны
percent_oborot и fix_per_client.
Миграция 2026_07_03_120000 меняет CHECK sales_tariffs.kind, освобождает
FK sales_users.current_tariff_id и sales_client_assignments.tariff_id,
удаляет тарифы уходящих видов. SalesEarningsService для уходящих видов
возвращает 0 по default-ветке. Снимки привязок не трогаются.
Обновлены контроллеры тарифов и дохода, сервисы Earnings и Metrics,
фронт SalesTariffsView и api/sales.ts, демо-сид, тесты бэка и фронта,
CHANGELOG схемы v8.61 и спека портала.
Не на проде: ветка feat/sales-portal-demo.
Проверка: Sales Feature 169/169, Vitest SalesTariffs 10/10, Larastan 0.
Co-Authored-By: Claude Opus 4.8 1M context <noreply@anthropic.com>
Task 8.2 — SalesDemoSeeder: начальник Орлов + 3 менеджера (Лебедев в
отпуске) + 4 тарифа (3 вида) + привязки (к существующим тенантам,
round-robin, снимок тарифа) + выплаты как в прототипе.
- Защита от прода: throw если app env = production.
- Идемпотентно (firstOrCreate/updateOrCreate; выплаты только если их нет —
append-only). DatabaseSeeder не трогается — запуск вручную
`php artisan db:seed --class=SalesDemoSeeder`.
NB: запускать в dev-БД, НЕ в liderra_testing (портит baseline dept-count
тестов). Larastan 0.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Производный статус тенанта (trial>suspended>overdue>active) был скопирован
в 3 контроллерах портала продаж. Вынесен в
App\Http\Controllers\Concerns\DerivesTenantStatus; контроллеры
(Clients/Dashboard/Managers) теперь используют трейт. Поведение не
изменено — sales-набор 28/28 затронутых, Larastan 0.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Task 7.1b — SalesManagersView (начальник, #page-managers) поверх
GET/POST /api/sales/managers.
- Форма «Новый менеджер» (имя, e-mail, пароль, роль) → POST → snackbar +
очистка + перезагрузка; ошибки (дубль email) через extractSalesErrorMessage.
- Список менеджеров: роль-чип, клиентов, выплачено всего, статус
(Активен/Отпуск).
- api/sales.ts: listSalesManagers/createSalesManager. Роут /sales/managers
со заглушки на экран.
Vitest 6/6, фронт-набор 1089 без регрессий, ESLint чист.
Фаза 7 завершена: начальник создаёт менеджеров (логин+пароль) и видит
список отдела.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Task 7.1a — SalesAccountService + store/index в SalesManagersController,
только head.
- store: создаёт sales_user (пароль Hash::make, created_by=head,
base_salary=0); email unique → 422; role in manager|head; password min:6;
в ответе нет password ($hidden).
- index: список всех sales_users (head-первыми) с clients_count и
выплачено всего.
Менеджер не может создавать/смотреть список (403).
Тесты 7/7 (вкл. проверку хеша пароля), sales-набор 174/174, Larastan 0.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Task 6.3 — период уже проброшен во всех контроллерах (SalesPeriodResolver)
и экранах (salesPeriod store + watch). Добавлен проверочный тест на
/api/sales/overview: period=this даёт оборот 3000/лид, period=prev — 5000/лид,
а balance_sum_rub одинаков (1000) — баланс не зависит от периода.
Фаза 6 завершена: начальник видит весь отдел; период переключается везде.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Task 6.2b — SalesPerformanceView (начальник, #page-performance) поверх
GET /api/sales/managers/performance.
- Поиск по имени (debounce) + таблица: менеджер (имя/email), клиентов,
активных, лидов пришло, оборот, выплачено, заработал, статус
(Активен/Отпуск). HelpHint на Оборот/Заработал. Период из salesPeriod store.
- Роут /sales/performance со заглушки на экран.
Vitest 5/5, фронт-набор 1083 без регрессий, ESLint чист.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Task 6.2a — SalesManagersController@performance, только head.
По каждому менеджеру за период: клиентов, активных клиентов (derived
status), лидов пришло, оборот клиентов, выплачено всего, заработал
(forManager), статус (active/vacation по is_active). Фильтр search по имени.
Тесты 4/4, sales-набор 166/166, Larastan 0.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Task 4.2b — два экрана поверх готовых эндпоинтов.
- SalesPayoutsView (начальник, #page-payouts): форма «Провести выплату»
(менеджер из remaining, сумма, дата, комментарий) → POST /payouts →
snackbar + перезагрузка; таблица «Остаток к выплате по менеджерам»
(начислено/выплачено/остаток за период); «Журнал всех выплат».
- SalesIncomeView (менеджер, #page-income): 4 KPI (оборот/начислено/
выплачено всего/к выплате), таблица «Начислено по клиентам» с ИТОГО,
«Журнал выплат мне» с ИТОГО.
- api/sales.ts: listSalesPayouts/getSalesPayoutsRemaining/createSalesPayout/
getSalesIncome. Роуты /sales/payouts и /sales/income со заглушек на экраны.
Vitest 9/9, фронт-набор 1061 без регрессий, ESLint чист.
Фаза 4 завершена: начальник проводит выплаты, менеджер видит начисления
и выплаты.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Task 4.2a — SalesIncomeController@show для авторизованного менеджера:
- totals: оборот клиентов (Σ), начислено за период (forManager),
выплачено всего, к выплате за период (остаток начислено−выплачено).
- per_client: строки «Начислено по клиентам» (организация, тариф,
пополнения, заработано) по снимкам тарифов.
- payouts: журнал СВОИХ выплат.
Head без клиентов → нули. Reuse earnings/metrics/payout сервисов.
Тесты 6/6, sales-набор 151/151, Larastan 0.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Task 4.1 — SalesPayoutService + SalesPayoutController.
- record: append-only запись в sales_payouts + письмо менеджеру
(SalesPayoutRecordedMail). Журнал неизменяем (DB-триггер
sales_payouts_no_mutate — покрыто тестами на UPDATE/DELETE → QueryException).
- remaining (head): по каждому менеджеру за период — начислено
(forManager), выплачено за период (по дате paid_on), выплачено всего,
остаток = начислено − выплачено(период); переплата не зажимается в 0.
- index: менеджер видит только свои выплаты, начальник — все.
- POST /payouts и /payouts/remaining — только head; валидация суммы/даты/
менеджера.
Тесты 15/15 (вкл. append-only через savepoint), sales-набор 145/145,
Larastan 0.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Task 3.3b — три экрана Фазы 1 показывают живой earned_rub вместо
заглушки «—»:
- «Мои клиенты»: колонка «Заработал» = комиссия по клиенту (или «—»
без привязки).
- Карточка клиента: KPI «Вы заработали (период)».
- Сводка: KPI «Я заработал» = суммарная комиссия за период.
Тип earned_rub расширен до number|null. Vitest-моки/ассерты обновлены
под реальные значения. Фронт-набор 1052 зелёных, ESLint чист.
Фаза 3 завершена: доход менеджера считается по тарифу каждого клиента
и виден во всех экранах.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Task 3.3a — SalesClientsController наполняет earned_rub через
SalesEarningsService (был null-заглушкой):
- index: доход по каждому клиенту за период по снимку тарифа привязки;
клиент без привязки (начальник видит незакреплённых) → null.
- show (kpi): доход по одному клиенту.
- overview (totals): сумма комиссии по всем привязкам в scope (без оклада).
Тесты Фазы 1 обновлены под реальные значения (percent_oborot 10/20% от
засеянного оборота → 500/5/10000 ₽; привязка без тарифа → 0.0; без
привязки → null). Попутно исправлен ключ params тест-тарифа
(percent→rate, движок читает rate). Sales-набор 132/132, Larastan 0.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Task 3.2b — SalesTariffsView поверх готового каталога тарифов.
- 3 семейства-конструктора: «процент от пополнений» (ступени from–to–%,
+добавить период), «оклад+процент» (оклад→params.base_salary, ставка→
params.rate), «фикс за клиента» (порог/вознаграждение). Создание — POST,
правка — PUT.
- Секция «Текущий тариф менеджера»: select тарифа + оклад (для оклад+процент),
метрики периода и оценка «Начислено» (estimated_earned_rub); сохранение —
assign. Оклад уходит в base_salary_rub только для percent_oborot.
- Период из salesPeriod store, перезагрузка по смене. Роут /sales/tariffs
переключён со заглушки.
Vitest 9/9, полный фронт-набор без регрессий, ESLint чист.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Task 3.1 — SalesEarningsService, денежное ядро портала продаж.
Доход считается по СНИМКУ тарифа клиента (assignment.tariff_kind/params),
не по live-тарифу менеджера.
- percent_oborot: оборот периода × ставка.
- fix_per_client: reward если накопленные пополнения (all-time) ≥ порога, иначе 0.
- topup_step: Σ по месяцам периода пополнений месяца × ставка ступени по сроку
обслуживания (tenure = diffInMonths(assigned_at→месяц)+1); вне таблицы → 0.
- forManager: оклад × число месяцев + Σ по клиентам (round 2).
- perClient: детализация для экрана «Мой доход».
Переиспользует SalesMetricsService (целые копейки, полуоткрытые интервалы)
и SalesPeriodResolver. Тесты 12/12 (заморозка времени на середину месяца
против флейков границ + партиций balance_transactions). Larastan 0.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
По спеке 2026-07-02-jivo-ai-support-bot-design: webhook + FTS-поиск
по инструкции + YandexGPT Lite + эскалация + журнал + тест скорости.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Task 2.3b портала отдела продаж — два Vue-экрана поверх готовых
эндпоинтов /api/sales/attachments:
- SalesAttachView (менеджер, #page-attach): форма заявки по логину
(e-mail/ИНН), живой баннер результата (отправлено/не найден/ошибка),
таблица «Мои заявки».
- SalesRequestsView (начальник, #page-requests): очередь на решение
с проверкой «свободен / уже за: …», кнопки Подтвердить/Переназначить
/Отклонить (переназначение = тот же approve на бэке), история, счётчик.
- api/sales.ts: submitAttachment / listMyAttachments / listAttachmentQueue
/ decideAttachment + типы.
- Роуты /sales/attach и /sales/requests переключены со stub на реальные экраны.
Vitest: SalesAttach 5 + SalesRequests 7 = 12 зелёных; полный фронт-набор
не сломан. ESLint чист.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Дизайн согласован владельцем 02.07.2026: свой бот через Jivo Bot API,
YandexGPT Lite, база знаний = docs/help/ в репо, кнопка «Показать»
(экскурсии), скорость 2-5 сек, v1 только общие вопросы.
Словарь: +jivo/дживо/gigachat.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Разбивка на 10 задач по TDD: LivenessProbe/DTO, 4 пробы живости
(SMTP/ЮKassa/Jivo/капча), джоба пишет строки живости, email-алерт по
edge-trigger, фронт со статус-текстом. Схема БД не меняется.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Дизайн (брейншторм 02.07): расширяем плитку балансов до наблюдения за всеми
внешними сервисами — деньги И живость. Добавляем Почту (Yandex 360 SMTP,
только живость), ЮKassa, JivoSite, SmartCaptcha. Красная плитка + письмо
на ops@liderra.ru по edge-trigger. Конкурентное поле — вне объёма.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Обоснование (spec) + детальный пошаговый план с полным откатом:
- факты живой базы (7 тест-клиентов, деньги синтетические), keep/delete
- разведка crm.lead.store: визуал новый, начинка (эндпоинты/API/формат лида) та же
- порядок: свап ЛК -> проверка проектов по алгоритму -> чистка кабинета -> чистка базы
- маркировка БОЕВОЙ ПРОД во всех доках + стартовый хук
Секреты/ПДн не включены (почты замаскированы, секрет вебхука как <секрет>).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Task 0.3: guard 'sales' (driver sanctum, provider sales_users). Тест SalesGuardTest 3/3 (valid Bearer→200, без токена→401, мусор→401). Миграция personal_access_tokens (Sanctum Bearer; раньше не было — основной кабинет SPA cookie), DDL через pgsql_supplier, гранты crm_admin_user, CHANGELOG v8.60. Larastan baseline: +SalesGuardTest (Pest TestCall false-pos), SetTenantContext int→mixed (второй provider расширил тип $request->user()). План: admin-db ДО auth:sales. Один эскейп на сессию.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Task 0.1: миграция sales_tariffs/sales_users/sales_client_assignments/sales_attachment_requests/sales_payouts (SaaS-level, без RLS, фильтр по владению в коде). Append-only триггер. Гранты crm_admin_user. DDL через pgsql_supplier. CHANGELOG_schema v8.59. Разрешение хозяина: один эскейп на сессию.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Демо-прототип портала менеджеров по продажам в дизайне Лидерры (Forest),
приведён к реальной модели данных + расширен. Без бэкенда.
- Роли менеджер/начальник, простой демо-вход, переключение роли
- Менеджер: Сводка, Мои клиенты, карточка клиента, Привязать, Мой доход
- Начальник: Сводка отдела, Результативность, Тарифы менеджеров,
Счета (оплата по счёту), Заявки на привязку, Выплаты, Менеджеры
- Тарифы = формула дохода (В1): 3 семейства, конструктор, переход «тариф
прилипает к клиенту» (В12 решён)
- Выбор периода везде (этот/прошлый/позапрошлый/произвольный)
- UX-проход Playwright: ?-подсказки, починена вёрстка подписей
- Спека: docs/superpowers/specs/2026-06-28-sales-manager-portal-brainstorm.md
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Разбор 13 false-positive ru-phone-unmasked: фейк-номера в заглушке агента
(Fake*CompetitorAgent), кликабельных прототипах фичи и демо-экране DetailScreen —
не реальные ПДн, та же категория, что factories/doubles/specs. Добавлены пути
и плейсхолдер-паттерн в .gitleaks.toml. full-history скан: no leaks found.
эскейп: фиксируй (авторизовано владельцем)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Прогон фичи глазами «самого тупого клиента» на изолированной тест-БД (прод не тронут):
все формы, групповые действия, биллинг с реальным списанием, эмуляция поставки Агента, визуал.
Деньги в порядке (300/50 списываются ровно при успехе, без двойных/ложных списаний).
Найдено и ПОЧИНЕНО 6 находок (код — коммит worktree-avtopodbor 1b3683c6).
Независимая перепроверка по коду; одна самокоррекция (общий тост, не «полная тишина»).
эскейп: фиксируй (авторизовано владельцем)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Находки эталон↔реализация и их закрытие (F1 «Предложения», F2 админ-тарифы,
F3 биллинг, M2 чистка; M1 — не баг; N1/M3 — хвосты). Код фичи — отдельным
коммитом в ветке worktree-avtopodbor (793b20a3).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Прод приведён к gitea-main 84dfbc85 один-в-один (rsync-checksum, потерь нет);
бэкап цел; экран Тенанты на серверную пагинацию выкачен; 992 фронт-теста зелёные;
деньги t2=1 839 405₽ целы. Остатки не-git на проде объяснены (.bak-precutover до 03.07).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Свод за заход «закрывай хвосты»: разбор и фикс preflight-sweep/reminder (no-op с 26.06
из-за RLS-роли очереди), self-heal 4 проектов на проде, деньги t2 целы, playwright в deps.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Корень: после переезда на Managed PG очередь ходит под ролью crm_app_user (RLS),
и Tenant::query() в BalancePreflightSweepJob/BalanceFrozenReminderJob отдавал 0 строк
без app.current_tenant_id — биллинг-преflight молча стал no-op с 26.06 (ни заморозок,
ни снятия проектных блоков). Перечень тенантов теперь берётся через pgsql_supplier
(BYPASSRLS), модель грузится внутри per-tenant SET LOCAL контекста. Логика проверена
на боевых данных: t25/t26 снимутся, t27/t30 заморозятся.
Playwright рантайма supplier-портала объявлен в dependencies ровно 1.59.0 под
chromium-1217 + package-lock синхронизирован; деплой ставит его npm ci --omit=dev,
durable к чистке node_modules.
Тесты Billing 18/18, pint/phpstan чисто.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>