1011a37e77
feat(sales): кандидат — ИНН обязателен, юрлицо отдельно от бренда, контактные лица Замечание владельца по форме «Добавить кандидата»: телефонов бывает много, нужны ФИО и должность человека, ИНН обязателен, бренд и юрлицо — разные вещи, юрлицо подтягивать по ИНН через ДаData. - БД v8.73: sales_prospects.legal_name VARCHAR(500) + contacts JSONB DEFAULT []. phone остаётся «главным телефоном»; inn в БД по-прежнему nullable — карточки из поиска и 24 живые строки могут быть без него. - store(): ИНН обязателен + контрольная сумма ФНС; повтор ИНН у того же менеджера — понятный 422 вместо 500 от уникального индекса; пустые контакты и телефоны отсекаются; phone = первый телефон первого контакта. - POST /api/sales/prospects/lookup-inn — юрлицо/город по ИНН через готовый шов PartyLookup (тот же, что в «Реквизитах»). Ничего не сохраняет; ДаData молчит или упала — заводим руками. - Диалог создания: ИНН* с кнопкой «Найти», бренд*, юрлицо, блок контактных лиц (+человек / +телефон). Карточка показывает юрлицо и контакты со ссылками tel:. Спека §16, CHANGELOG_schema v8.73. Гейты: Pest 28/28, Vitest 38/38, Larastan 0 в своих файлах, rls-reviewer PASS 4/4. LEFTHOOK_EXCLUDE: larastan/cspell падают на файлах параллельной сессии tests/Feature/Admin/*Balances*, свои файлы проверены отдельно и чисты. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> @