
🎨 Унификация UI: - Полная унификация визуала вкладок Рефералы и Мои контрагенты - Исправлены React Hooks ошибки в sidebar.tsx - Убрана лишняя обертка glass-card в partners-dashboard.tsx - Исправлена цветовая схема (purple → yellow) - Табличный формат вместо карточного grid-layout - Компактные блоки статистики (4 метрики в ряд) - Правильная прозрачность glass-morphism эффектов 📚 Документация: - Переименован referral-system-rules.md → partners-rules.md - Детальные UI/UX правила в partners-rules.md - Правила унификации в visual-design-rules.md - Обновлен current-session.md - Создан development-diary.md 🚀 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
30 KiB
🎯 ПРАВИЛА РЕФЕРАЛЬНОЙ СИСТЕМЫ SFERA
⚠️ КРИТИЧЕСКИ ВАЖНОЕ ПРАВИЛО: НЕ ПУТАТЬ "ПАРТНЁРСКИЕ ССЫЛКИ" И "РЕФЕРАЛЬНЫЕ ССЫЛКИ"
📅 Дата создания: 2025-01-10
🔧 Статус: Спецификация для разработки
📌 Версия: 1.1
📋 ОГЛАВЛЕНИЕ
- Общие принципы
- Структура данных
- Генерация реферальных ссылок
- UI/UX компоненты
- Система начисления баллов
- GraphQL API
- Процесс регистрации по реферальной ссылке
- Автоматическое партнерство через бизнес-сделки
- Безопасность и ограничения
1. ОБЩИЕ ПРИНЦИПЫ
1.1 Основные положения
- УНИВЕРСАЛЬНОСТЬ: Реферальная система доступна для всех типов кабинетов (SELLER, WHOLESALE, FULFILLMENT, LOGIST)
- АВТОМАТИЗАЦИЯ: Реферальная ссылка генерируется автоматически при создании организации
- ПРОЗРАЧНОСТЬ: Все начисления сфер ⚡ видны в режиме реального времени
- БЕЗОПАСНОСТЬ: Невозможно изменить реферальную ссылку после генерации
- ИНТЕГРАЦИЯ С БИЗНЕСОМ: Партнерство создается не только через рефералы, но и через коммерческие сделки
1.2 Терминология
- РЕФЕРЕР - организация, которая приглашает новых участников
- РЕФЕРАЛ - организация, зарегистрированная по реферальной ссылке
- РЕФЕРАЛЬНЫЙ КОД - уникальный идентификатор в ссылке (10 символов)
- СФЕРЫ ⚡ - единица вознаграждения за привлечение рефералов и коммерческие сделки
- АВТОПАРТНЕРСТВО - автоматическое создание партнерских связей при коммерческих сделках
- РЕФЕРАЛЬНАЯ ССЫЛКА - маркетинговый инструмент (
?ref=
), только начисление сфер - ПАРТНЕРСКАЯ ССЫЛКА - бизнес-инструмент (
?partner=
), сферы + автоматическое партнерство
1.3 Разделение ссылок
Реферальная система (маркетинг):
- URL формат:
https://app.sfera.ru/register?ref=SF2X9K4M7P
- Местоположение: Вкладка "Рефералы"
- Цель: Привлечение новых пользователей на платформу
- Результат: +100 сфер ⚡, автоматического партнерства НЕТ
- Ссылка: Уже готова при создании организации, быстрое копирование
Партнерская система (бизнес):
- URL формат:
https://app.sfera.ru/register?partner=SF2X9K4M7P
- Местоположение: Вкладка "Мои партнеры"
- Цель: Прямое деловое сотрудничество
- Результат: +100 сфер ⚡ + автоматическое добавление в партнеры
- Ссылка: Уже готова при создании организации, быстрое копирование
2. СТРУКТУРА ДАННЫХ
2.1 Расширение модели Organization (Prisma)
model Organization {
// Существующие поля...
// Реферальная система
referralCode String? @unique @default(cuid()) // Уникальный код для реферальной ссылки
referredById String? // ID организации-реферера
referredBy Organization? @relation("ReferralRelation", fields: [referredById], references: [id])
referrals Organization[] @relation("ReferralRelation")
referralPoints Int @default(0) // Общее количество баллов
@@index([referralCode])
@@index([referredById])
}
2.2 Новая модель ReferralTransaction
model ReferralTransaction {
id String @id @default(cuid())
referrerId String // Кто получил баллы
referralId String // За кого получил баллы
points Int // Количество баллов
type ReferralTransactionType // Тип транзакции
description String? // Описание транзакции
createdAt DateTime @default(now())
referrer Organization @relation("ReferrerTransactions", fields: [referrerId], references: [id])
referral Organization @relation("ReferralTransactions", fields: [referralId], references: [id])
@@index([referrerId, createdAt])
@@index([referralId])
}
enum ReferralTransactionType {
REGISTRATION // За регистрацию по реферальной ссылке
AUTO_PARTNERSHIP // За автоматическое партнерство через бизнес-сделку
FIRST_ORDER // За первый заказ (будущее расширение)
MONTHLY_BONUS // Ежемесячный бонус (будущее расширение)
}
3. ГЕНЕРАЦИЯ РЕФЕРАЛЬНЫХ ССЫЛОК
3.1 Формат реферальной ссылки
https://app.sfera.ru/register?ref={referralCode}
3.2 Алгоритм генерации кода
- Длина: 10 символов
- Символы: A-Z, 0-9 (исключая похожие: O/0, I/1)
- Пример:
SF2X9K4M7P
3.3 Правила генерации
- Генерируется автоматически при создании организации
- Проверка уникальности перед сохранением
- Невозможно изменить после создания
- Хранится в поле
referralCode
модели Organization
4. UI/UX КОМПОНЕНТЫ
4.1 Вкладка "Рефералы" в разделе Партнеры
Расположение
- Раздел:
/partners
- Новая вкладка: 6-я позиция после "Поставщик"
- Название: "Рефералы"
- Иконка:
Gift
илиUsers2
из lucide-react
Структура страницы
<div className="referrals-page">
{/* Блок с реферальной ссылкой */}
<div className="referral-link-section glass-card p-6 mb-6">
<h3>Ваша реферальная ссылка</h3>
<div className="flex items-center gap-4">
<div className="hidden-link">••••••••••</div>
<Button onClick={copyLink}>
<Copy className="h-4 w-4 mr-2" />
Копировать ссылку
</Button>
</div>
<p className="text-sm text-white/60 mt-2">
Поделитесь ссылкой с партнерами и получайте баллы за каждую регистрацию
</p>
</div>
{/* Статистика */}
<div className="stats-grid grid grid-cols-4 gap-4 mb-6">
<StatsCard title="Всего партнеров" value={totalReferrals} icon="Users" />
<StatsCard title="Сфер заработано" value={totalPoints} icon="Zap" suffix="⚡" />
<StatsCard title="Партнеров за месяц" value={monthlyReferrals} icon="TrendingUp" />
<StatsCard title="Сфер за месяц" value={monthlyPoints} icon="Zap" suffix="⚡" />
</div>
{/* Фильтры */}
<div className="filters glass-card p-4 mb-6">
<DateRangePicker />
<TypeFilter types={['SELLER', 'WHOLESALE', 'FULFILLMENT', 'LOGIST']} />
<SearchInput placeholder="Поиск по названию или ИНН" />
</div>
{/* Таблица рефералов */}
<div className="referrals-table glass-card">
<Table>
<TableHeader>
<TableRow>
<TableHead>Дата регистрации</TableHead>
<TableHead>Название организации</TableHead>
<TableHead>ИНН</TableHead>
<TableHead>Тип кабинета</TableHead>
<TableHead>Источник</TableHead>
<TableHead>Начислено сфер ⚡</TableHead>
<TableHead>Статус</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{referrals.map(referral => (
<TableRow key={referral.id}>
<TableCell>{formatDate(referral.createdAt)}</TableCell>
<TableCell>{referral.name || referral.fullName}</TableCell>
<TableCell>{referral.inn}</TableCell>
<TableCell>
<Badge className={getTypeBadgeStyles(referral.type)}>
{getTypeLabel(referral.type)}
</Badge>
</TableCell>
<TableCell>
<div className="flex items-center gap-2">
{referral.source === 'REFERRAL' ? (
<>
<UserPlus className="h-4 w-4 text-blue-400" />
<span className="text-blue-300">Реферальная ссылка</span>
</>
) : (
<>
<ShoppingCart className="h-4 w-4 text-orange-400" />
<span className="text-orange-300">Бизнес-сделка</span>
</>
)}
</div>
</TableCell>
<TableCell>
<div className="flex items-center gap-1">
<span className="text-green-400">+{referral.points}</span>
<Zap className="h-4 w-4 text-yellow-400" />
</div>
</TableCell>
<TableCell>
<Badge variant="success">Активен</Badge>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div>
</div>
4.2 Визуальные элементы
Скрытие реферальной ссылки
- Ссылка НЕ отображается в явном виде
- Показываются точки или звездочки:
••••••••••
- Только кнопка "Копировать ссылку"
Уведомления
- При копировании: "Реферальная ссылка скопирована"
- При новом реферале: push-уведомление
- При начислении баллов: анимация изменения баланса
5. СИСТЕМА НАЧИСЛЕНИЯ БАЛЛОВ
5.1 Базовые ставки
Тип регистрации | Количество баллов |
---|---|
SELLER | 100 сфер ⚡ |
WHOLESALE | 100 сфер ⚡ |
FULFILLMENT | 100 сфер ⚡ |
LOGIST | 100 сфер ⚡ |
💡 ИКОНКА СФЕРЫ: ⚡ (молния) - символизирует энергию, скорость и силу партнерства
5.2 Правила начисления
- МОМЕНТ НАЧИСЛЕНИЯ: Сразу после успешной регистрации реферала
- УСЛОВИЕ: Реферал должен пройти полную регистрацию (подтвердить ИНН)
- ОГРАНИЧЕНИЯ: Один ИНН = одно начисление (защита от дублей)
- ВИДИМОСТЬ: Баллы сразу отображаются в таблице и общем счетчике
5.3 Будущие расширения
- Бонусы за первый заказ реферала
- Ежемесячные начисления за активных рефералов
- Многоуровневая система (рефералы рефералов)
6. GRAPHQL API
6.1 Новые Queries
type Query {
# Получить мою реферальную ссылку
myReferralLink: String!
# Список моих рефералов
myReferrals(
dateFrom: DateTime
dateTo: DateTime
type: OrganizationType
search: String
limit: Int
offset: Int
): ReferralsResponse!
# Статистика по рефералам
myReferralStats: ReferralStats!
# История транзакций баллов
myReferralTransactions(
limit: Int
offset: Int
): ReferralTransactionsResponse!
}
6.2 Новые Types
type ReferralsResponse {
referrals: [Referral!]!
totalCount: Int!
totalPages: Int!
}
type Referral {
id: ID!
organization: Organization!
registeredAt: DateTime!
pointsEarned: Int!
status: ReferralStatus!
transactions: [ReferralTransaction!]!
}
type ReferralStats {
totalReferrals: Int!
totalPoints: Int!
monthlyReferrals: Int!
monthlyPoints: Int!
referralsByType: [ReferralTypeStats!]!
}
type ReferralTypeStats {
type: OrganizationType!
count: Int!
points: Int!
}
type ReferralTransaction {
id: ID!
points: Int!
type: ReferralTransactionType!
description: String
createdAt: DateTime!
referral: Organization!
}
enum ReferralStatus {
ACTIVE
INACTIVE
BLOCKED
}
6.3 Расширение существующих типов
extend type Organization {
referralCode: String
referredBy: Organization
referrals: [Organization!]!
referralPoints: Int!
isMyReferral: Boolean! # Computed field
}
7. ПРОЦЕСС РЕГИСТРАЦИИ ПО ССЫЛКАМ
7.1 Реферальная ссылка (маркетинг)
Пошаговый процесс:
-
Переход по ссылке
- Пользователь переходит по ссылке:
https://app.sfera.ru/register?ref=SF2X9K4M7P
- Система сохраняет реферальный код в sessionStorage
- Пользователь переходит по ссылке:
-
Регистрация
- Стандартный процесс регистрации
- Реферальный код передается в mutation
registerOrganization
-
Валидация
- Проверка существования реферального кода
- Проверка, что организация не регистрировалась ранее
-
Создание связи
- Установка
referredById
для новой организации - Создание записи в
ReferralTransaction
- ВАЖНО: Автоматическое партнерство НЕ создается
- Установка
-
Начисление баллов
- Автоматическое начисление 100 сфер ⚡ рефереру
- Отправка уведомления рефереру
7.2 Партнерская ссылка (бизнес)
Пошаговый процесс:
-
Переход по ссылке
- Пользователь переходит по ссылке:
https://app.sfera.ru/register?partner=SF2X9K4M7P
- Система сохраняет партнерский код в sessionStorage
- Пользователь переходит по ссылке:
-
Регистрация
- Стандартный процесс регистрации
- Партнерский код передается в mutation
registerOrganization
-
Валидация
- Проверка существования партнерского кода
- Проверка, что организация не регистрировалась ранее
-
Создание связи
- Установка
referredById
для новой организации - Создание записи в
ReferralTransaction
- ВАЖНО: Автоматическое создание партнерства (
Counterparty
)
- Установка
-
Начисление баллов
- Автоматическое начисление 100 сфер ⚡ партнеру
- Отправка уведомления партнеру
- Добавление в список "Мои партнеры"
7.3 Логика различения
// В процессе регистрации
if (query.ref) {
// Реферальная ссылка - только сферы
await addReferralTransaction(referrerId, newUserId, 100, 'REFERRAL_LINK')
} else if (query.partner) {
// Партнерская ссылка - сферы + автоматическое партнерство
await addReferralTransaction(partnerId, newUserId, 100, 'REFERRAL_LINK')
await createPartnership(partnerId, newUserId, 'REFERRAL')
}
7.4 Обработка ошибок
- Невалидный код: Регистрация продолжается без реферала/партнерства
- Самореферал: Блокировка (нельзя регистрироваться по своей ссылке)
- Повторная регистрация: Игнорирование кода
8. АВТОМАТИЧЕСКОЕ ПАРТНЕРСТВО ЧЕРЕЗ БИЗНЕС-СДЕЛКИ
8.1 Принцип работы
Кроме реферальных ссылок, партнерские отношения создаются автоматически через коммерческие взаимодействия в системе.
8.2 Триггер автопартнерства
МОМЕНТ СОЗДАНИЯ ПАРТНЕРСТВА: Когда поставщик одобряет заявку на поставку (supplierApproveOrder
mutation)
УСЛОВИЕ: Если между организациями еще нет партнерских отношений (Counterparty
связи)
ДЕЙСТВИЕ: Автоматическое создание взаимного партнерства
8.3 Алгоритм автопартнерства
// В GraphQL резолвере supplierApproveOrder
async supplierApproveOrder(supplyOrderId: string) {
// 1. Одобрить заявку
const supplyOrder = await updateSupplyOrderStatus(supplyOrderId, 'SUPPLIER_APPROVED')
// 2. Проверить существование партнерства
const existingCounterparty = await checkCounterpartyExists(
supplyOrder.organizationId, // Покупатель
supplyOrder.partnerId // Поставщик
)
// 3. Создать автопартнерство если его нет
if (!existingCounterparty) {
await createAutoCounterparty({
organizationId: supplyOrder.organizationId,
counterpartyId: supplyOrder.partnerId,
type: 'AUTO_BUSINESS',
triggeredBy: 'SUPPLY_ORDER_APPROVAL',
supplyOrderId: supplyOrderId
})
}
return supplyOrder
}
8.4 Расширение модели данных
model Counterparty {
// Существующие поля...
// Новые поля для автопартнерства
type CounterpartyType @default(MANUAL)
triggeredBy String? // 'SUPPLY_ORDER_APPROVAL', 'REFERRAL_LINK'
triggerEntityId String? // ID заявки, реферала и т.д.
@@index([type])
}
enum CounterpartyType {
MANUAL // Создано вручную через UI
REFERRAL // Создано через реферальную ссылку
AUTO_BUSINESS // Создано автоматически через бизнес-сделку
}
8.5 Начисление сфер за автопартнерство
ДЛЯ ПОСТАВЩИКА (кто одобрил заявку):
- +100 сфер ⚡ за каждого нового партнера через бизнес-сделку
- Равно рефералу, так как это также ценное партнерство
ДЛЯ ПОКУПАТЕЛЯ:
- Партнерство создается, но сферы не начисляются
- Выгода в том, что появляется прямая связь с поставщиком
8.6 Отображение в UI
В таблице рефералов добавить колонку "Источник":
Источник | Описание | Иконка |
---|---|---|
Реферальная ссылка | Зарегистрировались по вашей ссылке | UserPlus |
Бизнес-сделка | Стали партнерами через заказ | ShoppingCart |
8.7 Логирование автопартнерства
// Лог события создания автопартнерства
{
event: 'auto_counterparty_created',
supplierId: '...',
buyerId: '...',
supplyOrderId: '...',
spheresEarned: 50,
timestamp: '2025-01-10T15:30:00Z'
}
9. БЕЗОПАСНОСТЬ И ОГРАНИЧЕНИЯ
9.1 Защита от злоупотреблений
- Один ИНН - одна регистрация: Проверка уникальности ИНН
- Блокировка самореферала: Проверка IP и device fingerprint
- Лимиты: Максимум 100 регистраций в день с одного реферального кода
- Валидация ИНН: Обязательная проверка через DaData API
9.2 Права доступа
- Просмотр своих рефералов: Только владелец реферального кода
- Изменение кода: Запрещено
- Просмотр чужих рефералов: Запрещено
- Администратор: Полный доступ для модерации
9.3 Логирование
Все действия с реферальной системой логируются:
- Генерация ссылок
- Переходы по ссылкам
- Регистрации
- Начисления баллов
- Попытки злоупотреблений
🎨 UI/UX ПРАВИЛА РАЗДЕЛА "ПАРТНЕРЫ"
10.1 Принципы унификации интерфейса
КРИТИЧЕСКИ ВАЖНО: Все вкладки раздела "Партнеры" должны иметь единый визуальный дизайн:
Обязательная унификация:
- Идентичная структура блоков статистики: 4 метрики в ряд
- Одинаковые цветовые схемы для аналогичных элементов
- Табличный формат отображения данных вместо карточного grid-layout
- Компактное использование пространства
Структура DOM для блоков статистики:
{/* ПРАВИЛЬНАЯ структура */}
<div className="grid grid-cols-4 gap-3">
<Card className="glass-card p-3 hover:bg-white/5 transition-all duration-200">
<div className="p-1.5 rounded-lg bg-{color}-500/20 border border-{color}-500/30">
<Icon className="h-4 w-4 text-{color}-400" />
</div>
</Card>
</div>
{/* ЗАПРЕЩЕНО - дополнительные обертки */}
<Card className="glass-card">
<div className="grid grid-cols-4 gap-3">
<div>...</div> // <- НЕ glass-card внутри glass-card!
</div>
</Card>
10.2 Техническая реализация
A) Вкладка "Рефералы":
- Файл:
src/components/partners/referrals-tab.tsx
- Структура: Каждый блок статистики = отдельный
<Card className="glass-card">
- Прозрачность: Через glass-morphism эффекты
- Отступы: Компактные (
p-3
,p-4
)
B) Вкладка "Мои контрагенты":
- Файл:
src/components/market/market-counterparties.tsx
- Структура: Конвертирована от карточного grid к табличному формату
- Блоки статистики: Добавлены 4 компактных блока (Партнеров, Заявок, За месяц, Исходящих)
- Обертки: УБРАНА лишняя обертка
glass-card
вpartners-dashboard.tsx
10.3 Цветовая схема блоков
Реферальные/Партнерские ссылки (верхний блок):
- Цвет:
bg-yellow-500/20 border border-yellow-500/30
- Иконка:
text-yellow-400
- ЗАПРЕЩЕНО: Использовать фиолетовую схему (
bg-purple-500/20
)
Блоки статистики:
- 1-й блок (Партнеров):
bg-blue-500/20
+text-blue-400
(синий) - 2-й блок (Заработано/Заявок):
bg-yellow-500/20
+text-yellow-400
(желтый) - 3-й блок (За месяц):
bg-green-500/20
+text-green-400
(зеленый) - 4-й блок (Сфер за месяц/Исходящих):
bg-yellow-500/20
+text-yellow-400
(желтый)
10.4 Компоненты и размеры
Оптимизация пространства:
- Отступы карточек:
p-4
для верхнего блока,p-3
для статистики - Размеры иконок:
h-4 w-4
(компактно) - Шрифты заголовков:
text-base
вместоtext-2xl
- Отступы между блоками:
space-y-4
Hover эффекты:
- Блоки статистики:
hover:bg-white/5 transition-all duration-200
- Кнопки:
glass-button hover:bg-white/20
10.5 Исправления структурных проблем
КРИТИЧЕСКИ ВАЖНЫЕ исправления:
-
Убрана лишняя обертка в
src/components/partners/partners-dashboard.tsx
:// БЫЛО (неправильно): <TabsContent value="counterparties"> <Card className="glass-card"> // <- ЛИШНЯЯ обертка! <MarketCounterparties /> </Card> </TabsContent> // СТАЛО (правильно): <TabsContent value="counterparties"> <MarketCounterparties /> </TabsContent>
-
Исправлена цветовая схема верхнего блока в контрагентах:
// БЫЛО: bg-purple-500/20 text-purple-400 // СТАЛО: bg-yellow-500/20 text-yellow-400
10.6 Результат унификации
После применения правил:
- ✅ Идентичная прозрачность блоков (glass-morphism)
- ✅ Единая цветовая схема между вкладками
- ✅ Компактное использование пространства
- ✅ Табличный формат во всех вкладках
- ✅ Консистентная структура DOM
🎨 ВИЗУАЛЬНЫЙ ДИЗАЙН
Цветовая схема для сфер ⚡
- Положительные начисления:
text-green-400
- Иконка молнии:
text-yellow-400
(золотистый) - Фон для сфер:
bg-yellow-500/20
- Анимация при изменении:
animate-pulse
на 2 секунды
Иконки источников партнерства
- Реферальная ссылка:
UserPlus
вtext-blue-400
- Бизнес-сделка:
ShoppingCart
вtext-orange-400
- Сферы:
Zap
вtext-yellow-400
Стили для типов кабинетов (соответствуют существующим)
- SELLER:
bg-green-500/20 text-green-300
- WHOLESALE:
bg-purple-500/20 text-purple-300
- FULFILLMENT:
bg-blue-500/20 text-blue-300
- LOGIST:
bg-orange-500/20 text-orange-300
📊 МЕТРИКИ УСПЕХА
- Конверсия: % регистраций по реферальным ссылкам
- Активность: Среднее количество рефералов на одного партнера
- Retention: % активных рефералов через 30 дней
- Виральность: Количество рефералов, которые сами привели рефералов
🚀 ПЛАН ВНЕДРЕНИЯ
Фаза 1 (MVP)
- Базовая генерация ссылок
- Регистрация по реферальным ссылкам
- Начисление баллов за регистрацию
- UI для просмотра рефералов
Фаза 2
- Бонусы за первый заказ
- Email уведомления о новых рефералах
- Экспорт данных о рефералах
Фаза 3
- Многоуровневая система
- Использование баллов для оплаты услуг
- Gamification элементы (достижения, уровни)
Дата создания: 2025-01-10
Автор: Claude AI Assistant
Статус: Готово к реализации