Основные сущности CRM RMS
Это карта доменных сущностей системы: что хранит каждая сущность, через какие API она открывается фронту и как она участвует в проектной работе.
Общая схема
Центр системы — Project. Вокруг него собираются CRM-данные, команда, задачи, файлы, логистика, командировки, финансы, документы, чаты и уведомления.
Company + Contact
↓
Project
├─ Project Team
├─ Tasks + Time Entries
├─ Files + Documents
├─ Equipment Requests + Logistics Operations
├─ Trips
├─ Finance Cost Items + Budget
├─ Project/Task Chats
└─ NotificationsТочные поля, схемы запросов и ответы находятся в Scalar API Reference. Эта страница отвечает за смысловую модель и связи.
Компания (Company)
Компания — клиент или контрагент, с которым связаны проекты, контакты, реквизиты, документы и договоры.
Ключевые связи:
projects.company_id— клиентская сторона проекта;contacts.company_idиcompany_contacts— контактные лица;requisites.owner_type=company— реквизиты компании;contracts.counterparty_type=company— договоры;payments.counterparty_type=company— взаиморасчеты;/api/v1/entities/company/:id/related— навигационный хаб карточки.
Основной API:
GET/POST /api/v1/companies;GET/PUT/DELETE /api/v1/companies/:id;GET /api/v1/companies/:id/card;GET /api/v1/companies/:id/card.pdf.
Списки компаний для не-глобальных пользователей ограничены менеджером компании и его рекурсивными подчиненными.
Контакт (Contact)
Контакт — конкретное лицо клиента или контрагента. Он может быть прямым контактом компании и одновременно иметь M:M-связи с разными компаниями через company_contacts.
Ключевые связи:
projects.contact_id— контактное лицо проекта;company_contacts— роль контакта в компании и признакis_primary;requisites.owner_type=contact— реквизиты физлица/ИП;contracts.counterparty_type=contact— договоры;/api/v1/entities/contact/:id/related— связанные компании и проекты.
Основной API:
GET/POST /api/v1/contacts;GET/PUT/DELETE /api/v1/contacts/:id;GET /api/v1/contacts/:id/companies;GET/POST /api/v1/companies/:id/contacts;PATCH/DELETE /api/v1/companies/:id/contacts/:contact_id.
Правило is_primary: у одной компании может быть только один основной контакт; при назначении нового основной флаг снимается с остальных связей.
Реквизиты (Requisite)
Реквизиты принадлежат компании или контакту через пару owner_type / owner_id.
API:
GET /api/v1/requisites?owner_type=company&owner_id=1;POST /api/v1/requisites;GET/PUT/DELETE /api/v1/requisites/:id;PATCH /api/v1/requisites/:id/set-primary.
Primary-реквизиты используются при генерации счетов, актов, договоров и сметы.
Проект (Project)
Проект — рабочий контейнер, к которому привязаны команда, задачи, бюджет, логистика, файлы и документы.
Ключевые поля:
name,description;company_id,contact_id,location_id;department_id,manager_id;status;event_category;planned_budget,actual_revenue;start_planned,end_planned,start_actual,end_actual;has_approved_spec;is_archived.
Актуальные статусы:
planned -> estimating -> approved -> in_progress -> done -> closed
\-> cancelled| Статус | Смысл |
|---|---|
planned | Карточка создана, вводные собираются |
estimating | Готовятся спецификация, команда и смета |
approved | Проект согласован |
in_progress | Работа идет |
done | Операционная работа завершена |
closed | Проект закрыт, финансы заморожены |
cancelled | Проект отменен |
API:
GET/POST /api/v1/projects;GET/PUT/DELETE /api/v1/projects/:id;PATCH /api/v1/projects/:id/status;GET /api/v1/projects/:id/tasks;GET /api/v1/projects/summary;GET /api/v1/projects/export.
Список проектов: поиск, сортировка, сводка, выгрузка
Экран «Проекты» работает на сервере и не грузит все проекты страницами, чтобы искать и считать у себя.
GET /api/v1/projects— канонический список (items+meta,limitпо умолчанию 50, максимум 200). Кроме фильтров (status— один или несколько через запятую,department_id,manager_id,company_id,location_id,archived,include_archived,profit_min/profit_max) принимает:q— поиск без учёта регистра по подстроке в названии проекта, названии компании и ФИО менеджера (параметризованныйILIKE, символы%и_ищутся как текст; до 200 символов);sort— ключ из белого списка:name,company,manager,end_planned(срок: окончание по плану, иначе по факту),status(порядок воронки),created_at,profit(только с доступом к прибыли, иначе 403).-в начале — по убыванию, пустые значения всегда в конце, по умолчанию-created_at. Неизвестный ключ — 400 с полемsort.
GET /api/v1/projects/summary— плитки экрана по тем же фильтрам,qи охвату видимости (пагинация и сортировка не влияют):total,active(approved,in_progress),due_soon(незавершённые — неdone/closed/lost/cancelled— со сроком от сегодня до сегодня +due_soon_days= 14 включительно; «сегодня» — в часовом поясе компанииAPP_TIMEZONE),planned_budget— сумма плановых бюджетов, только при доступе к бюджету клиента (иначе поля нет). Сводка — отдельный эндпоинт, а не полеmeta:metaсписка остаётся каноническим, а плитки не пересчитываются при листании.GET /api/v1/projects/export— Excel с теми же фильтрами,qиsort(без пагинации). Колонки как на экране: «Проект», «Категория», «Компания», «Менеджер», «Дивизион», «Статус», «Начало», «Срок»; при доступе — «Плановый бюджет, ₽», «Фактическая выручка, ₽», «Вероятность, %», «Прибыль, ₽»; с архивными — «В архиве». Статус и категория подписями, датыДД.ММ.ГГГГв часовом поясе компании, суммы — числовыми ячейками, без внутренних номеров. Денежные колонки — по тем же правам, что иGET /projects.
Сортировки по названию и сроку обслуживают индексы миграции 0146, поиск — триграммные индексы 0084.
Детальный процесс описан в Жизненном цикле проекта.
Спецификация проекта (ProjectSpec)
Спецификация фиксирует версию требований или ТЗ проекта.
API:
POST /api/v1/projects/:id/specs;POST /api/v1/projects/:id/specs/:version/submit;POST /api/v1/projects/:id/specs/:version/approve;POST /api/v1/projects/:id/specs/:version/reject.
Согласование спецификации создает уведомления project_spec.submitted, project_spec.approved и project_spec.rejected. Утвержденная версия выставляет у проекта has_approved_spec=true.
Задача (Task)
Задача — единица работы внутри проекта. У нее есть основной исполнитель, опциональные соисполнители, плановые часы, due date и рабочие сессии. Закрытая рабочая сессия записывается в часы (auto time entry), но не больше 12 часов: сессию, которую забыли остановить, иначе закрывали через месяцы и начисляли тысячи часов одной записью; в ответе паузы или завершения — пояснение hours_note. Дата завершения — completed_at (ставится при переходе в done, снимается при выходе из него).
Ключевые поля:
project_id;creator_id;assignee_id;co_assignee_ids;status;planned_hours,spent_hours;required_time_logging;due_date;active_session_started_at,last_session_duration_seconds,total_session_seconds.
Статусы:
todo -> in_progress -> done
\ \-> blocked -> in_progress
\-> cancelledAPI:
GET/POST /api/v1/tasks;GET/PUT/PATCH/DELETE /api/v1/tasks/:id;PATCH /api/v1/tasks/:id/status;POST /api/v1/tasks/:id/start;POST /api/v1/tasks/:id/pause;POST /api/v1/tasks/:id/finish;GET/POST /api/v1/tasks/:id/comments;GET /api/v1/tasks/export.
Важное правило: done ставится через POST /api/v1/tasks/:id/finish. Прямой PATCH в done возвращает use_finish_endpoint, чтобы закрытие задачи не расходилось с учетом времени.
Запись времени (TimeEntry)
TimeEntry хранит факт времени сотрудника в проекте.
Поля:
project_id;task_id;user_id;entry_date;hours;comment.
API:
POST /api/v1/time-entries/self— текущий пользователь пишет время себе;POST /api/v1/time-entries— менеджер/admin пишет время за пользователя;GET /api/v1/time-entries— список с фильтрами.
Ограничения:
hoursдолжен быть>0и<=24;- пользователь должен быть активным участником команды проекта;
- дата не может выходить за фактические или плановые границы проекта.
Auto time entries создаются задачами при pause и finish. Денежная строка labor в бюджете появляется только если Finance создал cost_item для source_type=time_entry.
Участник команды (ProjectTeamMember)
Участник команды — связь пользователя с проектом и проектной ролью.
Поля:
project_id,user_id;role_in_project— legacy-основная роль;role_codes[]— канонические проектные роли;hourly_rate;is_lead;is_active.
API:
GET /api/v1/project-team?project_id=...;POST /api/v1/project-team;PATCH /api/v1/project-team/:project_id/:user_id;DELETE /api/v1/project-team/:project_id/:user_id;GET /api/v1/project-team/roles;GET /api/v1/projects/:id/team-history.
Проектные роли отличаются от системных RBAC-ролей. Они используются для ответственности внутри проекта и для доступа к секциям вроде Finance, Documents и Logistics.
Заявка в команду (TeamRequest)
Team Request формализует запрос людей из отделов.
Статусы заявки:
draft;pending;approved;rejected;cancelled.
Статусы строки заявки:
pending;assigned;declined.
API:
POST /api/v1/projects/:id/team-requests;GET /api/v1/team-requests/:id;POST /api/v1/team-requests/:id/submit;POST /api/v1/team-requests/:id/approve;POST /api/v1/team-request-items/:id/assign.
При назначении строки (assigned) backend добавляет выбранного сотрудника в проектную команду.
Локация (Location)
Локация — физическая точка для оборудования, логистики и командировок: склад, площадка, офис, город или объект клиента.
API:
GET/POST /api/v1/locations;GET/PUT/DELETE /api/v1/locations/:id.
Важные поля:
type:city,warehouse,venue,office,client_site,other;is_main_warehouse;- адрес, город, координаты;
- контакт, рабочие часы, инструкции по въезду, погрузке и парковке;
is_active.
Удаление поддерживает безопасные query-параметры dry_run и force. Если локация используется, frontend должен сначала показать предупреждения пользователю.
Оборудование (Equipment)
Оборудование — ресурс, который можно зарезервировать, перевезти, купить или арендовать для проекта.
Ключевые поля:
name,category,identifier;location_id,supplier_id,project_id;cost,unit_cost;quantity,unit;condition,is_broken,broken_description;status:available,reserved,in_transit,in_use,maintenance;is_active.
API:
GET/POST /api/v1/equipment;GET/PUT/DELETE /api/v1/equipment/:id;GET /api/v1/equipment/:id/stock.
GET /equipment/:id/stock показывает total, reserved, available и разбивку по локациям. Проектная потребность оформляется не прямым изменением карточки equipment, а через equipment request и логистику.
Заявка на оборудование (EquipmentRequest)
Equipment Request — фасад над логистическими таблицами для маршрута PM -> финансы -> закупки/логистика.
API:
POST /api/v1/projects/:id/equipment-requests;GET /api/v1/equipment-requests;GET /api/v1/equipment-requests/:id;POST /api/v1/equipment-requests/:id/submit;POST /api/v1/equipment-requests/:id/finance/approve|reject;POST /api/v1/equipment-requests/:id/procurement/start|reject;GET /api/v1/equipment-requests/:id/source-options;POST /api/v1/equipment-requests/:id/operation-plan/preview|confirm.
API-статусы фасада: created, under_review, in_progress, in_transit, completed, rejected, cancelled.
Детальный процесс — в Логистическом контуре.
Логистическая операция (LogisticsOperation)
Логистическая операция — конкретный маршрут или исполнение: откуда забираем, куда везем, что везем, кто отвечает, сколько стоит.
Статусы:
request_created;under_review;awaiting_supply;sourced;preparing_shipment;in_transit;delivered;accepted;completed;closed;cancelled;exception.
Финансовые статусы:
amount_missing;pending;approved;rejected;draft.
API:
GET/POST /api/v1/logistics;GET/PATCH/DELETE /api/v1/logistics/:id;POST /api/v1/logistics/:id/confirm;POST /api/v1/logistics/:id/finance/approve|reject;POST /api/v1/logistics/:id/close;POST /api/v1/logistics/shortage-requests;POST /api/v1/logistics/auto-shortage.
После финансового approve или закрытия операция синхронизирует статью Finance с source_type=logistic_operation.
Командировка (Trip)
Командировка связывает сотрудника, проект, маршрут, согласование, плановые и фактические расходы.
Статусы:
planned -> approved -> in_progress -> completed
\-> cancelledAPI:
GET/POST /api/v1/trips;GET/PATCH /api/v1/trips/:id;GET /api/v1/trips/export.
При approved backend может создать подготовительные задачи (transport, accommodation, advance), при completed — задачу expense_report. Расходы пишутся в Finance как source_type=trip.
Суточные: при создании задаётся ставка в день (per_diem_rate, миграция 0180); per_diem_days и per_diem_total считает сервер — календарные дни от плановой даты выезда до возвращения включительно × ставка. Сумма попадает в описание задачи «Выдать аванс и суточные» («Суточные: 3 дн. × 700 ₽ = 2 100 ₽»). Форма командировки запоминает ставку для следующей поездки и прибавляет суточные к плановым расходам, пока плановые расходы не введены вручную.
Статья затрат (CostItem)
Cost Item — финансовая строка проекта.
Категории: tech, logistics, travel, labor, rent, salary, contractors, materials, creative, office, other, taxes.
API:
POST /api/v1/finance/cost-items;GET /api/v1/finance/cost-items?project_id=...;GET /api/v1/finance/projects/:id/cost-items;GET /api/v1/finance/projects/:id/summary;GET /api/v1/projects/:id/budget.
Budget summary агрегирует именно эти строки. Подробнее — в Системе бюджета.
Файл (File)
File — загруженный файл, привязанный к сущности: проекту, задаче, чату или папке.
API:
GET/POST /api/v1/files;GET/DELETE /api/v1/files/:id;GET /api/v1/files/:id/download;GET /api/v1/files/:id/preview;GET/POST /api/v1/projects/:id/files;GET/POST /api/v1/tasks/:id/files;POST /api/v1/tasks/:id/files/from-chat;GET /api/v1/projects/:id/folders;GET/POST /api/v1/folders/:id/files.
Хранилище работает через local filesystem или S3-compatible backend. Исполняемые файлы и исполняемые MIME-типы запрещены.
Документ (Document)
Document — формальный артефакт, чаще всего сгенерированный из проектных данных: смета, счет, договор, акт.
Статусы:
draft -> issued -> paid
\-> acted
\-> cancelledAPI:
POST /api/v1/projects/:id/documents/estimate;POST /api/v1/projects/:id/documents/invoice;POST /api/v1/projects/:id/documents/contract;POST /api/v1/projects/:id/documents/act;GET /api/v1/documents/:id/download;PATCH /api/v1/documents/:id/status;GET/POST/PUT /api/v1/document-templates....
Документ может создавать файл, участвовать во взаиморасчетах и быть привязан к юридическому договору.
Чат (Chat)
Chat хранит коммуникации.
Типы:
direct;group;project;task.
API:
GET/POST /api/v1/chats;GET /api/v1/chats/:id/messages;POST /api/v1/chats/:id/messages;POST /api/v1/tasks/:id/chat/messages;POST /api/v1/messages/:id/reactions;POST /api/v1/messages/:id/forward;/ws/chat.
Project/task-чаты создаются бизнес-логикой, direct/group — пользователями.
Уведомление (Notification)
Notification — персональное событие для notification center и realtime badge.
Каналы:
in_app;email.
API:
GET /api/v1/notifications;GET /api/v1/notifications/unread-count;POST /api/v1/notifications/:id/read;POST /api/v1/notifications/read-all;DELETE /api/v1/notifications/:id;/ws/notifications.
Email отправляет отдельный notifications-worker через outbox notification_deliveries.
Пользователь, отдел и RBAC
Пользователь имеет:
- primary role в
users.role; - полный набор RBAC-ролей в
user_roles; - персональные overrides в
user_permissions; - primary department и список отделов;
- прямого руководителя
manager_id; - должность
position_id, которая может назначать default-роли.
Оргструктура и доступы открываются через:
/api/v1/users...;/api/v1/departments...;/api/v1/org...;/api/v1/rbac....
Подробнее — Security & RBAC и Оргструктура и админский UI.
Резюме связей
Company
├─ Contacts
├─ Requisites
├─ Contracts
└─ Projects
Project
├─ Specs
├─ Team Members
├─ Team Requests
├─ Tasks
│ ├─ Work Sessions
│ ├─ Time Entries
│ ├─ Files
│ └─ Task Chat
├─ Equipment Requests
│ └─ Logistics Operations
├─ Trips
├─ Finance Cost Items
│ └─ Budget Summary
├─ Documents
├─ Project Chat
└─ Notifications