DOC-SPC-003. As-built реализация CRM_14¶
Документ актуализирован по фактической реализации в каталогах backend/ и frontend/. Остальные разделы docs/ описывают требования и проектные решения; этот документ — «как реализовано на самом деле» (as-built) и является источником правды о текущем коде.
Статусы в документе:
- Реализовано — подтверждено кодом backend/frontend.
- Частично реализовано — есть код, но не весь заявленный сценарий или требуется внешний контур.
- Не реализовано — подтверждения в коде не найдено.
- Требует проверки — код есть, но без проверки внешней среды нельзя подтвердить рабочий сценарий.
- Заглушка / mock — используется упрощенная или временная реализация.
1. Общее описание проекта¶
CRM_14 — учебная MVP CRM-система для работы с лидами, стадиями воронки продаж и базовой аналитикой. Проект разделен на два основных приложения:
backend/— API на FastAPI с clean-architecture разбиением на domain/application/infrastructure/interface.frontend/— SPA на React/Vite с выбором роли, таблицей лидов, канбаном, отчетами и очередью возвратов.
Фактическая реализация не является production CRM. Авторизация упрощена до выбора роли в сессии, данные могут храниться в PostgreSQL, in-memory репозитории или через 1С-адаптер.
2. Назначение системы¶
Система реализует базовый контур управления лидами:
- создание лидов;
- просмотр списка лидов с учетом роли;
- фильтрацию лидов по владельцу, источнику и периоду создания;
- отображение лидов в таблице и канбане;
- перевод лидов по стадиям воронки;
- фиксацию истории стадий;
- комментарии к смене стадии;
- запрос возврата лида на предыдущую стадию;
- рассмотрение возвратов руководителем отдела продаж;
- расчет базовых метрик воронки;
- импорт лидов из CSV/XLSX;
- экспорт лидов в CSV/XLSX;
- аудит ключевых действий.
3. Реализованный функционал¶
Реализовано:
- выбор роли через backend-сессию;
- разграничение возможностей по ролям на backend и частично в UI;
- CRUD-контур лидов: создание, чтение, обновление, удаление;
- список лидов с фильтрами
owner,source_code,date_from,date_to,limit,offset; - таблица лидов;
- канбан по стадиям;
- ручная смена стадии;
- возврат на предыдущую стадию через заявку менеджера и решение РОП;
- история стадий лида;
- один комментарий на событие стадии;
- импорт CSV/XLSX;
- экспорт CSV/XLSX;
- отчет
/reports/summary; - audit log для основных мутаций.
Частично реализовано:
- интеграция с 1С: реализован HTTP-адаптер
OneCRepository; проверена на локальном 1С standalone-сервере (ibsrv) в демо-контуре (STORAGE_MODE=1c); промышленный 1С-сервис не подключался; - история изменений: сохраняются события стадий, комментарии, заявки возврата и audit log, но нет отдельной универсальной истории изменения каждого поля лида;
- дата создания лида: отдельного поля
created_atв таблицеleadsнет, frontend/API выводят дату создания как время первой записи стадииnew; - экспорт отчетности: отдельного endpoint экспорта отчета нет, но XLSX-экспорт лидов содержит лист "Аналитика" с метриками и графиками.
Не реализовано:
- полноценная регистрация/логин/пароли/JWT;
- роль администратора;
- справочники и экран настроек;
- текстовый поиск по лидам;
- JSON-импорт;
- golden-файл и автоматическая сверка
golden/funnel.csv; - телефония, почта, чат-боты;
- production-интеграции с внешними CRM/ERP/BI.
4. Роли пользователей¶
В коде есть четыре роли приложения:
| Роль | Название в UI | Назначение |
|---|---|---|
manager_1 |
Менеджер 1 | Операционная работа только со своими лидами |
manager_2 |
Менеджер 2 | Операционная работа только со своими лидами |
sales_head |
Руководитель отдела продаж | Управление всеми лидами, возвратами, отчетами и аудитом |
analyst |
Аналитик | Просмотр всех лидов, отчетов и экспорт без редактирования |
Enum владельцев лидов Users содержит manager_1, manager_2, sales_head. analyst не может быть владельцем лида или автором комментария.
Отдельной роли admin в backend/frontend не найдено.
5. Функционал по ролям¶
5.1 Администратор¶
Не реализовано.
В коде не найдено роли администратора, отдельного admin-экрана, управления пользователями, справочниками или системными настройками.
Часть административных возможностей фактически выполняет sales_head: видит все лиды, редактирует, удаляет, экспортирует, смотрит отчеты и audit log.
5.2 Менеджер¶
Роли manager_1 и manager_2 реализованы одинаково.
Реализовано:
- выбор роли на стартовом экране;
- просмотр только своих лидов;
- создание лида;
- импорт лидов CSV/XLSX, при котором owner назначается текущим менеджером;
- перевод своих лидов вперед по цепочке:
- запрос возврата на предыдущую стадию, если лид не в
new; - просмотр истории и карточки своих лидов.
Ограничения:
- менеджер не может редактировать произвольные поля существующего лида через PATCH;
- менеджер не может удалить лид;
- менеджер не может экспортировать лиды;
- менеджер не может смотреть отчеты;
- менеджер не может видеть чужие лиды;
- менеджер не может сам вернуть лид назад без заявки и одобрения РОП.
5.3 Руководитель¶
Роль sales_head реализована как расширенная управленческая роль.
Реализовано:
- просмотр всех лидов;
- создание лида с выбором владельца;
- импорт CSV/XLSX;
- экспорт CSV/XLSX;
- редактирование владельца, названия и заметок лида;
- удаление лидов;
- произвольная смена стадии, включая закрытые стадии;
- просмотр отчетов;
- просмотр audit log через API;
- просмотр и обработка заявок на возврат;
- одобрение возврата с фактическим перемещением лида на предыдущую стадию;
- отклонение возврата без смены стадии.
Ограничения:
- РОП не создает заявки на возврат, он рассматривает заявки менеджеров;
- полноценного управления пользователями нет.
5.4 Аналитик¶
Роль analyst реализована как read-only роль для аналитики.
Реализовано:
- просмотр всех лидов;
- просмотр таблицы и канбана;
- просмотр истории лида;
- просмотр отчета
/reports; - экспорт CSV/XLSX.
Ограничения:
- аналитик не создает лиды;
- не импортирует лиды;
- не редактирует и не удаляет лиды;
- не меняет стадии;
- не рассматривает возвраты;
- не имеет доступа к отдельному endpoint
/audit-log.
Важно: при открытии карточки лида backend возвращает audit_entries внутри LeadDetailResponse, если пользователь имеет доступ к самому лиду. Это отличается от отдельного endpoint /audit-log, который разрешен только РОП.
6. Функционал по экранам¶
6.1 Главная страница / Dashboard¶
Реализовано как экран выбора роли.
Маршрут / показывает стартовую страницу CRM 14 с кнопкой "Выбрать роль". После выбора роли frontend вызывает:
Если сессия уже активна, пользователь перенаправляется на /leads/table.
Отдельный полноценный dashboard как стартовая панель с KPI не реализован. Аналитика вынесена на экран /reports.
6.2 Канбан лидов¶
Реализовано.
Маршрут:
Канбан строит колонки по стадиям:
new;qualified;proposal;won;lost.
Карточка лида показывает UID, владельца, название, заметки, источник, кнопку истории и для менеджеров кнопку возврата. Для РОП есть удаление карточки. Drag-and-drop реализован через HTML5 dataTransfer; перед фактическим перемещением вызывается backend endpoint смены стадии.
Ограничения по ролям:
- аналитик не может перемещать карточки;
- менеджер может перемещать только вперед по разрешенным переходам;
- РОП может перемещать в любую другую стадию.
6.3 Список лидов¶
Реализовано.
Маршрут:
Таблица показывает:
lead_uid;- название;
- описание/заметки;
- источник;
- текущую стадию;
- владельца, если роль может видеть всех лидов;
- действия по роли.
Для ролей с can_read_all_leads доступна панель фильтров:
- владелец;
- источник;
- дата с;
- дата по.
Текстовый поиск и сортировка колонок в UI не реализованы.
6.4 Карточка лида¶
Реализована как модальная панель истории.
Отдельного маршрута вида /leads/:id нет. Карточка открывается модально из таблицы или канбана и загружает:
Панель показывает:
- владельца;
- источник;
- текущую стадию;
- дату создания, рассчитанную из первой стадии
new; - историю стадий;
- комментарии к стадиям;
- заявки на возврат;
- audit log по лиду.
6.5 Форма создания / редактирования лида¶
Реализовано.
Компонент LeadFormModal.jsx используется для создания и редактирования.
Поля формы:
- название;
- комментарий/заметки;
- источник;
- владелец, если текущая роль может управлять owner.
Создание вызывает:
Редактирование вызывает:
Требует проверки / устаревший код: frontend/src/components/AddLeadModal.jsx существует, но не импортируется и не используется текущими маршрутами. Его нельзя считать активной частью интерфейса.
6.6 Отчёт / Воронка продаж¶
Реализовано.
Маршрут:
Доступен ролям analyst и sales_head.
Экран вызывает:
Показывает:
- общее количество лидов;
- количество лидов по текущим стадиям;
- конверсии между стадиями;
- среднюю длительность стадий в часах и секундах.
Фильтры:
- владелец;
- источник;
- дата с;
- дата по.
На экране также есть экспорт CSV/XLSX, но он выгружает лиды через /leads/export, а не отдельный отчетный endpoint.
6.7 Настройки / справочники¶
Не реализовано.
В frontend нет маршрута настроек и нет UI для редактирования справочников стадий, источников, ролей или пользователей. Стадии, источники и роли зафиксированы enum-ами в backend и массивами опций во frontend.
7. Backend¶
7.1 Структура backend¶
Фактическая структура:
backend/
app/
main.py
core/
auth.py
config.py
deps.py
errors.py
logging.py
domain/
entities.py
enums.py
rules.py
application/
ports.py
dtos.py
use_cases/
infrastructure/
memo/
sql/
onec/
interface/
api/
schemas.py
v1/
alembic/
tests/
pyproject.toml
Makefile
Dockerfile
Стек backend:
- Python
>=3.12; - FastAPI;
- Uvicorn;
- Pydantic v2;
- pydantic-settings;
- SQLAlchemy async;
- asyncpg;
- Alembic;
- Starlette SessionMiddleware;
- python-multipart для upload;
- xlsxwriter для Excel-экспорта;
- requests для 1С HTTP-адаптера;
- pytest/httpx для тестов.
7.2 Основные сущности¶
Доменные сущности:
| Сущность | Назначение |
|---|---|
Lead |
Основная карточка лида |
LeadStageEvent |
Событие пребывания лида на стадии |
LeadComment |
Комментарий к событию стадии |
StageReturnRequest |
Заявка менеджера на возврат стадии |
AuditLogEntry |
Запись аудита действия |
Поля Lead:
id;lead_uid;source_code;current_stage;owner;title;notes.
Поля LeadStageEvent:
id;lead_id;stage;entered_at;left_at;approved.
Поля StageReturnRequest:
id;lead_id;from_stage;to_stage;requested_by;request_comment;requested_at;status;reviewed_by;review_comment;reviewed_at.
Enum-ы:
| Enum | Значения |
|---|---|
LeadStage |
new, qualified, proposal, won, lost |
SourcesCode |
advertisement, website, recommendation, event, other |
Users |
manager_1, manager_2, sales_head |
AppRole |
manager_1, manager_2, sales_head, analyst |
ReturnRequestStatus |
pending, approved, rejected |
PostgreSQL-таблицы по SQLAlchemy/Alembic:
leads;leads_stage;leads_comments;stage_return_requests;audit_log.
7.3 API endpoints¶
Все endpoint-ы имеют prefix /api/v1.
| Метод | Endpoint | Назначение | Доступ |
|---|---|---|---|
GET |
/health |
Проверка API и storage mode | Без роли |
POST |
/session/role |
Выбрать роль | Без роли |
GET |
/session/me |
Получить текущую роль | Нужна сессия |
DELETE |
/session/role |
Очистить роль | Без роли |
GET |
/leads |
Список лидов | Все роли после выбора роли |
POST |
/leads |
Создать лид | Менеджеры, РОП |
POST |
/new-lead |
Legacy endpoint создания | Менеджеры, РОП |
GET |
/leads/{lead_uid} |
Детальная карточка | С учетом видимости |
PATCH |
/leads/{lead_uid} |
Обновить owner/title/notes | РОП |
DELETE |
/leads/{lead_uid} |
Удалить лид | РОП |
POST |
/leads/{lead_uid}/stage |
Сменить стадию | Менеджер по правилам, РОП произвольно |
GET |
/leads/{lead_uid}/stage |
История стадий | С учетом видимости |
GET |
/leads/{lead_uid}/stages |
Alias истории стадий | С учетом видимости |
POST |
/leads/import |
Импорт CSV/XLSX | Менеджеры, РОП |
GET |
/leads/export |
Экспорт CSV/XLSX | РОП, аналитик |
POST |
/leads/{lead_uid}/return-requests |
Создать заявку возврата | Только менеджеры для своих лидов |
GET |
/return-requests |
Список заявок | РОП |
POST |
/return-requests/{request_id}/approve |
Одобрить возврат | РОП |
POST |
/return-requests/{request_id}/reject |
Отклонить возврат | РОП |
GET |
/reports/summary |
Метрики воронки | РОП, аналитик |
GET |
/audit-log |
Общий audit log | РОП |
Параметры /leads:
owner;stage;source_code;date_from;date_to;limitот 1 до 200;offsetот 0.
Параметры /leads/export:
file_type:csv,scvилиxlsx; значениеscvподдержано как alias/опечатка;owner.
7.4 Бизнес-логика¶
Создание лида:
lead_uidгенерируется автоматически;- длина UID — 5 символов;
- алфавит — ASCII letters + digits;
- при конфликте генерация повторяется до 20 попыток;
- новый лид всегда создается в стадии
new; - одновременно создается открытое событие стадии
new.
Смена стадии:
- при переходе закрывается текущее открытое событие стадии через
left_at; - создается новое событие стадии с
entered_at; current_stageобновляется вleads;- комментарий сохраняется только если передан.
Правила менеджера:
- менеджер работает только со своими лидами;
- менеджер может двигаться только вперед:
- из
wonиlostменеджер не может двигать лид дальше; - возврат назад выполняется только через заявку.
Правила РОП:
- видит все лиды;
- может менять стадию на любую другую;
- может вернуть закрытый лид из
won/lostна другую стадию; - рассматривает заявки возврата.
Возврат стадии:
- менеджер создает заявку с обязательным комментарием;
- target stage определяется автоматически через
resolve_previous_stage; - нельзя создать вторую pending-заявку по тому же лиду;
- РОП одобряет или отклоняет заявку с обязательным комментарием;
- при одобрении backend проверяет, что текущая стадия лида не изменилась с момента заявки;
- при одобрении лид перемещается на предыдущую стадию;
- при отклонении стадия не меняется.
7.5 Валидации¶
Реализовано:
- Pydantic enum-валидация ролей, стадий, владельцев, источников;
titleограниченmax_length=255;LeadUpdateRequestтребует хотя бы одно поле;ownerпри обновлении не может бытьnull;- комментарий заявки возврата обязателен и
min_length=1; - комментарий решения по возврату обязателен и
min_length=1; limitограничен диапазоном1..200;offset >= 0;- импорт проверяет наличие колонок
owner,title,notes,source_code, кроме случая менеджера, когдаownerможет быть подставлен автоматически; - импорт проверяет enum-значения через Pydantic;
- CSV декодируется как
utf-8-sig,utf-8илиcp1251; - CSV допускает разделители
;и,; - XLSX читается из первой worksheet.
Ограничения:
- импорт не принимает
lead_uid,current_stage,entered_at,left_at; - повторный импорт одного и того же файла создаст новые лиды с новыми UID, то есть идемпотентность по
lead_uidне реализована; - нет проверки lost reason;
- нет отдельной валидации дат истории при импорте, потому что история стадий не импортируется.
7.6 Обработка ошибок¶
Backend регистрирует обработчики:
AppErrorвозвращает JSON{"detail": ...}со статусом конкретного исключения;NotImplementedErrorвозвращает 501;- прочие исключения возвращают 500.
Основные статусы:
- 400 — общая ошибка приложения или недопустимый переход;
- 401 — роль в сессии отсутствует или некорректна;
- 403 — действие запрещено текущей роли;
- 404 — лид или заявка не найдены;
- 409 — конфликт, например pending-заявка уже существует или UID занят;
- 422 — ошибки FastAPI/Pydantic или ошибки импорта.
Frontend показывает ошибки через error-banner и сообщения из detail.
7.7 Импорт и экспорт данных¶
Импорт:
Поддерживается:
.csv;.xlsx.
Ожидаемые поля:
owner;title;notes;source_code.
Для менеджера owner может отсутствовать: backend назначит владельцем текущего менеджера. Для РОП owner должен быть указан в файле.
JSON-импорт не реализован.
Экспорт:
CSV содержит колонки:
lead_uid;title;notes;owner;stage;entered_at;source_code.
XLSX содержит:
- лист
Аналитика; - лист
Данные; - метрики;
- таблицы по стадиям, источникам, менеджерам;
- графики воронки, длительности, конверсии по источникам и нагрузки менеджеров.
7.8 Расчёт KPI и метрик¶
Endpoint:
Параметры:
owner;source_code;date_from;date_to.
Метрики:
total_leads;counts— количество лидов по текущей стадии;conversions— конверсии:new -> qualified;qualified -> proposal;proposal -> won;proposal -> lost;average_stage_durations— средняя длительность стадии в секундах и часах.
Особенность расчета:
- для фильтра периода используется дата создания, полученная из первого события
new; - для длительности открытых стадий используется разница между текущим временем и
entered_at; - conversion rate в
/reports/summaryвозвращается в процентах, округленных до 2 знаков.
XLSX-экспорт дополнительно считает:
- общую конверсию в
won; - долю
lost; - неподтвержденные переходы;
- зависшие лиды в активных стадиях больше 3 дней;
- конверсию
wonпо источникам; - количество лидов по менеджерам;
- среднюю длительность по менеджерам;
- активную нагрузку менеджеров.
8. Frontend¶
8.1 Структура frontend¶
Фактическая структура:
frontend/
src/
App.jsx
main.jsx
auth/
SessionProvider.jsx
components/
HomePage.jsx
LeadsPage.jsx
LeadsTable.jsx
LeadsKanban.jsx
LeadFormModal.jsx
ImportModal.jsx
LeadHistoryModal.jsx
ReportsPage.jsx
RequestsPage.jsx
AddLeadModal.jsx
lib/
leadsApi.js
ui.js
Стек frontend:
- React 19;
- React DOM 19;
- Vite 7;
- react-router-dom 7;
- plain CSS.
8.2 Страницы¶
Маршруты:
| Route | Компонент | Доступ |
|---|---|---|
/ |
HomePage |
Без роли |
/leads/table |
LeadsPage + LeadsTable |
Все выбранные роли |
/leads/kanban |
LeadsPage + LeadsKanban |
Все выбранные роли |
/leads |
Redirect на /leads/table |
Все выбранные роли |
/reports |
ReportsPage |
analyst, sales_head |
/requests |
RequestsPage |
sales_head |
* |
Redirect на / |
Все |
8.3 Компоненты¶
Активные компоненты:
SessionProvider— загружает сессию, выбирает роль, очищает сессию;HomePage— стартовый экран выбора роли;LeadsPage— контейнер таблицы/канбана, фильтры, импорт, экспорт, мутации;LeadsTable— табличное представление лидов;LeadsKanban— канбан по стадиям;LeadFormModal— создание/редактирование лида;ImportModal— загрузка CSV/XLSX;LeadHistoryModal— карточка лида, история, возвраты, audit entries;ReportsPage— отчет по воронке;RequestsPage— очередь возвратов для РОП.
Неиспользуемый компонент:
AddLeadModal.jsx— найден вfrontend/src/components, но не импортируется текущими экранами.
8.4 Работа с API¶
Все вызовы API собраны в frontend/src/lib/leadsApi.js.
Базовый URL:
Если переменная окружения не задана, используется fallback http://127.0.0.1:8000/api/v1.
Запросы выполняются через fetch с:
Это нужно для cookie-сессии mini_crm_session.
Frontend API-клиент реализует:
fetchSession;selectRole;clearSession;fetchLeads;fetchLeadDetail;createLead;updateLead;deleteLead;moveLeadStage;requestReturnToPreviousStage;fetchReturnRequests;approveReturnRequest;rejectReturnRequest;fetchReportsSummary;fetchAuditLog;importLeads;exportLeads.
fetchAuditLog есть в API-клиенте, но отдельного экрана общего audit log во frontend не найдено.
8.5 Состояния интерфейса¶
Реализовано:
- состояние загрузки сессии;
- protected routes;
- redirect при отсутствии роли;
- redirect при отсутствии доступа к маршруту;
- загрузка списка лидов;
- состояние мутации
isMutating; - error banner;
- loading panels для лидов, отчетов и заявок;
- пустые состояния таблицы, канбана и очереди возвратов;
- модальные состояния формы, импорта и истории.
Ограничения:
- комментарий к смене стадии вводится через
window.prompt, не через полноценную форму; - подтверждение удаления через
window.confirm; - нет глобального toast/notification слоя;
- нет сохранения фильтров в URL или localStorage.
8.6 Формы, таблицы, канбан¶
Формы:
- выбор роли;
- создание/редактирование лида;
- импорт файла;
- комментарий РОП к approve/reject возврата;
- prompt-комментарий к смене стадии;
- prompt-комментарий к заявке возврата.
Таблицы:
- таблица лидов;
- таблица конверсий;
- таблица средней длительности стадий.
Канбан:
- группировка по
current_stage; - счетчик лидов в колонке;
- drag-and-drop смена стадии;
- отображение доступных переходов;
- блокировка перемещения для аналитика.
9. Данные и модели¶
Основная модель данных строится вокруг лида и истории стадий.
leads:
- хранит текущую карточку и текущую стадию;
- не хранит
created_at; - не хранит сумму сделки, телефон, email, lost reason.
leads_stage:
- хранит историю стадий;
- текущее событие имеет
left_at = null; - содержит флаг
approved, но текущая логика создает stage events сapproved=True.
leads_comments:
- привязана к stage event;
- уникальность по
stage_event_id; - фактически один комментарий на событие.
stage_return_requests:
- хранит управляемый процесс возврата стадии.
audit_log:
- хранит события действий с
actor_role,action_type, JSON payload и временем.
10. KPI и аналитика¶
Реализовано в API и UI:
- количество лидов всего;
- количество лидов по стадиям;
- конверсия между основными переходами;
- средняя длительность стадий.
Реализовано в XLSX-экспорте:
- воронка продаж;
- средняя длительность стадий в днях;
- конверсия по источникам;
- лиды по менеджерам;
- средняя длительность по менеджеру;
- нагрузка менеджеров по активным стадиям;
- количество зависших лидов больше 3 дней;
- графики.
Не реализовано:
- отдельный экран с графиками;
- сравнение с
golden/funnel.csv; - прогнозирование продаж;
- когортный анализ;
- причины отказов.
11. История изменений и логирование¶
История стадий реализована через leads_stage:
- при создании лида создается стадия
new; - при переходе закрывается предыдущая стадия и создается новая;
- история доступна через
/leads/{lead_uid}/stageи/leads/{lead_uid}/stages; - детальная карточка лида включает
stage_info.
Комментарии:
- сохраняются к новой стадии при смене стадии, если передан
comment; - при approve возврата комментарий РОП сохраняется как комментарий к stage event.
Audit log реализован для действий:
lead_created;lead_created_legacy;lead_imported;lead_deleted;lead_updated;lead_stage_changed;return_request_created;return_request_approved;return_request_rejected.
Отдельный общий endpoint /audit-log доступен РОП. Детальная карточка лида также возвращает последние audit entries по конкретному лиду.
12. Интеграции и моки¶
Режимы хранения задаются STORAGE_MODE:
postgres— PostgreSQL через SQLAlchemy async;memo— in-memory репозиторий для тестов/демо;1c— HTTP-адаптер к 1С.
PostgreSQL:
- основная persist-реализация;
- миграция Alembic создает таблицы и enum-ы.
Memo:
- хранит данные в памяти процесса;
- используется в smoke-тестах;
- данные пропадают после перезапуска.
1С:
- в коде есть
OneCRepository, который читает/пишет лиды через HTTP endpoints/leads; - локально хранит синтетические stage events, comments, return requests и audit entries;
- удаление лидов через 1С-адаптер не поддержано;
- проверена на локальном 1С standalone-сервере (
ibsrv) в демо-контуре; промышленный 1С-сервис не подключался.
REST-моки как отдельные mock endpoints не найдены. Режим memo можно использовать как демонстрационное in-memory хранилище, но это не отдельный REST-mock слой.
13. Ограничения текущей реализации¶
- Упрощенная авторизация: роль выбирается пользователем вручную.
- Нет пользователей, паролей, регистрации и JWT.
- Session cookie используется для хранения роли.
- CORS в
app.mainфактически разрешен черезallow_origin_regex=".*", несмотря на наличие настройкиCORS_ALLOWED_ORIGINS. - Нет роли администратора.
- Нет справочников и настроек.
- Нет текстового поиска.
- Нет импорта истории стадий.
- Нет JSON-импорта.
- Импорт не идемпотентен по
lead_uid. - Нет отдельного
created_atу лида в БД. - Нет суммы сделки и финансовых полей.
- Нет контактных данных клиента.
- Нет причины проигрыша
lost_reason. - Нет полноценного журнала изменения всех полей.
AddLeadModal.jsxне используется.- Frontend не содержит отдельного экрана общего audit log.
- 1С-интеграция проверена на локальном учебном 1С-сервере (
ibsrv); промышленный 1С-контур не подключался.
14. Нереализованный функционал¶
Функция описана в исходной документации, но в текущей реализации не обнаружена:
- администратор;
- управление пользователями;
- редактирование справочников;
- JSON-импорт;
- импорт истории стадий из отдельного файла;
- идемпотентная повторная загрузка по
lead_uid; - golden-сверка;
- экспорт отдельного отчета с колонками
stage,leads_cnt,conv_from_prev; - текстовый поиск;
- сортировка колонок в таблице;
- отдельная карточка лида как маршрут;
- полноценный dashboard на главной странице;
- реальные коммуникационные интеграции;
- работа с персональными данными клиента;
- сделки, счета, документы продаж.
15. Функционал в разработке¶
Явных feature flags или TODO-статусов в коде для функций "в разработке" не найдено. По структуре проекта можно считать требующими дальнейшей доработки:
- 1С-адаптер и проверка реального обмена;
- импорт с поддержкой
lead_uidи идемпотентности; - экран общего audit log;
- удаление устаревшего
AddLeadModal.jsxили его приведение к текущему API; - синхронизация документации
docs/с текущими файламиPROJECT_DOCUMENTATION.mdиDOCUMENTATION_AUDIT.md.
16. Инструкция запуска проекта¶
16.1 Запуск backend¶
Требования:
- Python 3.12+;
uv;- PostgreSQL, если используется
STORAGE_MODE=postgres.
Команды:
API:
Swagger:
ReDoc:
Проверки:
16.2 Запуск frontend¶
Требования:
- Node.js;
- npm.
Команды:
Frontend по умолчанию запускается Vite dev server на:
Сборка:
16.3 Переменные окружения¶
Backend .env.example:
STORAGE_MODE=postgres
DATABASE_URL=postgresql+asyncpg://postgres:postgres@127.0.0.1:5432/mini_crm_simple
LOG_LEVEL=INFO
SESSION_SECRET=mini-crm-simple-dev-secret
CORS_ALLOWED_ORIGINS=http://127.0.0.1:5173,http://localhost:5173
SESSION_HTTPS_ONLY=false
Frontend .env.example:
Docker Compose из корня проекта поднимает:
postgres;backend;frontend.
Команда:
Особенность: backend/docker-compose.yml отдельно запускает только backend и по умолчанию использует STORAGE_MODE=memo.
17. Сценарий демонстрации¶
Рекомендуемый сценарий, соответствующий текущей реализации:
- Запустить backend и frontend.
- Открыть
/. - Выбрать роль
manager_1. - Создать лид через "Добавить лид".
- Показать, что лид появился в таблице в стадии
new. - Перейти в канбан и показать карточку в колонке
Новый. - Перевести лид в
qualifiedс комментарием. - Открыть "История" и показать стадии, дату создания и комментарий.
- Создать заявку на возврат.
- Сменить роль на
sales_head. - Открыть "Запросы" и одобрить заявку с комментарием.
- Вернуться к лиду и показать, что стадия изменилась назад.
- Открыть "Отчёты" и показать counts, conversions, average durations.
- Выполнить экспорт CSV и XLSX.
- Сменить роль на
analystи показать read-only доступ к лидам/канбану/отчетам.
18. Acceptance-критерии текущей реализации¶
| ID | Критерий | Статус |
|---|---|---|
| AC-01 | Пользователь выбирает роль и попадает в интерфейс | Реализовано |
| AC-02 | Менеджер видит только свои лиды | Реализовано |
| AC-03 | Менеджер создает лид в стадии new |
Реализовано |
| AC-04 | История стадии new создается вместе с лидом |
Реализовано |
| AC-05 | Менеджер переводит new -> qualified |
Реализовано |
| AC-06 | Менеджер переводит qualified -> proposal |
Реализовано |
| AC-07 | Менеджер переводит proposal -> won/lost |
Реализовано |
| AC-08 | Менеджер не возвращает стадию напрямую | Реализовано |
| AC-09 | Менеджер создает заявку возврата | Реализовано |
| AC-10 | РОП одобряет возврат | Реализовано |
| AC-11 | РОП отклоняет возврат | Реализовано |
| AC-12 | Аналитик видит лиды и отчеты без редактирования | Реализовано |
| AC-13 | Импорт CSV/XLSX создает лиды | Реализовано |
| AC-14 | Повторный импорт не создает дубли по lead_uid |
Не реализовано |
| AC-15 | Экспорт CSV формируется | Реализовано |
| AC-16 | Экспорт XLSX формируется с аналитикой и данными | Реализовано |
| AC-17 | Отчет показывает конверсии | Реализовано |
| AC-18 | Отчет показывает среднюю длительность стадий | Реализовано |
| AC-19 | Сверка с golden-файлом | Не реализовано |
| AC-20 | Администратор управляет справочниками | Не реализовано |
19. Краткий вывод¶
Текущая CRM_14 реализует рабочий учебный контур лидов, ролей, стадий, возвратов, импорта, экспорта и базовой аналитики. Реализация заметно шире простого REST-мока: есть backend API, ролевая матрица, PostgreSQL-модель, in-memory режим, 1С-адаптер, frontend-экраны и smoke-тесты.
Главные ограничения перед защитой: отсутствие полноценной авторизации, администратора, справочников, поиска, JSON-импорта, golden-сверки и идемпотентности импорта по lead_uid. Эти ограничения нужно явно проговаривать как границы текущего MVP, а не как реализованные функции.