Commit Graph

943 Commits

Author SHA1 Message Date
Дмитрий eddad70d63 chore(G7-A): baseline Pest-ложноположительных в SupportRequestControllerTest
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 15:08:30 +03:00
Дмитрий 7ebe25385b feat(G7-A): экран «Помощь» (форма-заявка) + пункт меню + роут
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 15:04:17 +03:00
Дмитрий dd365b0a0e feat(G7-A): meta support-email + условный JivoSite в shell-blade
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 15:02:14 +03:00
Дмитрий b02ab1cadf feat(G7-A): POST /api/support-requests + тест (store+mail+валидация)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 15:00:12 +03:00
Дмитрий 0469994948 feat(G7-A): SupportRequestMail + шаблон письма
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 14:55:21 +03:00
Дмитрий 448633e59c feat(G7-A): модель SupportRequest
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 14:54:25 +03:00
Дмитрий 0826cb24dd feat(G7-A): таблица support_requests (schema + миграция, RLS)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 14:53:57 +03:00
Дмитрий 35e4f020b9 feat(G7-A): конфиг support.email + jivosite.widget_id
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 14:50:39 +03:00
Дмитрий d33050f8f6 fix(schema): закрыть остаток дрейфа (project_routing_snapshots) + guard CREATE POLICY 05_27 (v8.47)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 13:37:48 +03:00
Дмитрий 4139896e0c fix(migration): guard CREATE POLICY в tenant_requisites (DROP IF EXISTS) — чинит migrate:fresh
G1-миграция guard'ила CREATE TABLE, но не CREATE POLICY (в PG нет IF NOT EXISTS) → коллизия с политикой из schema.sql на migrate:fresh. Тот же дрейф-класс. Теперь migrate:fresh зелёный целиком.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 12:58:37 +03:00
Дмитрий 1cb00e149c fix(schema): синк дрейфа lead-region в schema.sql + guard миграции 05_31 (v8.46)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 12:55:04 +03:00
Дмитрий ef28196082 fix(stan): Larastan-долг G1/G6 = 0 ошибок (реальные баги — починены, не спрятаны)
Продуктовый код (фиксы, не baseline): TenantRequisites+SupplierLead — явные @property (ide-helper:models пропускал модели); DealsController V1 — лишний ?-> на non-null received_at; ScrubPii — guard instanceof Monolog. Тест-код: ImitationTestCase @param int; findByInn return-type. Baseline перегенерён — в нём ТОЛЬКО ложноположительные (Pest TestCall + защитный ?-> на nullable first() в debug-строках ScenarioBC), 0 продуктовых подавлений (проверено диффом). composer stan: 0.

NB: столбцы lead-region (dadata_qc/phone_operator/region_source/resolved_subject_code) есть в БД, но отсутствуют в db/schema.sql — отдельный дрейф схемы.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 12:40:00 +03:00
Дмитрий 91e00b606f fix(G3): счётчик «7 событий» в уведомлениях + убрать «напоминаниях» из подсказки таймзоны
Хвосты, пойманные живым Playwright: захардкоженное «8 событий» после удаления reminder-события + stale-подсказка профиля.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 12:06:17 +03:00
Дмитрий ca04b45a55 chore(G3): почистить phpstan-baseline от напоминаний
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 11:55:57 +03:00
Дмитрий 3c214a692b feat(G3): drop таблицы reminders — миграция + schema.sql + CHANGELOG
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 11:48:26 +03:00
Дмитрий 8de94c46aa fix(G3): убрать создание reminders из HistoricalImportService (шов CSV-импорта)
CSV-колонку «Напоминание» парсер по-прежнему читает (внешний формат), но строки-напоминания больше не создаются — модель Reminder удалена.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 11:43:00 +03:00
Дмитрий 8e8cce885d feat(G3): убрать reminder из дефолтов notification_preferences (factory+seeder)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 11:38:58 +03:00
Дмитрий 5df354c39c feat(G3): удалить контроллер/роуты/модель/команду/письмо напоминаний
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 11:37:57 +03:00
Дмитрий c0f7d9ac73 feat(G3): убрать ветку reminder из NotificationService
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 11:36:27 +03:00
Дмитрий cb73457ec7 feat(G3): убрать next_reminder_at-подзапрос из DealController
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 11:34:36 +03:00
Дмитрий 25ac65e5e5 feat(G3): убрать преференцию «Напоминание» + хвосты фронт-тестов
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 11:29:46 +03:00
Дмитрий 0a3f90839c feat(G3): убрать next_reminder_at из фронт-слоя сделок
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 11:29:35 +03:00
Дмитрий abe6d51b0e feat(G3): убрать экран «Напоминания» и раздел в карточке сделки
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 11:18:49 +03:00
Дмитрий bb2e0daad8 feat(G6): контроллер + роут GET /api/v1/deals (публичный read-API сделок)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 10:13:08 +03:00
Дмитрий 206e7a328d feat(G6): middleware ApiKeyAuth — аутентификация по API-ключу
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 10:12:03 +03:00
Дмитрий 1fd24745d1 test(G6): приёмка публичного API сделок (RED)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 10:11:24 +03:00
Дмитрий 6bfe654efa test(G2-B): UserFactory зеркалит новый дефолт new_lead.email true
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 08:53:36 +03:00
Дмитрий 8a3569df9e feat(G2-B): миграция — дефолт new_lead.email true + дотяжка существующих
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 08:53:07 +03:00
Дмитрий e6c921935c test(G2-B): дефолт new_lead.email=true (RED) + backfill SQL
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 08:51:04 +03:00
Дмитрий 9317a45e7e fix(G1-tail): письмо с кодом в очередь + не валить register/resend при сбое доставки
Owner-decision: register не должен падать 500 при сбое SMTP — код уже создан,
клиент может «отправить повторно». Mail::queue + try/catch + Log (без email — ПДн).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 08:29:15 +03:00
Дмитрий df8f568888 fix(G1-tail): убран стейл-Шаг 6 (webhook_log удалён в v8.35) из OperationalFullFlowTest
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 08:18:30 +03:00
Дмитрий a8f833e5fe fix(G1-tail): NBSP перед ₽ через escape \u00A0 в DashboardPageHead (lint:vue green)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 08:18:30 +03:00
Дмитрий dec1c95092 feat(G1/SP3c): блок платёжных реквизитов + статус-чип + валидация (поля по типу лица)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 07:58:47 +03:00
Дмитрий 6dd9f041fa feat(G1/SP3b): UX гейта — alert requisites_required + переход к реквизитам
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 07:24:27 +03:00
Дмитрий 4fddba60b0 feat(G1/SP3b): вкладка Реквизиты в Настройках + deep-link ?tab=requisites
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 07:24:26 +03:00
Дмитрий 5347976566 feat(G1/SP3b): вкладка RequisitesTab — лёгкая форма реквизитов
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 07:24:26 +03:00
Дмитрий c42e99747e feat(G1/SP3b): api-обёртка реквизитов (get/update/lookup-inn)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 07:24:26 +03:00
Дмитрий f9e1ddb7da fix: дополнен мок DashboardSummary в DashboardView.spec (avg_lead_cost_rub) — type-check green
Пред-существующая type-ошибка (поле required в DashboardSummary отсутствовало в моке). Не связано с SP3a; убирает единственную ошибку vue-tsc. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 23:45:08 +03:00
Дмитрий d3483c21d8 feat: G1/SP3a фронт входа — регистрация + подтверждение почты
Переработка register под новый бэкенд SP1 (код на почту), новый ConfirmEmailView, капча-шов, роут /confirm-email. Проверено Playwright: register→код→confirm→dashboard, негатив, fallback email. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 23:33:26 +03:00
Дмитрий 60f76d5919 feat: G1/SP2 реквизиты клиента + ИНН по DaData + гейт первого проекта
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 22:25:23 +03:00
Дмитрий 9a661401a2 feat: G1/SP1 самозапись клиента с подтверждением почты 6-значным кодом
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 19:33:33 +03:00
Дмитрий 78e4c09d2d feat: G2-A дайджест новых сделок на почту - письмо-сводка раз в 30 минут вместо письма на каждую сделку
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 14:40:12 +03:00
Дмитрий 14d076b805 feat: G4 убрать неработающий push-канал из настроек уведомлений + находка G8 про сломанный фронт-тест-раннер
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 13:46:31 +03:00
Дмитрий c2bdfdd7d3 refactor(security): единый источник security-заголовков — nginx
Убраны дубли HTTP-заголовков. nginx уже шлёт enforcing CSP, X-Frame-Options,
X-Content-Type-Options, Referrer-Policy, HSTS, Permissions-Policy, COOP, CORP
через add_header always. App-уровневый middleware SecurityHeaders дублировал
четыре из них и слал лишний CSP Report-Only; на проде add_header always плюс
PHP-заголовок давали дубль в ответе.

- удалён middleware SecurityHeaders и его регистрация в bootstrap/app.php
- SecurityHeadersTest переписан: фиксирует, что приложение эти заголовки не ставит

Прод-дедуп вступит в силу после деплоя. Verify локально 4 из 4 green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 09:31:47 +03:00
Дмитрий c0a7fa6c74 test: починка харнеса AdminBilling и AdminIncidents
AdminBillingIndexTest: teardown глушит session-триггеры на время очистки.
DELETE tenants каскадил в append-only tenant_operations_log, триггер
audit_block_mutation давал RAISE EXCEPTION. Плюс ensureRange гарантирует
месячные партиции balance_transactions за прошлые 2 месяца под SharesSupplierPdo.

AdminIncidentsIndexTest: добавлен трейт SharesSupplierPdo. Контроллер читает
через pgsql_supplier, тест писал через дефолтный pgsql под DatabaseTransactions,
cross-connection невидимость давала total=0.

Verify: оба класса 20 из 20 green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 09:05:06 +03:00
Дмитрий 7068664026 fix(test): routing-snapshot today+tomorrow в CsvWebhookRaceTest + PII на slack/papertrail/stderr
C: LeadRouter.activeSnapshotDate после 21:00 МСК = завтра; снимок только на сегодня не активен -> снимки на обе даты. A: PII-процессор на остальные лог-каналы, 6/6.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 21:37:41 +03:00
Дмитрий e2425ce873 feat(security): PII-scrubbing процессор логов — Medium go-live
Monolog PiiScrubbingProcessor (телефоны/email -> [PHONE]/[EMAIL]) + ScrubPii tap на single/daily в config/logging.php. Pest 6/6 GREEN. Sentry-scrubbing (OPEN-И-16) не реализуем: sentry-laravel не установлен — open-item.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 20:43:28 +03:00
Дмитрий f32366279f feat(security): webhook DNS-rebind пиннинг + аддитивный HMAC supplier-webhook — edge/P2 go-live
WebhookUrlGuard::safeDeliveryIp один резолв + CURLOPT_RESOLVE пиннинг в test(); supplier-webhook принимает HMAC X-Webhook-Signature как альтернативу URL-секрету + secretless-маршрут. Аддитивно, backward-compat. 6 новых тестов GREEN; 5 падений webhook-сюиты pre-existing (Phase-3 B-regex + CsvWebhookRaceTest), подтверждено baseline без моих файлов.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 20:21:11 +03:00
Дмитрий fdb1c1cca2 feat(security): per-IP route-throttle на auth-эндпоинтах — P1 go-live
Именованные лимитеры auth-login/auth-2fa/auth-password (perMinute 20 by IP) в AppServiceProvider; throttle-middleware на login/forgot/reset/2fa-verify/recovery в web.php. Закрывает per-IP объёмный перебор. Pest tests/Feature/Auth 97/97 GREEN.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 19:56:23 +03:00
Дмитрий dea02e402d feat(security): CSP Report-Only под Vue+Vuetify SPA — 2-я ZAP Medium go-live
Report-Only политика в middleware SecurityHeaders; Pest 6/6 GREEN.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 19:30:51 +03:00