[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6XGHB7T505RSP7DN49PK2WF":3,"skill-same:01M6XGHB7T505RSP7DN49PK2WF":52},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":25,"linkOnly":26,"markdownContent":27,"markdownBody":28,"frontMatter":29,"refName":30,"commitSha":31,"skillDirectory":32,"forksCount":33,"repositoryHtmlUrl":34,"repositoryHomepageUrl":6,"ownerHtmlUrl":35,"ownerBlogUrl":6,"ownerDescription":36,"updatedAt":37,"install":38,"resources":51},"01M6XGHB7T505RSP7DN49PK2WF","insurance-aggregator",null,"Страховой агрегатор: архитектура, калькуляторы, адаптеры СК, CRM, лояльность, реферальная программа. Обучен на InsSmart, Sravni Labs, Polis.Online, Pampadu. Use when: страхование, ОСАГО, КАСКО, ВЗР, ипотечное, агрегатор, калькулятор, котировки, страховой агент, полис, СК, комиссия.","FDU-INS\u002FInsurance-Skills","FDU-INS","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F167067594?v=4","01M6XEYMRS4CVJMZ834YWE66BV","FDU-Insurance","01M6XEYMXPDA34HFM0ZE6AY78G",82,"Apache-2.0","https:\u002F\u002Fgithub.com\u002FFDU-INS\u002FInsurance-Skills\u002Fblob\u002Fmain\u002FSkills\u002Finsurance-aggregator\u002FSKILL.md",[],[19,20,21,22,23,24],"aggregator","insurance","insurance aggregator","use","crm","when","2026-11-10 10:12:30",false,"---\nname: insurance-aggregator\ndescription: \"Страховой агрегатор: архитектура, калькуляторы, адаптеры СК, CRM, лояльность, реферальная программа. Обучен на InsSmart, Sravni Labs, Polis.Online, Pampadu. Use when: страхование, ОСАГО, КАСКО, ВЗР, ипотечное, агрегатор, калькулятор, котировки, страховой агент, полис, СК, комиссия.\"\n---\n\n# Insurance Aggregator — Полная экспертиза\n\nЭтот skill содержит ВСЕ знания, необходимые для создания продакшн-уровня страхового агрегатора — B2B\u002FB2C платформы для расчёта, сравнения и оформления страховых полисов.\n\nОбучен на реальных данных 4 B2B-платформ (InsSmart, Sravni Labs, Polis.Online, Pampadu), потребительском Sravni.ru и 20+ open-source проектах.\n\n---\n\n## Часть 1: Архитектура платформы\n\n### 1.1 Три роли\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│                     INSURANCE PLATFORM                       │\n├─────────────┬──────────────────────┬────────────────────────┤\n│ Пользователь│      Агент           │    Админ               │\n│ (B2C)       │      (B2B)           │    (Internal)          │\n├─────────────┼──────────────────────┼────────────────────────┤\n│ Поиск полиса│ Калькулятор          │ Управление СК          │\n│ Сравнение   │ Результаты + комиссия│ Комиссионные правила   │\n│ Покупка     │ Оформление           │ Управление агентами    │\n│ Мои полисы  │ CRM клиентов         │ Отчёты (глобальные)    │\n│ Напоминания │ Баланс \u002F Финансы     │ Лояльность (настройки) │\n│             │ Отчёты               │ Модерация              │\n│             │ Реферальная программа│                        │\n│             │ Инструменты продаж   │                        │\n│             │ Лояльность (уровни)  │                        │\n└─────────────┴──────────────────────┴────────────────────────┘\n```\n\n### 1.2 Модули платформы\n\n| Модуль | Приоритет | Описание |\n|---|---|---|\n| **Калькуляторы** | P0 | Multi-step wizard для каждого продукта, автозаполнение |\n| **Quote Engine** | P0 | Параллельные запросы к адаптерам СК, кеширование, ранжирование |\n| **Результаты** | P0 | Список предложений: цена, СК, рейтинг, покрытие, комиссия агента |\n| **Оформление полиса** | P0 | Checkout: оплата, подтверждение, генерация полиса |\n| **Мои полисы** | P0 | Активные, истекающие, архив, статусы |\n| **CRM клиентов** | P0 | Карточка клиента: ФИО, полисы, расчёты, контакты |\n| **Баланс \u002F Финансы** | P0 | Начисления, списания, вывод средств |\n| **Черновики** | P1 | Автосохранение незавершённых расчётов |\n| **Отчёты** | P1 | Продажи, воронка, Excel export, группировка |\n| **Реферальная программа** | P1 | Генерация ссылок, метрики, типы |\n| **Лояльность** | P2 | 5 уровней, квартальный расчёт, бонусные комиссии |\n| **Планировщик** | P2 | Календарь: ДР, пролонгации, events |\n| **Инструменты продаж** | P2 | Виджеты, визитки, контент, обучение |\n| **Управление агентами** | P2 | Подагенты, иерархия, квоты |\n| **Справочники СК** | P2 | Рейтинги, отзывы, claim settlement ratio |\n\n### 1.3 Жизненный цикл полиса\n\n```\nЧерновик → Расчёт → Выбор → Оформление → Оплата → Активный → Пролонгация\n                                                        ↓\n                                                    Истекающий (за 30 дней)\n                                                        ↓\n                                                    Истёкший (архив)\n                                                        ↓\n                                              Claims (при страховом случае)\n```\n\n---\n\n## Часть 2: Продуктовый каталог\n\n### 2.1 Страховые продукты\n\n#### ОСАГО (обязательное, регулируется ЦБ РФ)\n- **Формула**: ТБ × КТ × КБМ × КВС × КО × КМ × КС × КП × КН\n- **Коэффициенты**:\n  - ТБ: 2746-4942₽ (коридор ЦБ для категории B)\n  - КТ: 0.6-2.1 (территориальный, по 88 регионам)\n  - КБМ: 0.46-3.92 (бонус-малус, 14 классов, проверка АИС РСА)\n  - КВС: 0.83-1.87 (возраст × стаж, матрица)\n  - КО: 1.0 (ограниченный список) \u002F 1.94 (без ограничений)\n  - КМ: 0.6-1.6 (мощность двигателя)\n  - КС: 0.5-1.0 (период использования)\n  - КП: 0.2-1.0 (период страхования)\n  - КН: 1.0-1.5 (нарушения)\n- **Автозаполнение**: по госномеру → марка, модель, год, мощность\n- **КБМ**: автоматическая проверка через АИС РСА (Edge Function)\n\n#### КАСКО (добровольное, устанавливается СК)\n- **Примерная стоимость**: 4-8% от стоимости авто\n- **Базовая формула**: стоимость_авто × базовая_ставка × К_возраст_авто × К_регион × К_франшиза × К_стаж × К_КБМ\n- **Доп.факторы**: кол-во ключей, срок владения, КАСКО-убытки за год, кредитный авто, автозапуск, праворульный\n- **Покрытие**: полное КАСКО, мини-КАСКО (ограниченные риски), КАСКО + GAP\n\n#### Ипотечное (обязательное для ипотеки)\n- **Типы покрытия**: Имущество (конструктив), Жизнь заёмщика, Титул\n- **Стоимость**: 0.15-0.5% от остатка кредита\n- **Факторы**: банк-кредитор, остаток, год постройки, тип объекта, пол, возраст, здоровье\n- **Особенность**: банк диктует минимальный набор покрытий\n\n#### ВЗР \u002F Travel\n- **Стоимость**: ~90-300₽\u002Fдень\n- **Факторы**: страна, дни, возраст, сумма покрытия\n- **Опции**: спорт, беременность, хронические заболевания\n- **Quick-picks стран**: Грузия, Таиланд, Шенген, Китай, Вьетнам, Турция\n\n#### НС (Несчастный случай)\n- **Типы**: На период \u002F На год\n- **Опции**: Для лагеря, Для спорта\n- **Простая форма**: возраст, даты, кол-во\n\n#### Антиклещ\n- **Стоимость**: 340-390₽\n- **Поля**: возраст, дата начала (на год)\n- **Референс**: Зетта 340₽, СберСтрах 360₽, ВСК 390₽, Ингосстрах 390₽\n\n#### ИФЛ (Имущество физлиц)\n- **Покрытие**: Отделка\u002Fремонт, Мебель\u002Fтехника, Ответственность перед соседями\n- **Фильтры**: газ, деревянные перекрытия, аренда\n- **Стоимость**: от 1,800₽\u002Fгод (квартира)\n\n#### Титул\n- **Период**: годовой\n- **Стоимость**: зависит от рыночной стоимости имущества (300K-50M₽)\n\n### 2.2 Дополнительные услуги\n\n| Услуга | Описание |\n|---|---|\n| Техосмотр | Запись на ТО: город, категория ТС, станция |\n| ДКП | Бесплатный шаблон договора купли-продажи |\n| Проверка ОСАГО | По VIN — актуальность полиса |\n| Подбор ипотеки | 20+ банков, сравнение условий |\n| Оценка имущества | Для страхования \u002F ипотеки |\n| Биржа ОСАГО | 100+ исполнителей, аукционная модель |\n\n---\n\n## Часть 3: Multi-Step Wizard — калькулятор\n\n### 3.1 Архитектура визарда\n\n```typescript\ninterface WizardStep {\n  id: string\n  title: string\n  fields: FieldConfig[]\n  validation: ZodSchema\n  autoFill?: AutoFillConfig  \u002F\u002F автозаполнение (госномер → данные ТС)\n  skipCondition?: (data: FormData) => boolean  \u002F\u002F пропустить шаг\n}\n\ninterface FieldConfig {\n  name: string\n  label: string\n  type: 'text' | 'select' | 'date' | 'number' | 'checkbox' | 'toggle' | 'phone' | 'masked'\n  mask?: string           \u002F\u002F '#### ######' для паспорта\n  required: boolean\n  defaultValue?: unknown\n  options?: SelectOption[] \u002F\u002F для select\n  autoComplete?: AutoCompleteConfig\n  dependsOn?: string      \u002F\u002F показать только если заполнено другое поле\n  copyFrom?: string       \u002F\u002F «Скопировать из собственника»\n}\n```\n\n### 3.2 ОСАГО — Golden Standard (7 шагов)\n\n**Шаг 1: Данные ТС**\n```\nfields:\n  - gosNumber: { type: 'masked', mask: 'A ### AA ###', autoComplete: vehicleLookup }\n  - noGosNumber: { type: 'checkbox', label: 'Госномер отсутствует' }\n  - withTrailer: { type: 'checkbox', label: 'ТС с прицепом' }\n  - category: { type: 'select', options: ['B', 'A', 'C', 'D', 'BE', ...], default: 'B' }\n  - purpose: { type: 'select', options: ['Личная', 'Такси', 'Учебная', 'Перевозка'], default: 'Личная' }\n  - brand: { type: 'select', autoFilled: true }\n  - model: { type: 'select', dependsOn: 'brand', autoFilled: true }\n  - year: { type: 'number', min: 1970, max: currentYear, autoFilled: true }\n  - power: { type: 'number', suffix: 'л.с.', autoFilled: true }\n  - powerKw: { type: 'number', suffix: 'кВт' }\n  - vin: { type: 'masked', mask: 'XXXXXXXXXXXXXXXXX' }\n  - docType: { type: 'select', options: ['ПТС', 'СТС', 'ЭПТС'] }\n  - docSeries: { type: 'masked', mask: '## ##' }\n  - docNumber: { type: 'masked', mask: '######' }\n  - docDate: { type: 'date' }\n```\n\n**Шаг 2: Собственник**\n```\nfields:\n  - ownerType: { type: 'select', options: ['ФЛ', 'ИП', 'ЮЛ'], default: 'ФЛ' }\n  - lastName: { type: 'text', required: true }\n  - firstName: { type: 'text', required: true }\n  - middleName: { type: 'text' }\n  - birthDate: { type: 'date', required: true }\n  - passportSeries: { type: 'masked', mask: '## ##' }\n  - passportNumber: { type: 'masked', mask: '######' }\n  - passportDate: { type: 'date' }\n  - address: { type: 'text', autoComplete: addressSuggest }\n```\n\n**Шаг 3: Страхователь**\n```\nfields:\n  - isOwner: { type: 'checkbox', label: 'Является собственником', default: true }\n  \u002F\u002F если isOwner=false → показать те же поля что у собственника\n  - lastName, firstName, middleName, birthDate, passport*, address (skipIf: isOwner)\n```\n\n**Шаг 4: Водители**\n```\nfields:\n  - multiDrive: { type: 'toggle', label: 'Без ограничений (мультидрайв)' }\n  \u002F\u002F если multiDrive=false → показать список водителей\n  - drivers[]: {\n      lastName, firstName, middleName: { type: 'text' }\n      birthDate: { type: 'date' }\n      licSeries: { type: 'masked', mask: '## ##' }\n      licNumber: { type: 'masked', mask: '######' }\n      licDate: { type: 'date' }  \u002F\u002F дата выдачи ВУ\n      expStart: { type: 'date' } \u002F\u002F дата начала стажа\n      foreignLic: { type: 'checkbox', label: 'Иностранное ВУ' }\n      prevLic: { type: 'checkbox', label: 'Указать предыдущее ВУ (для переноса КБМ)' }\n      prevLicSeries, prevLicNumber: { dependsOn: 'prevLic' }\n      copyFromOwner: { type: 'button', label: 'Скопировать из собственника' }\n      copyFromInsurer: { type: 'button', label: 'Скопировать из страхователя' }\n    }\n  - addDriver: { type: 'button', label: '+ Ещё один водитель' }\n```\n\n**Шаг 5: Данные полиса**\n```\nfields:\n  - startDate: { type: 'date', min: tomorrow }\n  - period: { type: 'select', options: ['3 мес', '6 мес', '12 мес'], default: '12 мес' }\n  - greenCorridor: { type: 'checkbox', label: 'Предыдущий полис (зелёный коридор)' }\n  - prevPolicyNumber: { dependsOn: 'greenCorridor', type: 'masked' }\n```\n\n**Шаг 6: Контакты**\n```\nfields:\n  - phone: { type: 'phone', mask: '+7 (###) ###-##-##' }\n  - email: { type: 'text', validation: email }\n```\n\n**Шаг 7: Подтверждение**\n```\nfields:\n  - consentPD: { type: 'checkbox', required: true, label: 'Согласие на обработку ПД (152-ФЗ)' }\n  - consentSK: { type: 'checkbox', required: true, label: 'Согласие на передачу данных СК' }\n  - consentAccuracy: { type: 'checkbox', required: true, label: 'Подтверждаю достоверность' }\n  - consentRules: { type: 'checkbox', required: true, label: 'Ознакомлен с правилами' }\nactions:\n  - saveDraft: { label: 'Сохранить черновик', variant: 'outline' }\n  - calculate: { label: 'Рассчитать', variant: 'primary' }\n```\n\n### 3.3 Автозаполнение по госномеру\n\n```\nПользователь вводит госномер (напр. А123БВ777)\n  → Edge Function insurance-vehicle-lookup\n    → API запрос к сервису (ГИБДД \u002F RSA \u002F коммерческий API)\n    → Возврат: { brand, model, year, power, vin, engineVolume }\n  → Форма автозаполняется\n  → Пользователь проверяет и корректирует\n```\n\n### 3.4 Проверка КБМ\n\n```\nДля каждого водителя:\n  → Edge Function insurance-kbm-check\n    → Запрос к АИС РСА (по ФИО + ДР + ВУ)\n    → Возврат: { kbmClass: number, kbmValue: number, prevInsurer: string }\n  → КБМ автоподставляется в расчёт\n  → Кеширование: 30 дней (КБМ меняется 1 раз\u002Fгод 1 апреля)\n```\n\n---\n\n## Часть 4: Quote Engine\n\n### 4.1 Архитектура\n\n```\n┌─────────────┐\n│  Calculator  │  ← пользователь заполнил форму\n│  (Frontend)  │\n└──────┬──────┘\n       │ POST \u002Fapi\u002Finsurance-quote\n       ▼\n┌──────────────┐\n│ Quote Engine │  ← Edge Function\n│              │\n│ 1. Validate  │  ← Zod schema validation\n│ 2. Cache?    │  ← Есть ли кешированный результат?\n│ 3. Fan-out   │  ← Promise.allSettled([...adapters])\n│ 4. Collect   │  ← Собрать ответы\n│ 5. Rank      │  ← Отсортировать\n│ 6. Cache     │  ← Сохранить в quote_sessions\n│ 7. Return    │  ← Отдать клиенту\n└──────────────┘\n       │\n       ├────────────┬───────────────┬──────────────┐\n       ▼            ▼               ▼              ▼\n┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐\n│ Adapter: │ │ Adapter: │ │ Adapter: │ │ Adapter: │\n│ Ингос    │ │ Альфа    │ │ СОГАЗ    │ │ Ренессанс│\n└──────────┘ └──────────┘ └──────────┘ └──────────┘\n```\n\n### 4.2 Adapter interface\n\n```typescript\ninterface InsuranceProviderAdapter {\n  code: string           \u002F\u002F 'ingos', 'alpha', 'sogaz'\n  name: string           \u002F\u002F 'Ингосстрах'\n  logo: string           \u002F\u002F URL логотипа\n  supportedProducts: ProductCode[]\n  timeout: number        \u002F\u002F ms, per-provider\n\n  getQuote(req: QuoteRequest): Promise\u003CProviderQuote[]>\n  purchase(req: PurchaseRequest): Promise\u003CPurchaseResult>\n  getStatus(policyId: string): Promise\u003CPolicyStatus>\n  cancel(policyId: string): Promise\u003CCancelResult>\n}\n\ninterface ProviderQuote {\n  providerId: string\n  providerName: string\n  providerLogo: string\n  providerRating: number  \u002F\u002F 1-5\n  productCode: ProductCode\n  premium: number         \u002F\u002F стоимость полиса ₽\n  commission: number      \u002F\u002F комиссия агента ₽\n  commissionPercent: number\n  coverage: CoverageDetails\n  franchise?: number      \u002F\u002F франшиза ₽\n  paymentOptions: PaymentOption[]\n  purchaseUrl?: string\n  validUntil: string      \u002F\u002F ISO date, когда котировка истекает\n}\n```\n\n### 4.3 Quote Session\n\n```typescript\ninterface QuoteSession {\n  id: string             \u002F\u002F uuid\n  userId: string\n  productCode: ProductCode\n  params: QuoteRequest   \u002F\u002F входные параметры\n  paramsHash: string     \u002F\u002F SHA-256 для дедупликации\n  status: 'pending' | 'partial' | 'complete' | 'expired'\n  results: ProviderQuote[]\n  errors: ProviderError[]  \u002F\u002F какие адаптеры упали\n  createdAt: string\n  expiresAt: string      \u002F\u002F TTL 15 минут\n}\n```\n\n### 4.4 Кеширование\n\n```\nLayer 1: React Query (staleTime: 5 min) — фронтенд\nLayer 2: Quote Session (TTL: 15 min) — те же параметры → тот же результат\nLayer 3: КБМ кеш (TTL: 30 days) — обновляется 1 раз\u002Fгод 1 апреля\nLayer 4: Vehicle кеш (TTL: 365 days) — данные ТС меняются редко\nLayer 5: Provider rate кеш (TTL: 24h) — тарифы СК для аналитики\n```\n\n---\n\n## Часть 5: Результаты расчёта\n\n### 5.1 Карточка предложения\n\n```\n┌─────────────────────────────────────────────────┐\n│ [Лого СК]  Ингосстрах           ★ 4.7 (1,234)  │\n│                                                  │\n│ ОСАГО                           12 450 ₽        │\n│ Покрытие: стандартное                            │\n│ Рейтинг надёжности: A++         Комиссия: 8%    │\n│                                                  │\n│ [Подробнее]  [Сравнить]  [== Оформить ==]       │\n└─────────────────────────────────────────────────┘\n```\n\n### 5.2 Сортировка и фильтры\n\n**Сортировка:**\n- По цене (↑↓) — default\n- По рейтингу СК (↑↓)\n- По сумме покрытия (↑↓)\n- По комиссии агента (↑↓) — только для агентов\n\n**Фильтры:**\n- Страховая компания (мультивыбор)\n- Франшиза (0 \u002F 10K \u002F 20K \u002F 50K)\n- Минимальное покрытие\n- Рейтинг СК (от 3.0 \u002F от 4.0 \u002F от 4.5)\n\n### 5.3 Сравнение (Comparison Mode)\n\nПользователь выбирает 2-4 предложения → side-by-side таблица:\n\n| Параметр | Ингосстрах | АльфаСтрахование | СОГАЗ |\n|---|---|---|---|\n| Цена | 12,450₽ | 11,890₽ | 13,200₽ |\n| Рейтинг | 4.7 | 4.5 | 4.3 |\n| Покрытие | Стандарт | Стандарт | Расширенное |\n| Франшиза | 0₽ | 0₽ | 15,000₽ |\n| Комиссия | 8% | 7% | 9% |\n| CSR | 96% | 93% | 91% |\n\n---\n\n## Часть 6: CRM клиентов\n\n### 6.1 Карточка клиента (референс: InsSmart)\n\n```\n┌─ Клиент ────────────────────────────────────┐\n│ Иванов Иван Иванович                        │\n│ ДР: 15.03.1985 (39 лет)                     │\n│ Тел: +7 (999) 123-45-67                     │\n│ Email: ivanov@example.com                    │\n│                                              │\n│ Авто: BMW X5, 2020, 249 л.с.                │\n│ Госномер: А123БВ777                          │\n│                                              │\n│ ┌─ Полисы ─────────────────────────────────┐ │\n│ │ ОСАГО  #XXX  до 15.09.2026  ✅ активен  │ │\n│ │ КАСКО  #YYY  до 15.09.2026  ✅ активен  │ │\n│ │ ОСАГО  #ZZZ  до 15.09.2025  ⛔ истёк    │ │\n│ └──────────────────────────────────────────┘ │\n│                                              │\n│ ┌─ Расчёты ────────────────────────────────┐ │\n│ │ ОСАГО  12 предложений  15.08.2026       │ │\n│ │ КАСКО  8 предложений   14.08.2026       │ │\n│ └──────────────────────────────────────────┘ │\n│                                              │\n│ [Новый расчёт] [Пролонгация] [Редактировать]│\n└──────────────────────────────────────────────┘\n```\n\n### 6.2 Пролонгации\n\nInsSmart и Sravni Labs автоматически отслеживают полисы и показывают:\n- Полисы, истекающие через 30 дней → badge «Пролонгация»\n- Автоматическое уведомление агенту и клиенту\n- One-click переход к расчёту нового полиса (данные предзаполнены)\n\n### 6.3 Excel Export\n\nPolis.Online и InsSmart поддерживают:\n- Экспорт CRM в Excel\n- Настройка колонок (какие поля включить)\n- Фильтры (по датам, продуктам, статусам)\n- Группировка (по дням, неделям, месяцам)\n\n---\n\n## Часть 7: Финансы и баланс\n\n### 7.1 Модель начислений\n\n```\nОформлен полис → Комиссия начислена на баланс агента\n  → Status: 'pending' (ожидает подтверждения СК)\n  → Status: 'confirmed' (СК подтвердила оплату)\n  → Status: 'available' (можно вывести)\n  → Status: 'withdrawn' (выведено)\n```\n\n### 7.2 Вывод средств\n\n**InsSmart**: минимум 1,000₽, на карту \u002F расчётный счёт\n**Polis.Online**: быстрые выплаты на карту (для самозанятых)\n\n### 7.3 Отчётность\n\n**По периоду**: Текущий месяц, Прошлый, Квартал, Год, Все время, Custom dates\n**Метрики**:\n- Оформлено полисов (шт.)\n- Премии (₽)\n- Комиссия (₽)\n- Средний чек\n- Конверсия (расчёты → оформления)\n\n---\n\n## Часть 8: Лояльность\n\n### 8.1 5-уровневая система (InsSmart)\n\n```typescript\nconst LOYALTY_LEVELS = [\n  { name: 'Новичок',         threshold: 0,       bonus: 0 },\n  { name: 'Агент',           threshold: 30_000,  bonus: 5 },\n  { name: 'Агент 2.0',       threshold: 75_000,  bonus: 8 },\n  { name: 'Уполномоченный',  threshold: 150_000, bonus: 12 },\n  { name: 'Уполномоченный+', threshold: 300_000, bonus: 15 },\n] as const\n\n\u002F\u002F Расчёт: квартальные премии → определяют уровень\n\u002F\u002F bonus — процент надбавки к базовой комиссии\n```\n\n### 8.2 Механика\n\n- Период оценки: **квартал** (3 месяца)\n- Метрика: сумма **премий** оформленных полисов за квартал\n- Повышение уровня: автоматическое при достижении порога\n- Понижение уровня: если за квартал не дотянул до текущего порога → понижение на 1\n\n---\n\n## Часть 9: Реферальная программа\n\n### 9.1 Модель InsSmart (2-уровневая)\n\n```\nАгент A приглашает Агент B → A получает X% от продаж B\nАгент B приглашает Агент C → A получает Y% от продаж C (2-й уровень)\n```\n\n### 9.2 Модель Polis.Online (типизированные ссылки)\n\n```typescript\ntype ReferralType = \n  | 'mentorship'      \u002F\u002F Кураторство\n  | 'partnership'      \u002F\u002F Партнёрская программа  \n  | 'osago'           \u002F\u002F Оформление ОСАГО\n  | 'mortgage'        \u002F\u002F Оформление ипотечного полиса\n\ninterface ReferralLink {\n  id: string\n  url: string\n  type: ReferralType\n  name: string\n  quotaPercent: number  \u002F\u002F размер квоты %\n  activations: number\n  calculations: number\n  policies: number      \u002F\u002F оформлено\n  createdAt: string\n}\n```\n\n---\n\n## Часть 10: Схема базы данных\n\n### 10.1 Основные таблицы\n\n```sql\n-- Страховые продукты (справочник)\nCREATE TABLE insurance_products (\n  code TEXT PRIMARY KEY,           -- 'osago', 'kasko', 'mortgage', 'vzr'\n  name TEXT NOT NULL,\n  description TEXT,\n  icon TEXT,\n  sort_order INTEGER DEFAULT 0,\n  is_active BOOLEAN DEFAULT true,\n  created_at TIMESTAMPTZ DEFAULT now()\n);\n\n-- Страховые компании (справочник)\nCREATE TABLE insurance_companies (\n  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n  code TEXT UNIQUE NOT NULL,       -- 'ingos', 'alpha', 'sogaz'\n  name TEXT NOT NULL,\n  logo_url TEXT,\n  rating NUMERIC(2,1),             -- 1.0-5.0\n  csr NUMERIC(4,1),                -- claim settlement ratio %\n  is_active BOOLEAN DEFAULT true,\n  supported_products TEXT[],       -- {'osago','kasko','mortgage'}\n  adapter_config JSONB,           -- конфиг адаптера (timeout, base_url, etc.)\n  created_at TIMESTAMPTZ DEFAULT now()\n);\n\n-- Агенты\nCREATE TABLE insurance_agents (\n  id UUID PRIMARY KEY REFERENCES auth.users(id) ON DELETE CASCADE,\n  loyalty_level TEXT DEFAULT 'novice', -- 'novice'|'agent'|'agent2'|'authorized'|'authorized_plus'\n  quarterly_premiums NUMERIC DEFAULT 0,\n  balance NUMERIC DEFAULT 0,\n  referrer_id UUID REFERENCES insurance_agents(id),\n  referral_code TEXT UNIQUE,\n  is_self_employed BOOLEAN DEFAULT false,\n  inn TEXT,\n  created_at TIMESTAMPTZ DEFAULT now()\n);\n\n-- Клиенты агента (CRM)\nCREATE TABLE insurance_clients (\n  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n  agent_id UUID NOT NULL REFERENCES insurance_agents(id),\n  first_name TEXT NOT NULL,\n  last_name TEXT NOT NULL,\n  middle_name TEXT,\n  birth_date DATE,\n  phone TEXT,\n  email TEXT,\n  passport_series TEXT,\n  passport_number TEXT,\n  address TEXT,\n  notes TEXT,\n  created_at TIMESTAMPTZ DEFAULT now(),\n  updated_at TIMESTAMPTZ DEFAULT now()\n);\n\n-- ТС клиента\nCREATE TABLE insurance_vehicles (\n  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n  client_id UUID REFERENCES insurance_clients(id),\n  gos_number TEXT,\n  brand TEXT,\n  model TEXT,\n  year INTEGER,\n  power INTEGER,           -- л.с.\n  vin TEXT,\n  doc_type TEXT,           -- 'pts', 'sts', 'epts'\n  doc_series TEXT,\n  doc_number TEXT,\n  doc_date DATE,\n  created_at TIMESTAMPTZ DEFAULT now()\n);\n\n-- Черновики расчётов\nCREATE TABLE insurance_drafts (\n  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n  user_id UUID NOT NULL REFERENCES auth.users(id),\n  product_code TEXT NOT NULL REFERENCES insurance_products(code),\n  step INTEGER DEFAULT 1,\n  form_data JSONB NOT NULL DEFAULT '{}',\n  created_at TIMESTAMPTZ DEFAULT now(),\n  updated_at TIMESTAMPTZ DEFAULT now()\n);\n\n-- Сессии расчёта (quote sessions)\nCREATE TABLE insurance_quote_sessions (\n  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n  user_id UUID NOT NULL REFERENCES auth.users(id),\n  product_code TEXT NOT NULL,\n  params JSONB NOT NULL,\n  params_hash TEXT NOT NULL,       -- SHA-256 для дедупликации\n  status TEXT DEFAULT 'pending',   -- 'pending'|'partial'|'complete'|'expired'\n  results JSONB DEFAULT '[]',\n  errors JSONB DEFAULT '[]',\n  created_at TIMESTAMPTZ DEFAULT now(),\n  expires_at TIMESTAMPTZ DEFAULT (now() + interval '15 minutes')\n);\n\n-- Полисы\nCREATE TABLE insurance_policies (\n  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n  user_id UUID NOT NULL REFERENCES auth.users(id),\n  agent_id UUID REFERENCES insurance_agents(id),\n  client_id UUID REFERENCES insurance_clients(id),\n  product_code TEXT NOT NULL,\n  company_id UUID REFERENCES insurance_companies(id),\n  policy_number TEXT,\n  status TEXT DEFAULT 'active',    -- 'active'|'expiring'|'expired'|'cancelled'\n  premium NUMERIC NOT NULL,\n  commission NUMERIC DEFAULT 0,\n  start_date DATE NOT NULL,\n  end_date DATE NOT NULL,\n  coverage JSONB,\n  raw_data JSONB,                 -- данные формы для пролонгации\n  created_at TIMESTAMPTZ DEFAULT now()\n);\n\n-- Транзакции баланса агента\nCREATE TABLE insurance_transactions (\n  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n  agent_id UUID NOT NULL REFERENCES insurance_agents(id),\n  policy_id UUID REFERENCES insurance_policies(id),\n  type TEXT NOT NULL,              -- 'commission'|'bonus'|'withdrawal'|'referral'\n  amount NUMERIC NOT NULL,\n  status TEXT DEFAULT 'pending',   -- 'pending'|'confirmed'|'available'|'withdrawn'\n  description TEXT,\n  created_at TIMESTAMPTZ DEFAULT now()\n);\n\n-- Реферальные ссылки\nCREATE TABLE insurance_referral_links (\n  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n  agent_id UUID NOT NULL REFERENCES insurance_agents(id),\n  type TEXT NOT NULL,              -- 'mentorship'|'partnership'|'osago'|'mortgage'\n  name TEXT,\n  code TEXT UNIQUE NOT NULL,\n  quota_percent NUMERIC DEFAULT 0,\n  activations INTEGER DEFAULT 0,\n  calculations INTEGER DEFAULT 0,\n  policies INTEGER DEFAULT 0,\n  created_at TIMESTAMPTZ DEFAULT now()\n);\n\n-- КБМ кеш\nCREATE TABLE insurance_kbm_cache (\n  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n  driver_hash TEXT UNIQUE NOT NULL,  -- SHA-256(ФИО+ДР+ВУ)\n  kbm_class INTEGER NOT NULL,\n  kbm_value NUMERIC NOT NULL,\n  prev_insurer TEXT,\n  checked_at TIMESTAMPTZ DEFAULT now(),\n  expires_at TIMESTAMPTZ DEFAULT (now() + interval '30 days')\n);\n\n-- Vehicle кеш\nCREATE TABLE insurance_vehicle_cache (\n  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n  lookup_key TEXT UNIQUE NOT NULL,  -- госномер или VIN\n  brand TEXT,\n  model TEXT,\n  year INTEGER,\n  power INTEGER,\n  vin TEXT,\n  engine_volume INTEGER,\n  checked_at TIMESTAMPTZ DEFAULT now(),\n  expires_at TIMESTAMPTZ DEFAULT (now() + interval '365 days')\n);\n```\n\n### 10.2 Индексы\n\n```sql\nCREATE INDEX idx_policies_user ON insurance_policies(user_id);\nCREATE INDEX idx_policies_agent ON insurance_policies(agent_id);\nCREATE INDEX idx_policies_status ON insurance_policies(status);\nCREATE INDEX idx_policies_end_date ON insurance_policies(end_date);\nCREATE INDEX idx_clients_agent ON insurance_clients(agent_id);\nCREATE INDEX idx_transactions_agent ON insurance_transactions(agent_id);\nCREATE INDEX idx_quote_sessions_hash ON insurance_quote_sessions(params_hash);\nCREATE INDEX idx_quote_sessions_expires ON insurance_quote_sessions(expires_at);\nCREATE INDEX idx_drafts_user ON insurance_drafts(user_id);\nCREATE INDEX idx_kbm_cache_hash ON insurance_kbm_cache(driver_hash);\nCREATE INDEX idx_vehicle_cache_key ON insurance_vehicle_cache(lookup_key);\nCREATE INDEX idx_referral_links_agent ON insurance_referral_links(agent_id);\nCREATE INDEX idx_referral_links_code ON insurance_referral_links(code);\n```\n\n### 10.3 RLS политики\n\n```sql\n-- Агент видит только своих клиентов\nALTER TABLE insurance_clients ENABLE ROW LEVEL SECURITY;\nCREATE POLICY \"agent_own_clients\" ON insurance_clients\n  FOR ALL USING (agent_id = auth.uid());\n\n-- Пользователь видит свои полисы, агент видит полисы своих клиентов\nALTER TABLE insurance_policies ENABLE ROW LEVEL SECURITY;\nCREATE POLICY \"user_own_policies\" ON insurance_policies\n  FOR SELECT USING (user_id = auth.uid() OR agent_id = auth.uid());\n\n-- Агент видит свои транзакции\nALTER TABLE insurance_transactions ENABLE ROW LEVEL SECURITY;\nCREATE POLICY \"agent_own_transactions\" ON insurance_transactions\n  FOR SELECT USING (agent_id = auth.uid());\n\n-- Черновики — только владелец\nALTER TABLE insurance_drafts ENABLE ROW LEVEL SECURITY;\nCREATE POLICY \"user_own_drafts\" ON insurance_drafts\n  FOR ALL USING (user_id = auth.uid());\n\n-- Quote sessions — только владелец\nALTER TABLE insurance_quote_sessions ENABLE ROW LEVEL SECURITY;\nCREATE POLICY \"user_own_quotes\" ON insurance_quote_sessions\n  FOR ALL USING (user_id = auth.uid());\n```\n\n---\n\n## Часть 11: Edge Functions\n\n### 11.1 insurance-quote (расчёт котировок)\n\n```typescript\n\u002F\u002F supabase\u002Ffunctions\u002Finsurance-quote\u002Findex.ts\n\u002F\u002F POST: { productCode, params }\n\u002F\u002F Response: { sessionId, results: ProviderQuote[], errors: ProviderError[] }\n\n\u002F\u002F Логика:\n\u002F\u002F 1. Validate params (Zod)\n\u002F\u002F 2. Check cache (params_hash)\n\u002F\u002F 3. Get adapters for productCode\n\u002F\u002F 4. Promise.allSettled(adapters.map(a => a.getQuote(params)))\n\u002F\u002F 5. Collect results + errors\n\u002F\u002F 6. Rank by price ASC\n\u002F\u002F 7. Cache in quote_sessions\n\u002F\u002F 8. Return\n```\n\n### 11.2 insurance-vehicle-lookup (распознавание ТС)\n\n```typescript\n\u002F\u002F GET: ?gosNumber=А123БВ777 или ?vin=XXXXXXXXXXXXXXXXX\n\u002F\u002F Response: { brand, model, year, power, vin, engineVolume }\n\u002F\u002F Cache: 365 days\n```\n\n### 11.3 insurance-kbm-check (проверка КБМ)\n\n```typescript\n\u002F\u002F POST: { lastName, firstName, middleName, birthDate, licSeries, licNumber }\n\u002F\u002F Response: { kbmClass, kbmValue, prevInsurer }\n\u002F\u002F Cache: 30 days\n```\n\n### 11.4 insurance-purchase (оформление полиса)\n\n```typescript\n\u002F\u002F POST: { quoteId, sessionId, paymentMethod }\n\u002F\u002F Response: { policyId, policyNumber, policyUrl, status }\n```\n\n---\n\n## Часть 12: Конкурентные преимущества\n\n### Что отличает нашу платформу от InsSmart\u002FSravni\u002FPolis.Online:\n\n| Преимущество | Описание |\n|---|---|\n| **Суперприложение** | Страхование = модуль экосистемы (чат + соцсеть + такси + маркетплейс) |\n| **Встроенный мессенджер** | Агент ведёт клиента в чате платформы |\n| **E2EE** | Паспорт, ВУ — шифрованная передача документов |\n| **Нативное приложение** | Capacitor Android\u002FiOS — push, offline, камера для документов |\n| **AI-ассистент** | Claude-powered рекомендации, навигация, ответы |\n| **Realtime** | Supabase Realtime — live-обновления статуса |\n| **Видеозвонки с агентом** | E2EE звонки через WebRTC |\n\n---\n\n## Часть 13: Антипаттерны\n\n| Антипаттерн | Как правильно |\n|---|---|\n| Mock-данные вместо реальных API | Sandbox от реальных СК, fallback на формулу ЦБ |\n| Все поля на одной странице | Multi-step wizard (7 шагов для ОСАГО) |\n| `Promise.all` для адаптеров | `Promise.allSettled` — одна СК упала → остальные ОК |\n| Нет черновиков | Автосохранение каждый step |\n| Нет КБМ-автопроверки | Edge Function с кешем 30 дней |\n| Захардкоженные коэффициенты | Справочники в БД, обновляемые при изменении ЦБ |\n| Один калькулятор на все продукты | Product-agnostic wizard engine + конфигурация per-product |\n| Нет комиссии для агента | Commission engine: per-product × per-company × loyalty_level |\n| Баланс без вывода | Полный финансовый модуль: начисления → подтверждение → вывод |\n\n---\n\n*Skill создан на основе живого тестирования 4 B2B-платформ (InsSmart, Pampadu, Sravni Labs, Polis.Online) и анализа 20+ GitHub-проектов.*\n","# Insurance Aggregator — Полная экспертиза\n\nЭтот skill содержит ВСЕ знания, необходимые для создания продакшн-уровня страхового агрегатора — B2B\u002FB2C платформы для расчёта, сравнения и оформления страховых полисов.\n\nОбучен на реальных данных 4 B2B-платформ (InsSmart, Sravni Labs, Polis.Online, Pampadu), потребительском Sravni.ru и 20+ open-source проектах.\n\n---\n\n## Часть 1: Архитектура платформы\n\n### 1.1 Три роли\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│                     INSURANCE PLATFORM                       │\n├─────────────┬──────────────────────┬────────────────────────┤\n│ Пользователь│      Агент           │    Админ               │\n│ (B2C)       │      (B2B)           │    (Internal)          │\n├─────────────┼──────────────────────┼────────────────────────┤\n│ Поиск полиса│ Калькулятор          │ Управление СК          │\n│ Сравнение   │ Результаты + комиссия│ Комиссионные правила   │\n│ Покупка     │ Оформление           │ Управление агентами    │\n│ Мои полисы  │ CRM клиентов         │ Отчёты (глобальные)    │\n│ Напоминания │ Баланс \u002F Финансы     │ Лояльность (настройки) │\n│             │ Отчёты               │ Модерация              │\n│             │ Реферальная программа│                        │\n│             │ Инструменты продаж   │                        │\n│             │ Лояльность (уровни)  │                        │\n└─────────────┴──────────────────────┴────────────────────────┘\n```\n\n### 1.2 Модули платформы\n\n| Модуль | Приоритет | Описание |\n|---|---|---|\n| **Калькуляторы** | P0 | Multi-step wizard для каждого продукта, автозаполнение |\n| **Quote Engine** | P0 | Параллельные запросы к адаптерам СК, кеширование, ранжирование |\n| **Результаты** | P0 | Список предложений: цена, СК, рейтинг, покрытие, комиссия агента |\n| **Оформление полиса** | P0 | Checkout: оплата, подтверждение, генерация полиса |\n| **Мои полисы** | P0 | Активные, истекающие, архив, статусы |\n| **CRM клиентов** | P0 | Карточка клиента: ФИО, полисы, расчёты, контакты |\n| **Баланс \u002F Финансы** | P0 | Начисления, списания, вывод средств |\n| **Черновики** | P1 | Автосохранение незавершённых расчётов |\n| **Отчёты** | P1 | Продажи, воронка, Excel export, группировка |\n| **Реферальная программа** | P1 | Генерация ссылок, метрики, типы |\n| **Лояльность** | P2 | 5 уровней, квартальный расчёт, бонусные комиссии |\n| **Планировщик** | P2 | Календарь: ДР, пролонгации, events |\n| **Инструменты продаж** | P2 | Виджеты, визитки, контент, обучение |\n| **Управление агентами** | P2 | Подагенты, иерархия, квоты |\n| **Справочники СК** | P2 | Рейтинги, отзывы, claim settlement ratio |\n\n### 1.3 Жизненный цикл полиса\n\n```\nЧерновик → Расчёт → Выбор → Оформление → Оплата → Активный → Пролонгация\n                                                        ↓\n                                                    Истекающий (за 30 дней)\n                                                        ↓\n                                                    Истёкший (архив)\n                                                        ↓\n                                              Claims (при страховом случае)\n```\n\n---\n\n## Часть 2: Продуктовый каталог\n\n### 2.1 Страховые продукты\n\n#### ОСАГО (обязательное, регулируется ЦБ РФ)\n- **Формула**: ТБ × КТ × КБМ × КВС × КО × КМ × КС × КП × КН\n- **Коэффициенты**:\n  - ТБ: 2746-4942₽ (коридор ЦБ для категории B)\n  - КТ: 0.6-2.1 (территориальный, по 88 регионам)\n  - КБМ: 0.46-3.92 (бонус-малус, 14 классов, проверка АИС РСА)\n  - КВС: 0.83-1.87 (возраст × стаж, матрица)\n  - КО: 1.0 (ограниченный список) \u002F 1.94 (без ограничений)\n  - КМ: 0.6-1.6 (мощность двигателя)\n  - КС: 0.5-1.0 (период использования)\n  - КП: 0.2-1.0 (период страхования)\n  - КН: 1.0-1.5 (нарушения)\n- **Автозаполнение**: по госномеру → марка, модель, год, мощность\n- **КБМ**: автоматическая проверка через АИС РСА (Edge Function)\n\n#### КАСКО (добровольное, устанавливается СК)\n- **Примерная стоимость**: 4-8% от стоимости авто\n- **Базовая формула**: стоимость_авто × базовая_ставка × К_возраст_авто × К_регион × К_франшиза × К_стаж × К_КБМ\n- **Доп.факторы**: кол-во ключей, срок владения, КАСКО-убытки за год, кредитный авто, автозапуск, праворульный\n- **Покрытие**: полное КАСКО, мини-КАСКО (ограниченные риски), КАСКО + GAP\n\n#### Ипотечное (обязательное для ипотеки)\n- **Типы покрытия**: Имущество (конструктив), Жизнь заёмщика, Титул\n- **Стоимость**: 0.15-0.5% от остатка кредита\n- **Факторы**: банк-кредитор, остаток, год постройки, тип объекта, пол, возраст, здоровье\n- **Особенность**: банк диктует минимальный набор покрытий\n\n#### ВЗР \u002F Travel\n- **Стоимость**: ~90-300₽\u002Fдень\n- **Факторы**: страна, дни, возраст, сумма покрытия\n- **Опции**: спорт, беременность, хронические заболевания\n- **Quick-picks стран**: Грузия, Таиланд, Шенген, Китай, Вьетнам, Турция\n\n#### НС (Несчастный случай)\n- **Типы**: На период \u002F На год\n- **Опции**: Для лагеря, Для спорта\n- **Простая форма**: возраст, даты, кол-во\n\n#### Антиклещ\n- **Стоимость**: 340-390₽\n- **Поля**: возраст, дата начала (на год)\n- **Референс**: Зетта 340₽, СберСтрах 360₽, ВСК 390₽, Ингосстрах 390₽\n\n#### ИФЛ (Имущество физлиц)\n- **Покрытие**: Отделка\u002Fремонт, Мебель\u002Fтехника, Ответственность перед соседями\n- **Фильтры**: газ, деревянные перекрытия, аренда\n- **Стоимость**: от 1,800₽\u002Fгод (квартира)\n\n#### Титул\n- **Период**: годовой\n- **Стоимость**: зависит от рыночной стоимости имущества (300K-50M₽)\n\n### 2.2 Дополнительные услуги\n\n| Услуга | Описание |\n|---|---|\n| Техосмотр | Запись на ТО: город, категория ТС, станция |\n| ДКП | Бесплатный шаблон договора купли-продажи |\n| Проверка ОСАГО | По VIN — актуальность полиса |\n| Подбор ипотеки | 20+ банков, сравнение условий |\n| Оценка имущества | Для страхования \u002F ипотеки |\n| Биржа ОСАГО | 100+ исполнителей, аукционная модель |\n\n---\n\n## Часть 3: Multi-Step Wizard — калькулятор\n\n### 3.1 Архитектура визарда\n\n```typescript\ninterface WizardStep {\n  id: string\n  title: string\n  fields: FieldConfig[]\n  validation: ZodSchema\n  autoFill?: AutoFillConfig  \u002F\u002F автозаполнение (госномер → данные ТС)\n  skipCondition?: (data: FormData) => boolean  \u002F\u002F пропустить шаг\n}\n\ninterface FieldConfig {\n  name: string\n  label: string\n  type: 'text' | 'select' | 'date' | 'number' | 'checkbox' | 'toggle' | 'phone' | 'masked'\n  mask?: string           \u002F\u002F '#### ######' для паспорта\n  required: boolean\n  defaultValue?: unknown\n  options?: SelectOption[] \u002F\u002F для select\n  autoComplete?: AutoCompleteConfig\n  dependsOn?: string      \u002F\u002F показать только если заполнено другое поле\n  copyFrom?: string       \u002F\u002F «Скопировать из собственника»\n}\n```\n\n### 3.2 ОСАГО — Golden Standard (7 шагов)\n\n**Шаг 1: Данные ТС**\n```\nfields:\n  - gosNumber: { type: 'masked', mask: 'A ### AA ###', autoComplete: vehicleLookup }\n  - noGosNumber: { type: 'checkbox', label: 'Госномер отсутствует' }\n  - withTrailer: { type: 'checkbox', label: 'ТС с прицепом' }\n  - category: { type: 'select', options: ['B', 'A', 'C', 'D', 'BE', ...], default: 'B' }\n  - purpose: { type: 'select', options: ['Личная', 'Такси', 'Учебная', 'Перевозка'], default: 'Личная' }\n  - brand: { type: 'select', autoFilled: true }\n  - model: { type: 'select', dependsOn: 'brand', autoFilled: true }\n  - year: { type: 'number', min: 1970, max: currentYear, autoFilled: true }\n  - power: { type: 'number', suffix: 'л.с.', autoFilled: true }\n  - powerKw: { type: 'number', suffix: 'кВт' }\n  - vin: { type: 'masked', mask: 'XXXXXXXXXXXXXXXXX' }\n  - docType: { type: 'select', options: ['ПТС', 'СТС', 'ЭПТС'] }\n  - docSeries: { type: 'masked', mask: '## ##' }\n  - docNumber: { type: 'masked', mask: '######' }\n  - docDate: { type: 'date' }\n```\n\n**Шаг 2: Собственник**\n```\nfields:\n  - ownerType: { type: 'select', options: ['ФЛ', 'ИП', 'ЮЛ'], default: 'ФЛ' }\n  - lastName: { type: 'text', required: true }\n  - firstName: { type: 'text', required: true }\n  - middleName: { type: 'text' }\n  - birthDate: { type: 'date', required: true }\n  - passportSeries: { type: 'masked', mask: '## ##' }\n  - passportNumber: { type: 'masked', mask: '######' }\n  - passportDate: { type: 'date' }\n  - address: { type: 'text', autoComplete: addressSuggest }\n```\n\n**Шаг 3: Страхователь**\n```\nfields:\n  - isOwner: { type: 'checkbox', label: 'Является собственником', default: true }\n  \u002F\u002F если isOwner=false → показать те же поля что у собственника\n  - lastName, firstName, middleName, birthDate, passport*, address (skipIf: isOwner)\n```\n\n**Шаг 4: Водители**\n```\nfields:\n  - multiDrive: { type: 'toggle', label: 'Без ограничений (мультидрайв)' }\n  \u002F\u002F если multiDrive=false → показать список водителей\n  - drivers[]: {\n      lastName, firstName, middleName: { type: 'text' }\n      birthDate: { type: 'date' }\n      licSeries: { type: 'masked', mask: '## ##' }\n      licNumber: { type: 'masked', mask: '######' }\n      licDate: { type: 'date' }  \u002F\u002F дата выдачи ВУ\n      expStart: { type: 'date' } \u002F\u002F дата начала стажа\n      foreignLic: { type: 'checkbox', label: 'Иностранное ВУ' }\n      prevLic: { type: 'checkbox', label: 'Указать предыдущее ВУ (для переноса КБМ)' }\n      prevLicSeries, prevLicNumber: { dependsOn: 'prevLic' }\n      copyFromOwner: { type: 'button', label: 'Скопировать из собственника' }\n      copyFromInsurer: { type: 'button', label: 'Скопировать из страхователя' }\n    }\n  - addDriver: { type: 'button', label: '+ Ещё один водитель' }\n```\n\n**Шаг 5: Данные полиса**\n```\nfields:\n  - startDate: { type: 'date', min: tomorrow }\n  - period: { type: 'select', options: ['3 мес', '6 мес', '12 мес'], default: '12 мес' }\n  - greenCorridor: { type: 'checkbox', label: 'Предыдущий полис (зелёный коридор)' }\n  - prevPolicyNumber: { dependsOn: 'greenCorridor', type: 'masked' }\n```\n\n**Шаг 6: Контакты**\n```\nfields:\n  - phone: { type: 'phone', mask: '+7 (###) ###-##-##' }\n  - email: { type: 'text', validation: email }\n```\n\n**Шаг 7: Подтверждение**\n```\nfields:\n  - consentPD: { type: 'checkbox', required: true, label: 'Согласие на обработку ПД (152-ФЗ)' }\n  - consentSK: { type: 'checkbox', required: true, label: 'Согласие на передачу данных СК' }\n  - consentAccuracy: { type: 'checkbox', required: true, label: 'Подтверждаю достоверность' }\n  - consentRules: { type: 'checkbox', required: true, label: 'Ознакомлен с правилами' }\nactions:\n  - saveDraft: { label: 'Сохранить черновик', variant: 'outline' }\n  - calculate: { label: 'Рассчитать', variant: 'primary' }\n```\n\n### 3.3 Автозаполнение по госномеру\n\n```\nПользователь вводит госномер (напр. А123БВ777)\n  → Edge Function insurance-vehicle-lookup\n    → API запрос к сервису (ГИБДД \u002F RSA \u002F коммерческий API)\n    → Возврат: { brand, model, year, power, vin, engineVolume }\n  → Форма автозаполняется\n  → Пользователь проверяет и корректирует\n```\n\n### 3.4 Проверка КБМ\n\n```\nДля каждого водителя:\n  → Edge Function insurance-kbm-check\n    → Запрос к АИС РСА (по ФИО + ДР + ВУ)\n    → Возврат: { kbmClass: number, kbmValue: number, prevInsurer: string }\n  → КБМ автоподставляется в расчёт\n  → Кеширование: 30 дней (КБМ меняется 1 раз\u002Fгод 1 апреля)\n```\n\n---\n\n## Часть 4: Quote Engine\n\n### 4.1 Архитектура\n\n```\n┌─────────────┐\n│  Calculator  │  ← пользователь заполнил форму\n│  (Frontend)  │\n└──────┬──────┘\n       │ POST \u002Fapi\u002Finsurance-quote\n       ▼\n┌──────────────┐\n│ Quote Engine │  ← Edge Function\n│              │\n│ 1. Validate  │  ← Zod schema validation\n│ 2. Cache?    │  ← Есть ли кешированный результат?\n│ 3. Fan-out   │  ← Promise.allSettled([...adapters])\n│ 4. Collect   │  ← Собрать ответы\n│ 5. Rank      │  ← Отсортировать\n│ 6. Cache     │  ← Сохранить в quote_sessions\n│ 7. Return    │  ← Отдать клиенту\n└──────────────┘\n       │\n       ├────────────┬───────────────┬──────────────┐\n       ▼            ▼               ▼              ▼\n┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐\n│ Adapter: │ │ Adapter: │ │ Adapter: │ │ Adapter: │\n│ Ингос    │ │ Альфа    │ │ СОГАЗ    │ │ Ренессанс│\n└──────────┘ └──────────┘ └──────────┘ └──────────┘\n```\n\n### 4.2 Adapter interface\n\n```typescript\ninterface InsuranceProviderAdapter {\n  code: string           \u002F\u002F 'ingos', 'alpha', 'sogaz'\n  name: string           \u002F\u002F 'Ингосстрах'\n  logo: string           \u002F\u002F URL логотипа\n  supportedProducts: ProductCode[]\n  timeout: number        \u002F\u002F ms, per-provider\n\n  getQuote(req: QuoteRequest): Promise\u003CProviderQuote[]>\n  purchase(req: PurchaseRequest): Promise\u003CPurchaseResult>\n  getStatus(policyId: string): Promise\u003CPolicyStatus>\n  cancel(policyId: string): Promise\u003CCancelResult>\n}\n\ninterface ProviderQuote {\n  providerId: string\n  providerName: string\n  providerLogo: string\n  providerRating: number  \u002F\u002F 1-5\n  productCode: ProductCode\n  premium: number         \u002F\u002F стоимость полиса ₽\n  commission: number      \u002F\u002F комиссия агента ₽\n  commissionPercent: number\n  coverage: CoverageDetails\n  franchise?: number      \u002F\u002F франшиза ₽\n  paymentOptions: PaymentOption[]\n  purchaseUrl?: string\n  validUntil: string      \u002F\u002F ISO date, когда котировка истекает\n}\n```\n\n### 4.3 Quote Session\n\n```typescript\ninterface QuoteSession {\n  id: string             \u002F\u002F uuid\n  userId: string\n  productCode: ProductCode\n  params: QuoteRequest   \u002F\u002F входные параметры\n  paramsHash: string     \u002F\u002F SHA-256 для дедупликации\n  status: 'pending' | 'partial' | 'complete' | 'expired'\n  results: ProviderQuote[]\n  errors: ProviderError[]  \u002F\u002F какие адаптеры упали\n  createdAt: string\n  expiresAt: string      \u002F\u002F TTL 15 минут\n}\n```\n\n### 4.4 Кеширование\n\n```\nLayer 1: React Query (staleTime: 5 min) — фронтенд\nLayer 2: Quote Session (TTL: 15 min) — те же параметры → тот же результат\nLayer 3: КБМ кеш (TTL: 30 days) — обновляется 1 раз\u002Fгод 1 апреля\nLayer 4: Vehicle кеш (TTL: 365 days) — данные ТС меняются редко\nLayer 5: Provider rate кеш (TTL: 24h) — тарифы СК для аналитики\n```\n\n---\n\n## Часть 5: Результаты расчёта\n\n### 5.1 Карточка предложения\n\n```\n┌─────────────────────────────────────────────────┐\n│ [Лого СК]  Ингосстрах           ★ 4.7 (1,234)  │\n│                                                  │\n│ ОСАГО                           12 450 ₽        │\n│ Покрытие: стандартное                            │\n│ Рейтинг надёжности: A++         Комиссия: 8%    │\n│                                                  │\n│ [Подробнее]  [Сравнить]  [== Оформить ==]       │\n└─────────────────────────────────────────────────┘\n```\n\n### 5.2 Сортировка и фильтры\n\n**Сортировка:**\n- По цене (↑↓) — default\n- По рейтингу СК (↑↓)\n- По сумме покрытия (↑↓)\n- По комиссии агента (↑↓) — только для агентов\n\n**Фильтры:**\n- Страховая компания (мультивыбор)\n- Франшиза (0 \u002F 10K \u002F 20K \u002F 50K)\n- Минимальное покрытие\n- Рейтинг СК (от 3.0 \u002F от 4.0 \u002F от 4.5)\n\n### 5.3 Сравнение (Comparison Mode)\n\nПользователь выбирает 2-4 предложения → side-by-side таблица:\n\n| Параметр | Ингосстрах | АльфаСтрахование | СОГАЗ |\n|---|---|---|---|\n| Цена | 12,450₽ | 11,890₽ | 13,200₽ |\n| Рейтинг | 4.7 | 4.5 | 4.3 |\n| Покрытие | Стандарт | Стандарт | Расширенное |\n| Франшиза | 0₽ | 0₽ | 15,000₽ |\n| Комиссия | 8% | 7% | 9% |\n| CSR | 96% | 93% | 91% |\n\n---\n\n## Часть 6: CRM клиентов\n\n### 6.1 Карточка клиента (референс: InsSmart)\n\n```\n┌─ Клиент ────────────────────────────────────┐\n│ Иванов Иван Иванович                        │\n│ ДР: 15.03.1985 (39 лет)                     │\n│ Тел: +7 (999) 123-45-67                     │\n│ Email: ivanov@example.com                    │\n│                                              │\n│ Авто: BMW X5, 2020, 249 л.с.                │\n│ Госномер: А123БВ777                          │\n│                                              │\n│ ┌─ Полисы ─────────────────────────────────┐ │\n│ │ ОСАГО  #XXX  до 15.09.2026  ✅ активен  │ │\n│ │ КАСКО  #YYY  до 15.09.2026  ✅ активен  │ │\n│ │ ОСАГО  #ZZZ  до 15.09.2025  ⛔ истёк    │ │\n│ └──────────────────────────────────────────┘ │\n│                                              │\n│ ┌─ Расчёты ────────────────────────────────┐ │\n│ │ ОСАГО  12 предложений  15.08.2026       │ │\n│ │ КАСКО  8 предложений   14.08.2026       │ │\n│ └──────────────────────────────────────────┘ │\n│                                              │\n│ [Новый расчёт] [Пролонгация] [Редактировать]│\n└──────────────────────────────────────────────┘\n```\n\n### 6.2 Пролонгации\n\nInsSmart и Sravni Labs автоматически отслеживают полисы и показывают:\n- Полисы, истекающие через 30 дней → badge «Пролонгация»\n- Автоматическое уведомление агенту и клиенту\n- One-click переход к расчёту нового полиса (данные предзаполнены)\n\n### 6.3 Excel Export\n\nPolis.Online и InsSmart поддерживают:\n- Экспорт CRM в Excel\n- Настройка колонок (какие поля включить)\n- Фильтры (по датам, продуктам, статусам)\n- Группировка (по дням, неделям, месяцам)\n\n---\n\n## Часть 7: Финансы и баланс\n\n### 7.1 Модель начислений\n\n```\nОформлен полис → Комиссия начислена на баланс агента\n  → Status: 'pending' (ожидает подтверждения СК)\n  → Status: 'confirmed' (СК подтвердила оплату)\n  → Status: 'available' (можно вывести)\n  → Status: 'withdrawn' (выведено)\n```\n\n### 7.2 Вывод средств\n\n**InsSmart**: минимум 1,000₽, на карту \u002F расчётный счёт\n**Polis.Online**: быстрые выплаты на карту (для самозанятых)\n\n### 7.3 Отчётность\n\n**По периоду**: Текущий месяц, Прошлый, Квартал, Год, Все время, Custom dates\n**Метрики**:\n- Оформлено полисов (шт.)\n- Премии (₽)\n- Комиссия (₽)\n- Средний чек\n- Конверсия (расчёты → оформления)\n\n---\n\n## Часть 8: Лояльность\n\n### 8.1 5-уровневая система (InsSmart)\n\n```typescript\nconst LOYALTY_LEVELS = [\n  { name: 'Новичок',         threshold: 0,       bonus: 0 },\n  { name: 'Агент',           threshold: 30_000,  bonus: 5 },\n  { name: 'Агент 2.0',       threshold: 75_000,  bonus: 8 },\n  { name: 'Уполномоченный',  threshold: 150_000, bonus: 12 },\n  { name: 'Уполномоченный+', threshold: 300_000, bonus: 15 },\n] as const\n\n\u002F\u002F Расчёт: квартальные премии → определяют уровень\n\u002F\u002F bonus — процент надбавки к базовой комиссии\n```\n\n### 8.2 Механика\n\n- Период оценки: **квартал** (3 месяца)\n- Метрика: сумма **премий** оформленных полисов за квартал\n- Повышение уровня: автоматическое при достижении порога\n- Понижение уровня: если за квартал не дотянул до текущего порога → понижение на 1\n\n---\n\n## Часть 9: Реферальная программа\n\n### 9.1 Модель InsSmart (2-уровневая)\n\n```\nАгент A приглашает Агент B → A получает X% от продаж B\nАгент B приглашает Агент C → A получает Y% от продаж C (2-й уровень)\n```\n\n### 9.2 Модель Polis.Online (типизированные ссылки)\n\n```typescript\ntype ReferralType = \n  | 'mentorship'      \u002F\u002F Кураторство\n  | 'partnership'      \u002F\u002F Партнёрская программа  \n  | 'osago'           \u002F\u002F Оформление ОСАГО\n  | 'mortgage'        \u002F\u002F Оформление ипотечного полиса\n\ninterface ReferralLink {\n  id: string\n  url: string\n  type: ReferralType\n  name: string\n  quotaPercent: number  \u002F\u002F размер квоты %\n  activations: number\n  calculations: number\n  policies: number      \u002F\u002F оформлено\n  createdAt: string\n}\n```\n\n---\n\n## Часть 10: Схема базы данных\n\n### 10.1 Основные таблицы\n\n```sql\n-- Страховые продукты (справочник)\nCREATE TABLE insurance_products (\n  code TEXT PRIMARY KEY,           -- 'osago', 'kasko', 'mortgage', 'vzr'\n  name TEXT NOT NULL,\n  description TEXT,\n  icon TEXT,\n  sort_order INTEGER DEFAULT 0,\n  is_active BOOLEAN DEFAULT true,\n  created_at TIMESTAMPTZ DEFAULT now()\n);\n\n-- Страховые компании (справочник)\nCREATE TABLE insurance_companies (\n  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n  code TEXT UNIQUE NOT NULL,       -- 'ingos', 'alpha', 'sogaz'\n  name TEXT NOT NULL,\n  logo_url TEXT,\n  rating NUMERIC(2,1),             -- 1.0-5.0\n  csr NUMERIC(4,1),                -- claim settlement ratio %\n  is_active BOOLEAN DEFAULT true,\n  supported_products TEXT[],       -- {'osago','kasko','mortgage'}\n  adapter_config JSONB,           -- конфиг адаптера (timeout, base_url, etc.)\n  created_at TIMESTAMPTZ DEFAULT now()\n);\n\n-- Агенты\nCREATE TABLE insurance_agents (\n  id UUID PRIMARY KEY REFERENCES auth.users(id) ON DELETE CASCADE,\n  loyalty_level TEXT DEFAULT 'novice', -- 'novice'|'agent'|'agent2'|'authorized'|'authorized_plus'\n  quarterly_premiums NUMERIC DEFAULT 0,\n  balance NUMERIC DEFAULT 0,\n  referrer_id UUID REFERENCES insurance_agents(id),\n  referral_code TEXT UNIQUE,\n  is_self_employed BOOLEAN DEFAULT false,\n  inn TEXT,\n  created_at TIMESTAMPTZ DEFAULT now()\n);\n\n-- Клиенты агента (CRM)\nCREATE TABLE insurance_clients (\n  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n  agent_id UUID NOT NULL REFERENCES insurance_agents(id),\n  first_name TEXT NOT NULL,\n  last_name TEXT NOT NULL,\n  middle_name TEXT,\n  birth_date DATE,\n  phone TEXT,\n  email TEXT,\n  passport_series TEXT,\n  passport_number TEXT,\n  address TEXT,\n  notes TEXT,\n  created_at TIMESTAMPTZ DEFAULT now(),\n  updated_at TIMESTAMPTZ DEFAULT now()\n);\n\n-- ТС клиента\nCREATE TABLE insurance_vehicles (\n  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n  client_id UUID REFERENCES insurance_clients(id),\n  gos_number TEXT,\n  brand TEXT,\n  model TEXT,\n  year INTEGER,\n  power INTEGER,           -- л.с.\n  vin TEXT,\n  doc_type TEXT,           -- 'pts', 'sts', 'epts'\n  doc_series TEXT,\n  doc_number TEXT,\n  doc_date DATE,\n  created_at TIMESTAMPTZ DEFAULT now()\n);\n\n-- Черновики расчётов\nCREATE TABLE insurance_drafts (\n  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n  user_id UUID NOT NULL REFERENCES auth.users(id),\n  product_code TEXT NOT NULL REFERENCES insurance_products(code),\n  step INTEGER DEFAULT 1,\n  form_data JSONB NOT NULL DEFAULT '{}',\n  created_at TIMESTAMPTZ DEFAULT now(),\n  updated_at TIMESTAMPTZ DEFAULT now()\n);\n\n-- Сессии расчёта (quote sessions)\nCREATE TABLE insurance_quote_sessions (\n  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n  user_id UUID NOT NULL REFERENCES auth.users(id),\n  product_code TEXT NOT NULL,\n  params JSONB NOT NULL,\n  params_hash TEXT NOT NULL,       -- SHA-256 для дедупликации\n  status TEXT DEFAULT 'pending',   -- 'pending'|'partial'|'complete'|'expired'\n  results JSONB DEFAULT '[]',\n  errors JSONB DEFAULT '[]',\n  created_at TIMESTAMPTZ DEFAULT now(),\n  expires_at TIMESTAMPTZ DEFAULT (now() + interval '15 minutes')\n);\n\n-- Полисы\nCREATE TABLE insurance_policies (\n  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n  user_id UUID NOT NULL REFERENCES auth.users(id),\n  agent_id UUID REFERENCES insurance_agents(id),\n  client_id UUID REFERENCES insurance_clients(id),\n  product_code TEXT NOT NULL,\n  company_id UUID REFERENCES insurance_companies(id),\n  policy_number TEXT,\n  status TEXT DEFAULT 'active',    -- 'active'|'expiring'|'expired'|'cancelled'\n  premium NUMERIC NOT NULL,\n  commission NUMERIC DEFAULT 0,\n  start_date DATE NOT NULL,\n  end_date DATE NOT NULL,\n  coverage JSONB,\n  raw_data JSONB,                 -- данные формы для пролонгации\n  created_at TIMESTAMPTZ DEFAULT now()\n);\n\n-- Транзакции баланса агента\nCREATE TABLE insurance_transactions (\n  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n  agent_id UUID NOT NULL REFERENCES insurance_agents(id),\n  policy_id UUID REFERENCES insurance_policies(id),\n  type TEXT NOT NULL,              -- 'commission'|'bonus'|'withdrawal'|'referral'\n  amount NUMERIC NOT NULL,\n  status TEXT DEFAULT 'pending',   -- 'pending'|'confirmed'|'available'|'withdrawn'\n  description TEXT,\n  created_at TIMESTAMPTZ DEFAULT now()\n);\n\n-- Реферальные ссылки\nCREATE TABLE insurance_referral_links (\n  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n  agent_id UUID NOT NULL REFERENCES insurance_agents(id),\n  type TEXT NOT NULL,              -- 'mentorship'|'partnership'|'osago'|'mortgage'\n  name TEXT,\n  code TEXT UNIQUE NOT NULL,\n  quota_percent NUMERIC DEFAULT 0,\n  activations INTEGER DEFAULT 0,\n  calculations INTEGER DEFAULT 0,\n  policies INTEGER DEFAULT 0,\n  created_at TIMESTAMPTZ DEFAULT now()\n);\n\n-- КБМ кеш\nCREATE TABLE insurance_kbm_cache (\n  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n  driver_hash TEXT UNIQUE NOT NULL,  -- SHA-256(ФИО+ДР+ВУ)\n  kbm_class INTEGER NOT NULL,\n  kbm_value NUMERIC NOT NULL,\n  prev_insurer TEXT,\n  checked_at TIMESTAMPTZ DEFAULT now(),\n  expires_at TIMESTAMPTZ DEFAULT (now() + interval '30 days')\n);\n\n-- Vehicle кеш\nCREATE TABLE insurance_vehicle_cache (\n  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n  lookup_key TEXT UNIQUE NOT NULL,  -- госномер или VIN\n  brand TEXT,\n  model TEXT,\n  year INTEGER,\n  power INTEGER,\n  vin TEXT,\n  engine_volume INTEGER,\n  checked_at TIMESTAMPTZ DEFAULT now(),\n  expires_at TIMESTAMPTZ DEFAULT (now() + interval '365 days')\n);\n```\n\n### 10.2 Индексы\n\n```sql\nCREATE INDEX idx_policies_user ON insurance_policies(user_id);\nCREATE INDEX idx_policies_agent ON insurance_policies(agent_id);\nCREATE INDEX idx_policies_status ON insurance_policies(status);\nCREATE INDEX idx_policies_end_date ON insurance_policies(end_date);\nCREATE INDEX idx_clients_agent ON insurance_clients(agent_id);\nCREATE INDEX idx_transactions_agent ON insurance_transactions(agent_id);\nCREATE INDEX idx_quote_sessions_hash ON insurance_quote_sessions(params_hash);\nCREATE INDEX idx_quote_sessions_expires ON insurance_quote_sessions(expires_at);\nCREATE INDEX idx_drafts_user ON insurance_drafts(user_id);\nCREATE INDEX idx_kbm_cache_hash ON insurance_kbm_cache(driver_hash);\nCREATE INDEX idx_vehicle_cache_key ON insurance_vehicle_cache(lookup_key);\nCREATE INDEX idx_referral_links_agent ON insurance_referral_links(agent_id);\nCREATE INDEX idx_referral_links_code ON insurance_referral_links(code);\n```\n\n### 10.3 RLS политики\n\n```sql\n-- Агент видит только своих клиентов\nALTER TABLE insurance_clients ENABLE ROW LEVEL SECURITY;\nCREATE POLICY \"agent_own_clients\" ON insurance_clients\n  FOR ALL USING (agent_id = auth.uid());\n\n-- Пользователь видит свои полисы, агент видит полисы своих клиентов\nALTER TABLE insurance_policies ENABLE ROW LEVEL SECURITY;\nCREATE POLICY \"user_own_policies\" ON insurance_policies\n  FOR SELECT USING (user_id = auth.uid() OR agent_id = auth.uid());\n\n-- Агент видит свои транзакции\nALTER TABLE insurance_transactions ENABLE ROW LEVEL SECURITY;\nCREATE POLICY \"agent_own_transactions\" ON insurance_transactions\n  FOR SELECT USING (agent_id = auth.uid());\n\n-- Черновики — только владелец\nALTER TABLE insurance_drafts ENABLE ROW LEVEL SECURITY;\nCREATE POLICY \"user_own_drafts\" ON insurance_drafts\n  FOR ALL USING (user_id = auth.uid());\n\n-- Quote sessions — только владелец\nALTER TABLE insurance_quote_sessions ENABLE ROW LEVEL SECURITY;\nCREATE POLICY \"user_own_quotes\" ON insurance_quote_sessions\n  FOR ALL USING (user_id = auth.uid());\n```\n\n---\n\n## Часть 11: Edge Functions\n\n### 11.1 insurance-quote (расчёт котировок)\n\n```typescript\n\u002F\u002F supabase\u002Ffunctions\u002Finsurance-quote\u002Findex.ts\n\u002F\u002F POST: { productCode, params }\n\u002F\u002F Response: { sessionId, results: ProviderQuote[], errors: ProviderError[] }\n\n\u002F\u002F Логика:\n\u002F\u002F 1. Validate params (Zod)\n\u002F\u002F 2. Check cache (params_hash)\n\u002F\u002F 3. Get adapters for productCode\n\u002F\u002F 4. Promise.allSettled(adapters.map(a => a.getQuote(params)))\n\u002F\u002F 5. Collect results + errors\n\u002F\u002F 6. Rank by price ASC\n\u002F\u002F 7. Cache in quote_sessions\n\u002F\u002F 8. Return\n```\n\n### 11.2 insurance-vehicle-lookup (распознавание ТС)\n\n```typescript\n\u002F\u002F GET: ?gosNumber=А123БВ777 или ?vin=XXXXXXXXXXXXXXXXX\n\u002F\u002F Response: { brand, model, year, power, vin, engineVolume }\n\u002F\u002F Cache: 365 days\n```\n\n### 11.3 insurance-kbm-check (проверка КБМ)\n\n```typescript\n\u002F\u002F POST: { lastName, firstName, middleName, birthDate, licSeries, licNumber }\n\u002F\u002F Response: { kbmClass, kbmValue, prevInsurer }\n\u002F\u002F Cache: 30 days\n```\n\n### 11.4 insurance-purchase (оформление полиса)\n\n```typescript\n\u002F\u002F POST: { quoteId, sessionId, paymentMethod }\n\u002F\u002F Response: { policyId, policyNumber, policyUrl, status }\n```\n\n---\n\n## Часть 12: Конкурентные преимущества\n\n### Что отличает нашу платформу от InsSmart\u002FSravni\u002FPolis.Online:\n\n| Преимущество | Описание |\n|---|---|\n| **Суперприложение** | Страхование = модуль экосистемы (чат + соцсеть + такси + маркетплейс) |\n| **Встроенный мессенджер** | Агент ведёт клиента в чате платформы |\n| **E2EE** | Паспорт, ВУ — шифрованная передача документов |\n| **Нативное приложение** | Capacitor Android\u002FiOS — push, offline, камера для документов |\n| **AI-ассистент** | Claude-powered рекомендации, навигация, ответы |\n| **Realtime** | Supabase Realtime — live-обновления статуса |\n| **Видеозвонки с агентом** | E2EE звонки через WebRTC |\n\n---\n\n## Часть 13: Антипаттерны\n\n| Антипаттерн | Как правильно |\n|---|---|\n| Mock-данные вместо реальных API | Sandbox от реальных СК, fallback на формулу ЦБ |\n| Все поля на одной странице | Multi-step wizard (7 шагов для ОСАГО) |\n| `Promise.all` для адаптеров | `Promise.allSettled` — одна СК упала → остальные ОК |\n| Нет черновиков | Автосохранение каждый step |\n| Нет КБМ-автопроверки | Edge Function с кешем 30 дней |\n| Захардкоженные коэффициенты | Справочники в БД, обновляемые при изменении ЦБ |\n| Один калькулятор на все продукты | Product-agnostic wizard engine + конфигурация per-product |\n| Нет комиссии для агента | Commission engine: per-product × per-company × loyalty_level |\n| Баланс без вывода | Полный финансовый модуль: начисления → подтверждение → вывод |\n\n---\n\n*Skill создан на основе живого тестирования 4 B2B-платформ (InsSmart, Pampadu, Sravni Labs, Polis.Online) и анализа 20+ GitHub-проектов.*\n",{"name":5,"description":7},"main","b22eca2e974f918ce591c5b2bd829fb7510e0191","Skills\u002Finsurance-aggregator",18,"https:\u002F\u002Fgithub.com\u002FFDU-INS\u002FInsurance-Skills","https:\u002F\u002Fgithub.com\u002FFDU-INS","Fudan University Department of Risk Management and Insurance","2026-07-12 12:54:34",{"source":8,"skillName":5,"commands":39,"prompt":49,"zipAvailable":50},[40,43,46],{"tool":41,"command":42},"npx","npx skills add FDU-INS\u002FInsurance-Skills --skill insurance-aggregator",{"tool":44,"command":45},"bunx","bunx skills add FDU-INS\u002FInsurance-Skills --skill insurance-aggregator",{"tool":47,"command":48},"pnpm","pnpm dlx skills add FDU-INS\u002FInsurance-Skills --skill insurance-aggregator","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FFDU-INS\u002FInsurance-Skills\u002Fblob\u002Fmain\u002FSkills\u002Finsurance-aggregator\u002FSKILL.md",true,[],[53,82,106,137,159,192],{"skillNo":54,"name":55,"nameZh":6,"description":56,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":57,"categories":58,"keywords":64,"publishedAt":25},"01M713QW6EGEG0YAD75440GSD0","로인장 (Roinjiang)","Activates when the user needs legal advice, contract review, insurance law consultation, startup legal support, or any legal\u002Fregulatory matter. She is a top-tier in-house lawyer with absolute loyalty to the CEO, specializing in insurance law, financial consumer protection, privacy, contracts, labor law, family law, civil and criminal matters.","https:\u002F\u002Fgithub.com\u002FFDU-INS\u002FInsurance-Skills\u002Fblob\u002Fmain\u002FSkills\u002F로인장 (Roinjiang)\u002FSKILL.md",[59],{"categoryNo":60,"categoryName":61,"taxonomyType":62,"taxonomyTypeDesc":63},"01JBSEEDCAT000000000000037","律师与法务","PROFESSION","适用职业",[55,65,20,66,67,68,24,69,70,71,72,73,74,75,76,77,78,79,80,81],"insurance law","civil","contract","family","review","loyalty","with","top","contract review","ceo","support","advice","consultation","regulatory","privacy","protection","startup",{"skillNo":83,"name":84,"nameZh":6,"description":85,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":86,"categories":87,"keywords":88,"publishedAt":25},"01M713QRN8VFMA9VKS6R4DJ2WS","zocdoc-doctor-finder","Use when a user needs to find a doctor, dentist, specialist, therapist, or healthcare provider — especially when they mention insurance, in-network, availability, location, appointments, or booking. Also use for browsing provider reviews, comparing doctors by specialty, or checking if a provider takes their insurance.","https:\u002F\u002Fgithub.com\u002FFDU-INS\u002FInsurance-Skills\u002Fblob\u002Fmain\u002FSkills\u002Fzocdoc-doctor-finder\u002FSKILL.md",[],[89,90,91,92,20,93,94,24,95,96,97,98,99,100,101,102,103,104,22,105],"zocdoc doctor finder","doctor","healthcare","reviews","browser automation","access","browsing","browser","booking","network","therapist","computer","availability","for","provider","tool","automation",{"skillNo":107,"name":108,"nameZh":6,"description":109,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":110,"categories":111,"keywords":117,"publishedAt":25},"01M713QKGV3FTX7EEYWKDM8ENZ","zenmux-context","Answers any question about ZenMux by reading the latest official documentation. Use this skill whenever the user asks about ZenMux product features, API usage, configuration, integration, pricing, models, providers, routing, fallback, streaming, multimodal, structured output, tool calling, reasoning, prompt caching, image generation, video generation, web search, long context, observability, logs, cost tracking, usage analytics, insurance, subscription, pay-as-you-go, invoices, best practices for tools like Claude Code, Cursor, Cline, CodeX, Gemini CLI, opencode, Cherry Studio, Obsidian, Sider, Open-WebUI, Dify, Neovate, GitHub Copilot, OpenClaw, CC-Switch, Immersive Translate, Studio Chat, architecture, benchmarks, FAQ, contact, privacy, terms of service, compliance, or any other ZenMux-related topic. Also trigger when the user writes in Chinese about ZenMux: 文档, 使用指南, 快速开始, API 参考, 最佳实践, 模型路由, 供应商路由, 订阅, 按量计费, 可观测性, 帮助, 常见问题, 接入指南, 配置. Trigger on phrases like \"how to use ZenMux\", \"ZenMux docs\", \"ZenMux API\", \"ZenMux integration\", \"ZenMux 怎么用\", \"ZenMux 接入\", \"ZenMux 配置\". Even if the user doesn't say \"ZenMux\" explicitly but asks about LLM API aggregation, model routing, provider fallback in a context where ZenMux is the project being worked on, this skill should activate.","https:\u002F\u002Fgithub.com\u002FFDU-INS\u002FInsurance-Skills\u002Fblob\u002Fmain\u002FSkills\u002Fzenmux-context\u002FSKILL.md",[112],{"categoryNo":113,"categoryName":114,"taxonomyType":115,"taxonomyTypeDesc":116},"01JBSEEDCAT000000000000016","图像与多媒体","SCENARIO","使用场景",[118,119,120,121,20,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136],"context","zenmux context","Video","chinese","project","web search","translate","search","open","question","pay","image","you","activate","architecture","logs","streaming","cherry studio","how",{"skillNo":138,"name":139,"nameZh":6,"description":140,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":141,"categories":142,"keywords":143,"publishedAt":25},"01M713QHWTBG634BCBV7NBJME1","workers-comp-guide","Guide workers compensation compliance and claims management.\nTRIGGERS - Use when user needs help with workers-comp-guide related tasks.","https:\u002F\u002Fgithub.com\u002FFDU-INS\u002FInsurance-Skills\u002Fblob\u002Fmain\u002FSkills\u002Fworkers-comp-guide\u002FSKILL.md",[],[144,145,146,147,148,20,149,150,22,24,151,71,152,153,154,155,156,157,158],"workers","comp","workers comp","workers comp guide","guide","triggers","workers-comp","tasks","claims management","claims","compliance","help","compensation","management","user",{"skillNo":160,"name":161,"nameZh":6,"description":162,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":163,"categories":164,"keywords":174,"publishedAt":25},"01M713QF45VMV1685AFNF1GPMA","weekly-kpi-report","Generate McKinsey-style board presentation PPTs from weekly auto insurance data. Automatically calculates 16+ KPIs, creates executive-level slides with actionable insights, and supports week-over-week comparisons. Use when user uploads insurance cost data (Excel\u002FCSV) and requests board report, weekly presentation, executive briefing, or mentions keywords like 董事会汇报, 周报PPT, 经营分析演示, McKinsey-style reports.","https:\u002F\u002Fgithub.com\u002FFDU-INS\u002FInsurance-Skills\u002Fblob\u002Fmain\u002FSkills\u002Fweekly-kpi-report\u002FSKILL.md",[165,168,171],{"categoryNo":166,"categoryName":167,"taxonomyType":115,"taxonomyTypeDesc":116},"01JBSEEDCAT000000000000003","演示文稿",{"categoryNo":169,"categoryName":170,"taxonomyType":115,"taxonomyTypeDesc":116},"01JBSEEDCAT000000000000004","电子表格",{"categoryNo":172,"categoryName":173,"taxonomyType":62,"taxonomyTypeDesc":63},"01JBSEEDCAT000000000000034","行政与办公人员",[175,176,177,178,179,20,180,181,182,183,24,184,185,186,187,188,189,190,22,191],"weekly","weekly kpi report","kpi","report","xlsx","actionable","insights","briefing","auto","board report","reports","generate","演示","data","presentation","slides","uploads",{"skillNo":193,"name":194,"nameZh":6,"description":195,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":196,"categories":197,"keywords":201,"publishedAt":25},"01M713QA9WJDHMNVTTY1ENRKVB","wealth-advisory","Wealth management and financial planning for HNW and UHNW clients. Activate when the user\nmentions wealth management, financial planning, retirement, estate planning, tax planning,\nGRAT, IDGT, trust, asset allocation, withdrawal rate, Monte Carlo simulation, goals-based\ninvesting, tax-loss harvesting, Roth conversion, insurance, annuity, mortgage strategy,\nconcentrated stock, family office, direct indexing, 529 plan, charitable giving, donor-advised\nfund, private foundation, or asks about personal finance strategy, inheritance, long-term\nfinancial planning, or UHNW advisory.","https:\u002F\u002Fgithub.com\u002FFDU-INS\u002FInsurance-Skills\u002Fblob\u002Fmain\u002FSkills\u002Fwealth-advisory\u002FSKILL.md",[198],{"categoryNo":199,"categoryName":200,"taxonomyType":62,"taxonomyTypeDesc":63},"01JBSEEDCAT000000000000040","财务",[202,203,20,204,205,24,131,206,207,208,209,210,211,212,213,214,215,216,217,218],"wealth advisory","advisory","stock","inheritance","conversion","indexing","plan","simulation","personal finance","rate","allocation","asset","direct","personal","investing","trust","planning"]