290e7dbc34
- ActivityChart: native SVG line chart (без chart-library, чтобы не +400KB зависимость для статичных дашборд-графиков). Y-grid 5 линий, area-gradient, 7 точек (предпоследняя выделена primary teal как «сегодня»), 3 tabs (Принято/Оплачено/Отказ). - FunnelChart: segmented bar по 14 статусам + funnel-list (sort desc). - composables/leadStatuses.ts: snapshot 14 статусов из db/schema.sql:2130 (НЕ из BRANDBOOK §3.6 - расхождение #1 handoff vs ТЗ из реестра v1.13). 14 правильных slug'ов: new/viewed/worked/base/missed/negotiations/ waiting_payment/partnership/paid/closed/test_drive/hot/replacement/final_missed. - DashboardView интегрирует оба чарта в charts-row (md=7+5). - cspell-words.txt: ldot, композаблом, инлайнингом, инлайнены. Vue compiler quirk: withDefaults factory не разрешает референсить module-level const'ы (checkInvalidScopeReference). Обходим инлайнингом литерала. Vitest +13 тестов (всего 48/48 за 5.5s): - ActivityChart 6 (3 tabs + 7 circles + 'сегодня' + custom points + legend) - FunnelChart 7 (14 segments + 14 list-items + assertion на отсутствие 'Думает'/'Спам' из handoff + сортировка + colorHex + total) Stories +2 с 3 variants каждый (Histoire 10/14 за 30.43s). Регресс: lint+type-check+format OK; vitest 48/48; vite build (DashboardView chunk 14.9->21.17 KB с чартами); story:build 10/14 за 30.43s; Pest 48/48 за 5.10s. CLAUDE.md v1.21->v1.22, реестр Открытых_вопросов v1.30->v1.31. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
36 lines
2.4 KiB
TypeScript
36 lines
2.4 KiB
TypeScript
/**
|
|
* 14 системных и пользовательских статусов воронки.
|
|
*
|
|
* Источник истины: db/schema.sql:2130 (lead_statuses seed). НЕ из BRANDBOOK_v2 §3.6
|
|
* (расхождение #1 handoff vs ТЗ из реестра v1.13: handoff содержит 14 «обобщённых»
|
|
* статусов, не совпадающих с реальными slug'ами; пересечение всего 2 — Переговоры
|
|
* и Оплачено).
|
|
*
|
|
* При фактической интеграции с API подтягиваем `GET /api/lead-statuses` —
|
|
* система+tenant-кастом. Сейчас — компайл-тайм snapshot для UI.
|
|
*/
|
|
export interface LeadStatus {
|
|
slug: string;
|
|
nameRu: string;
|
|
isSystem: boolean;
|
|
sortOrder: number;
|
|
colorHex: string;
|
|
}
|
|
|
|
export const LEAD_STATUSES: LeadStatus[] = [
|
|
{ slug: 'new', nameRu: 'Новые', isSystem: true, sortOrder: 1, colorHex: '#3B82F6' },
|
|
{ slug: 'viewed', nameRu: 'Просмотрено', isSystem: true, sortOrder: 2, colorHex: '#8B5CF6' },
|
|
{ slug: 'worked', nameRu: 'Проработан', isSystem: true, sortOrder: 3, colorHex: '#06B6D4' },
|
|
{ slug: 'base', nameRu: 'База', isSystem: false, sortOrder: 4, colorHex: '#64748B' },
|
|
{ slug: 'missed', nameRu: 'Недозвон', isSystem: false, sortOrder: 5, colorHex: '#F59E0B' },
|
|
{ slug: 'negotiations', nameRu: 'Переговоры', isSystem: false, sortOrder: 6, colorHex: '#EAB308' },
|
|
{ slug: 'waiting_payment', nameRu: 'Ожидаем оплаты', isSystem: false, sortOrder: 7, colorHex: '#A78BFA' },
|
|
{ slug: 'partnership', nameRu: 'Партнерка', isSystem: false, sortOrder: 8, colorHex: '#EC4899' },
|
|
{ slug: 'paid', nameRu: 'Оплачено', isSystem: true, sortOrder: 9, colorHex: '#10B981' },
|
|
{ slug: 'closed', nameRu: 'Закрыто и не реализовано', isSystem: true, sortOrder: 10, colorHex: '#6B7280' },
|
|
{ slug: 'test_drive', nameRu: 'Тест драйв', isSystem: false, sortOrder: 11, colorHex: '#14B8A6' },
|
|
{ slug: 'hot', nameRu: 'Горячий', isSystem: false, sortOrder: 12, colorHex: '#EF4444' },
|
|
{ slug: 'replacement', nameRu: 'На замену', isSystem: false, sortOrder: 13, colorHex: '#F97316' },
|
|
{ slug: 'final_missed', nameRu: 'Конечный недозвон', isSystem: true, sortOrder: 14, colorHex: '#1F2937' },
|
|
];
|