Files
CRM-LeadRadar/README.md
T

147 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Y&P Lead Radar
Сервис находит новые объявления на List.am по фильтрам клиента, доставляет их агентам в Telegram
и ведёт каждый объект как лид в CRM до сделки. Домен: `listcrm.yandpconsulting.com`.
Написан с нуля по ТЗ. Из прежней CRM (`../crmyerevan-…`) взят только модуль парсера —
см. [docs/PARSER.md](docs/PARSER.md).
## Структура
| Путь | Назначение |
| ----------------- | -------------------------------------------------------------------------- |
| `apps/api` | Бэкенд: Fastify, Postgres (Drizzle). Один API для веб-кабинета и Mini App |
| `apps/web` | Веб-кабинет и Mini App: React, Tailwind, тема сайта yandpconsulting.com |
| `packages/shared` | Тарифы и лимиты, роли, воронки по умолчанию, сопоставление с фильтрами |
## Запуск на своём компьютере
Нужны Node 22+, pnpm 10, Docker.
```bash
cp .env.example .env
pnpm install
pnpm db:up # Postgres в Docker, порт 5433
pnpm db:migrate
pnpm --filter @lr/api superadmin <email> "Имя" # печатает пароль суперадмина
pnpm dev:api # http://localhost:3100
pnpm dev:web # http://localhost:5174
```
Проверки: `pnpm typecheck && pnpm test` (тестам API нужен запущенный Postgres и база
`leadradar_test`).
После изменения `apps/api/src/db/schema.ts`: `pnpm db:generate && pnpm db:migrate` — появится новый
файл миграции в `apps/api/drizzle/`; старые файлы миграций не правятся и не удаляются.
## Что готово
- Схема данных всех сущностей ТЗ (раздел 9).
- Вход по email и паролю, через Telegram Login и Telegram Mini App; подтверждение email и
сброс пароля (письма пока пишутся в лог API — почтовый сервис не выбран).
- Компании, тарифы и лимит участников, роли, приглашения, удаление агента.
- Состояние подписки: активна → просрочена (15 дней) → только чтение.
- Суперадмин: компании, тариф, дата окончания, отсрочка, вход в кабинет, состояние парсера.
- **Парсер → общая база → фильтры → лиды**: все категории недвижимости list.am, в базу идут
объявления не старше 3 дней, оттуда — клиентам по общим и личным фильтрам.
- **Бот**: уведомление о лиде с кнопкой «Беру», атомарный захват, «Взял(а) Имя» у остальных,
привязка Telegram, /pause и /resume, тихие часы. Очередь сообщений с повторами и лимитом темпа.
- **Пул**: возврат через 24 часа без смены статуса, предупреждение за 2 часа, повторное «Беру».
- **Воронка объекта**: статусы, отказ с причиной, сделка с комиссией, назначение и
переназначение, комментарии, напоминания, история, «Это агент», лиды вручную.
- **Воронка клиента**: покупатели и арендаторы, запрос клиента, подбор подходящих объектов из CRM,
отметки «предложен» и «показан», переназначение руководителем, напоминания в боте.
- **Общая сделка**: объект и клиент из CRM закрываются один раз, комиссия записывается одной
строкой из двух частей: с собственника — агенту объекта, с покупателя или арендатора — агенту
клиента; если стороны в CRM нет, обе части получает агент второй стороны. Суммы и дату исправляет
руководитель.
- **Оплата агентов**: оклад, процент с части комиссии агента (отдельно для продажи и аренды) или
оклад + процент; план на месяц (сделки, комиссия) и бонус за него — суммой или надбавкой к
проценту. Ведомость «Кому сколько платить» за месяц; строка сотрудника раскрывает его сделки,
начисления, ручные записи (премия, штраф, аванс) и отметку «выплачено». Выплата закрывает месяц:
он считается по условиям и курсам на день выплаты, а изменения его сделок и недоплата переходят
перерасчётом в ближайший месяц без выплаты. Агент видит свои условия, сделки, начисления и историю
выплат в «Настройках».
- **Динамика и рейтинг**: сделки и комиссия по месяцам — по компании и по каждому сотруднику
(агент видит только свою); рейтинг месяца виден всем: место, число сделок, выполнение плана,
без сумм. Ведомость со сделками выгружается файлом для Excel.
- **Суперадмину в Telegram** приходит уведомление о каждой новой регистрации и о компании,
созданной самостоятельно: имя, email, Telegram. **Приветствие бота** (ответ на /start тому, кто
ещё не привязал Telegram): текст на трёх языках и до 10 файлов — в разделе «Сообщения». Следом бот
спрашивает язык кнопками; выбор запоминается, на нём бот отвечает и создаётся аккаунт.
- **Отчёты в Telegram** (включает руководитель в настройках компании): итоги недели по
понедельникам и итоги месяца с ведомостью первого числа, в 9 утра по Еревану.
- **Настройка воронок**: руководитель переименовывает, добавляет, удаляет и переставляет
промежуточные статусы и причины отказа в обеих воронках.
- **База** (Team, Agency): объекты и клиенты (покупатели, арендаторы), закрытые сделкой или отказом; у клиента — связанные
объекты. Раз в сутки объекты из CRM проверяются на list.am: снятое объявление получает отметку
и дату. Повторно опубликованный объект приходит новым лидом с блоком «Уже был в работе».
- **Аналитика** (Team, Agency, руководителю): сводка, воронка, таблица по агентам (взято, скорость
реакции, возвраты в пул, конверсия по этапам, сделки, комиссии), причины отказа, выгрузка в CSV;
отдельно по объектам и по клиентам.
- **Суперадмин — «Объявления»**: вся общая база объявлений с поиском, фильтрами и карточкой
«кому ушло лидом». **Настройки парсера** в админке: включение, свежесть в днях, пауза, число
страниц, категории, ключ ридера Jina, проверка снятых объявлений — без перезапуска сервиса. **Ночная пауза**: с 22:00 до 8:00 по Еревану
парсер и проверка снятых не работают (экономия токенов Jina), сторож парсера ночью молчит.
- **Биллинг**: счета за установку, фикс и «%» с расшифровкой по сделкам; смена тарифа со
следующего месяца; напоминания за 7, 3 и 1 день и при просрочке; ручная отметка оплаты
суперадмином; контракт платёжного провайдера для онлайн-оплаты — см. [docs/BILLING.md](docs/BILLING.md).
- **Суперадмин — «Счета» и «Сообщения»**: сводка (активные компании, выручка за месяц, просрочки),
счета всех компаний, курсы валют; сообщения в Telegram всем, компании, руководителям или одному
пользователю с журналом отправок.
- **Поддержка**: всё, что человек пишет боту (текст, фото, файл), попадает в обращение. Суперадмин
отвечает в разделе «Поддержка» — ответ уходит в тот же чат — и закрывает кнопкой «Проблема решена».
В кабинете у пользователей есть раздел «Поддержка» с подсказкой, как написать.
- **Характеристики объявления**: со страницы List.am берутся удобства по разделам, «можно с детьми»,
«можно с животными», мебель, ремонт, предоплата и остальные поля. Видны в карточке объекта;
правила про детей и животных — ещё и в уведомлении бота. Телефон автора не собирается.
- **Кто будет жить** (карточка клиента): один, с другом, пара; дети и животные с количеством и
возрастом; до 10 фото. Подбор не предлагает объекты, где с детьми или животными прямо нельзя.
- **Анкета соискателя**: у каждого агента своя ссылка на клиентский бот (команда `/anketa` в основном
боте или кнопка в разделе «Клиенты»). Соискатель отвечает на вопросы — в CRM появляется клиент,
закреплённый за агентом, а агент получает в бот вопрос «Показать подходящие объекты?».
- **Страница подборки для клиента**: `<кабинет>/<компания>/<код>` — объекты, прикреплённые к клиенту,
и запись на показ по дням. Адрес и ссылка на List.am на странице скрыты. Запись на показ приходит
создателю ссылки в бот и появляется в карточке клиента.
- **Фото и текст на странице клиента** (логика из бота `list-am-bot`): для объектов, которые показывают
клиенту, догружается полный набор фото объявления; фото отдаёт сам сервис, срезая сверху 8 % высоты
(`CROP_TOP_PERCENT`); текст собирается по шаблону-карточке, а с ключом `OPENROUTER_API_KEY`
дополняется абзацем из описания. Адреса в тексте нет.
- **Карточка объекта**: все фото объявления (обрезанные, догружаются в фоне после первого открытия),
«Описание для клиента» с кнопкой копирования и поле «Телефон собственника» — номер агент берёт из
объявления сам; он сохраняется в карточке и, если в общей базе его не было, в базе объявлений.
- **Комиссия агентства**: руководитель задаёт в настройках процент или фикс — отдельно для объектов и
клиентов, продажи и аренды. В карточке видно условие и ожидаемую сумму; агент может поменять условие
для своей карточки. При закрытии сделки сумма комиссии подставляется по условию.
- **Оплата агентов**: руководитель задаёт каждому сотруднику оклад, процент с комиссии по его сделкам
или оклад + процент («Команда»). Там же таблица «Кому сколько платить» за выбранный месяц; агент
видит свои условия и начисления в настройках.
- **Отделы** (раздел «Команда»): руководитель создаёт отделы, назначает и снимает сотрудников, задаёт фильтры
отдела. У отдела свои объекты и клиенты: сотрудник видит только данные своего отдела, руководитель и
суперадмин — все отделы (с выбором отдела в списках). Одно объявление под фильтрами двух отделов приходит
каждому своей карточкой; уведомления — сотрудникам отдела. При смене отдела объекты и клиенты сотрудника
переходят с ним. Удалить можно отдел без сотрудников, клиентов и объектов в работе.
- **Рабочий список объектов** показывает только актуальное: снятые с List.am и закрытые сделкой или отказом
объекты не попадают в список, поиск, подбор, страницу клиента и витрину — они остаются в базе и в «Базе»
(фильтр «Сняты с List.am»).
- **Избранное и «Не просмотренные»**: звёздочка в списке и карточке, у каждого своя; фильтры сочетаются со
всеми остальными. **Цена в АМД или ДОЛ**: границы задаются в выбранной валюте, цены объектов в другой
валюте пересчитываются по курсу из админки («Счета»); при смене валюты введённые границы пересчитываются.
- **«Отправить в бот»** в карточке объекта: фото, описание и комиссия приходят основным ботом в личный чат
того, кто нажал. Без привязанного Telegram — инструкция и кнопка привязки.
- **Демо-компании**: `scripts/seed-demo.mjs` создаёт «Демо: Аренда» и «Демо: Продажа» на настоящих
объявлениях из базы, `scripts/seed-demo-backdate.sql` раскладывает их историю по трём неделям.
- **Мастер первой настройки**: первый фильтр, привязка бота, приглашение агентов.
- **Mini App**: тот же кабинет в Telegram с входом без пароля и нижней панелью разделов.
Тариф Solo в браузере видит только подписку и профиль — рабочие разделы открываются в Telegram.
- Веб-кабинет: объекты (таблица и канбан), карточка, клиенты, база, аналитика, фильтры, команда,
настройки, подписка, админка; три языка, тёмная и светлая тема.
- **Боевая сборка**: Docker-образы, ежедневная резервная копия, скрипт выкладки —
см. [docs/DEPLOY.md](docs/DEPLOY.md).
## Что дальше
1. Выкладка на VPS по [docs/DEPLOY.md](docs/DEPLOY.md): домен, боевой бот, первая выкладка.
2. Ручная приёмка на боевом стенде — что осталось, перечислено в [docs/ACCEPTANCE.md](docs/ACCEPTANCE.md).
3. Платёжный провайдер, почтовый сервис, вычитка армянских текстов.