Бумажные согласования тянутся неделями. Документы теряются, подписи подделывают, сотрудники тратят время на постоянные напоминания. Мы разрабатываем цифровые workflow согласования, которые заканчивают этот хаос. Наш движок встраивается в сайт или CRM, автоматически направляет документы по заданным маршрутам, контролирует сроки и ведёт полный аудит. Никаких «потерялось в почте» — всё прозрачно в одном окне. За 5 лет мы реализовали 50+ проектов, сократив время согласования в среднем в 3 раза. Подробнее о концепции workflow можно прочитать на Wikipedia.
Проблемы, которые решает workflow согласования
Если руководитель в командировке, процесс останавливается. Наш движок автоматически эскалирует задачу заместителю или переназначает по правилам. Таймауты настраиваются в часах — если ответа нет, система напоминает, а затем передаёт выше. Ручной контроль отнимает часы: сотрудники отслеживают статусы вручную. Мы даём личный кабинет с timeline, где видно каждый шаг: кто, когда и что решил. Инициатор видит прогресс, согласующие — дедлайн. Ошибки и дубли исключаются: workflow жёстко задаёт маршрут с проверкой ролей. В одном проекте мы сократили количество ошибок на 90%. Интеграция с ЭЦП (электронной подписью) реализуется через API подписантов, поддерживаются сертификаты КЭП и НЭП. Переход на электронный документооборот даёт полную прозрачность — это и есть система подписания документов на сайте.
Как мы строим гибкий workflow?
Используем проверенный стек: TypeScript + Node.js (Nest.js) на бэке, React с TypeScript на фронте. Для хранения — PostgreSQL с JSONB для шаблонов шагов. Движок состояний реализован как отдельный микросервис с чёткими транзакциями.
Модель данных — шаблоны workflow, экземпляры для каждого документа и задачи согласования. Каждая задача привязана к шагу, исполнителю и таймауту. JSONB в шаблоне позволяет гибко описывать шаги: тип (последовательный/параллельный), условия перехода, эскалацию.
-- Шаблоны workflow CREATE TABLE workflow_templates ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), name VARCHAR(200), description TEXT, steps JSONB NOT NULL, -- Массив шагов с конфигурацией created_by UUID REFERENCES users(id) ); -- Экземпляр workflow для конкретного документа CREATE TABLE workflow_instances ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), template_id UUID REFERENCES workflow_templates(id), document_id UUID REFERENCES documents(id), initiator_id UUID REFERENCES users(id), current_step INT DEFAULT 1, status VARCHAR(50) DEFAULT 'in_progress', -- in_progress, approved, rejected, cancelled metadata JSONB DEFAULT '{}', created_at TIMESTAMPTZ DEFAULT NOW(), completed_at TIMESTAMPTZ ); -- Задачи согласования CREATE TABLE workflow_tasks ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), instance_id UUID REFERENCES workflow_instances(id), step_number INT NOT NULL, assignee_id UUID REFERENCES users(id), assignee_role VARCHAR(100), -- Альтернатива assignee_id для динамических ролей task_type VARCHAR(50), -- 'approve', 'sign', 'review' status VARCHAR(50) DEFAULT 'pending', -- pending, approved, rejected, delegated comment TEXT, due_at TIMESTAMPTZ, completed_at TIMESTAMPTZ, completed_by_id UUID REFERENCES users(id) -- Если делегировал ); Движок обрабатывает решения: approve — проверяет параллельный шаг (все ли одобрили), затем переходит к следующему шагу или завершает workflow. reject — останавливает процесс или возвращает на доработку. request_changes — отправляет документ инициатору с комментарием.
class WorkflowEngine { async processDecision( taskId: string, decision: 'approve' | 'reject' | 'request_changes', comment: string, userId: string ) { const task = await db.workflowTasks.findOne(taskId, { include: 'instance.template' }); if (task.assigneeId !== userId) throw new Error('Not authorized'); await db.workflowTasks.update(taskId, { status: decision, comment, completedAt: new Date(), }); await auditLog.record({ action: `task.${decision}`, userId, taskId, instanceId: task.instanceId, }); switch (decision) { case 'approve': await this.onTaskApproved(task); break; case 'reject': await this.onTaskRejected(task); break; case 'request_changes': await this.returnToInitiator(task, comment); break; } } private async onTaskApproved(task: WorkflowTask) { const instance = task.instance; const template = JSON.parse(instance.template.steps); const currentStep = template[task.stepNumber - 1]; // Параллельный шаг: проверяем все ли в этом шаге одобрили if (currentStep.type === 'parallel') { const stepTasks = await db.workflowTasks.findAll({ instanceId: instance.id, stepNumber: task.stepNumber, }); const allApproved = stepTasks.every(t => t.status === 'approve'); const anyRejected = stepTasks.some(t => t.status === 'reject'); if (anyRejected) return this.onTaskRejected(task); if (!allApproved) return; // Ждём остальных } // Переходим к следующему шагу const nextStep = template[task.stepNumber]; // Следующий элемент if (!nextStep) { // Все шаги пройдены — workflow завершён await this.completeWorkflow(instance.id); } else { await this.activateStep(instance.id, nextStep, task.stepNumber + 1); } } private async activateStep(instanceId: string, step: WorkflowStep, stepNumber: number) { await db.workflowInstances.update(instanceId, { currentStep: stepNumber }); const assignees = await this.resolveAssignees(step); const dueAt = step.deadlineHours ? addHours(new Date(), step.deadlineHours) : null; for (const assignee of assignees) { const task = await db.workflowTasks.create({ instanceId, stepNumber, assigneeId: assignee.id, taskType: step.taskType, dueAt, }); await notifyAssignee(assignee, task); } } } Как работает делегирование и эскалация?
Согласующий может передать задачу коллеге с комментарием. Система закрывает исходную задачу и создаёт новую для делегата. Все делегирования фиксируются в аудит-логе.
async function delegateTask(taskId, delegateToId, reason, requesterId) { const task = await db.workflowTasks.findByPk(taskId); if (task.assigneeId !== requesterId) throw new Error('Not authorized'); // Закрываем текущую задачу await db.workflowTasks.update(taskId, { status: 'delegated', comment: `Делегировано: ${reason}`, completedAt: new Date(), }); // Создаём новую для делегата await db.workflowTasks.create({ ...task.toJSON(), id: undefined, assigneeId: delegateToId, status: 'pending', completedAt: null, metadata: { delegatedFrom: task.assigneeId, reason }, }); await notifyDelegate(delegateToId, taskId); } Таймауты проверяются кроном каждый час. Если задача просрочена — отправляется уведомление согласующему и эскалация руководителю. Можно настроить автоматическое одобрение при просрочке.
// Cron job: проверяем просроченные задачи каждый час async function processOverdueTasks() { const overdueTasks = await db.workflowTasks.findAll({ status: 'pending', dueAt: { lt: new Date() }, escalationSentAt: null, }); for (const task of overdueTasks) { const step = getStepConfig(task); if (step.escalationUserId) { // Уведомляем руководителя await notifyEscalation(step.escalationUserId, task); await db.workflowTasks.update(task.id, { escalationSentAt: new Date() }); } if (step.autoApproveOnTimeout) { await workflowEngine.processDecision(task.id, 'approve', 'Auto-approved on timeout', 'system'); } } } Визуализация прогресса
Инициатор видит timeline workflow: какой шаг выполнен, кто согласовал, кто ещё не ответил, сколько времени ждём. React-компонент с вертикальным списком, иконками статусов (✓, ✗, ⏳) и tooltip'ами с комментариями.
Уведомления
| Событие | Кому | Срочность |
|---|---|---|
| Задача назначена | Согласующий | Немедленно |
| Дедлайн через 4ч | Согласующий | Push + Email |
| Просрочена задача | Согласующий + эскалация | |
| Документ одобрен | Инициатор | In-app + Email |
| Документ отклонён | Инициатор | Немедленно, все каналы |
Почему стоит внедрить workflow на сайте?
Workflow на нашем движке в 3 раза быстрее бумажного документооборота и на 50% эффективнее простых email-уведомлений. Вы получаете прозрачность, контроль и экономию ресурсов. Типовой проект окупается за 3–6 месяцев за счёт сокращения времени сотрудников. Средняя экономия на операционных расходах может достигать существенной суммы. Мы гарантируем качество: 5 лет опыта, сертифицированные инженеры, 12 месяцев поддержки после внедрения.
Что входит в работу?
- Аналитика: изучаем бизнес-процессы, роли и типы документов.
- Проектирование: создаём схему workflow с шагами, условиями и ролями.
- Реализация: разрабатываем движок, интеграцию с хранилищем документов и ЭЦП.
- Интерфейс: личный кабинет инициатора и согласующих.
- Тестирование: покрытие юнит-тестами, нагрузочное тестирование.
- Документация: описание API, инструкции пользователя, администрирование.
- Обучение: вебинар для ключевых пользователей.
- Поддержка: 2 недели бесплатной пост-продакшн поддержки.
Сроки ориентировочно
| Комплектация | Срок |
|---|---|
| Базовый workflow (последовательное согласование, задачи, уведомления) | 7–10 дней |
| Расширенный (параллельное, делегирование, эскалация, таймауты) | 12–17 дней |
| С визуальным конструктором шаблонов | 19–27 дней |
Точные сроки рассчитываем после аудита ваших процессов. Свяжитесь с нами — проведём бесплатный аудит и предложим решение за 1 день. Закажите внедрение и сократите время согласований в 3 раза. Получите консультацию уже сегодня.







