Дата: 2025-11-10
Версия: 1.0.0
Цель: Полная система описания бизнес-процессов
# order_fulfillment.cifra
process:
id: OrderFulfillment
name: "Обработка заказа"
type: business_process
# Участники процесса
participants:
- warehouse_team
- customer_service
- delivery_service
# Входные данные
input:
order_id: {type: uuid, required: true}
# Шаги процесса
steps:
- task: CheckStock
type: service
action: call_api
endpoint: /inventory/check/{order_id}
- gateway: StockAvailable?
type: exclusive
branches:
- when: "stock.available == true"
goto: PrepareOrder
- when: "stock.available == false"
goto: NotifyCustomer
- task: PrepareOrder
type: user
assignee: warehouse_team
form: prepare_order_form
- task: ShipOrder
type: service
action: call_api
endpoint: /shipping/create
# Обработка ошибок
error_handlers:
- catch: ApiError
retry: 3
fallback: NotifySupport
Использование: Основной бизнес-процесс компании
Пример: Продажа товара
# sales_process.cifra
process:
id: SalesProcess
name: "Процесс продажи"
type: business_process
category: sales
# Цель процесса
goal: "Продать товар клиенту и получить оплату"
# KPI процесса
kpi:
- name: conversion_rate
description: "Процент завершённых продаж"
target: ">= 30%"
- name: average_time
description: "Среднее время закрытия сделки"
target: "<= 14 days"
# Входные данные
input:
lead_id: {type: uuid, required: true}
# Выходные данные
output:
deal_id: {type: uuid}
status: {type: enum, values: [won, lost]}
steps:
- task: QualifyLead
name: "Квалифицировать лид"
type: user
assignee: sales_rep
priority: high
sla: 24h # Должно быть выполнено за 24 часа
- task: CreateProposal
name: "Создать коммерческое предложение"
type: service
action: generate_document
template: proposal_template
data:
lead: "{process.lead}"
products: "{process.selected_products}"
- task: SendProposal
name: "Отправить предложение клиенту"
type: email
to: "{lead.email}"
subject: "Коммерческое предложение"
template: proposal_email
attachments:
- "{previous_task.proposal_document}"
- task: WaitForResponse
name: "Ожидать ответ клиента"
type: wait
timeout: 7d
on_timeout: SendReminder
- gateway: ClientDecision
name: "Решение клиента"
type: exclusive
branches:
- when: "response.accepted == true"
goto: CreateDeal
- when: "response.rejected == true"
goto: MarkAsLost
- when: "response == null" # timeout
goto: SendReminder
- task: CreateDeal
name: "Создать сделку"
type: service
action: create_entity
entity: Deal
data:
lead_id: "{process.lead_id}"
status: won
amount: "{proposal.total}"
- task: SendConfirmation
name: "Отправить подтверждение"
type: email
to: "{lead.email}"
template: deal_confirmation
# Вложенные подпроцессы
subprocesses:
- id: SendReminder
name: "Отправить напоминание"
steps:
- task: EmailReminder
type: email
to: "{lead.email}"
template: reminder_email
- task: WaitAgain
type: wait
timeout: 3d
on_timeout: MarkAsLost
- return_to: WaitForResponse
Использование: Автоматизированный процесс без участия человека
Пример: Обработка платежа
# payment_processing.cifra
process:
id: PaymentProcessing
name: "Обработка платежа"
type: workflow
trigger: automatic # Запускается автоматически
input:
order_id: {type: uuid, required: true}
amount: {type: decimal, required: true}
payment_method: {type: enum, values: [card, bank_transfer, cash]}
steps:
- task: ValidateAmount
type: validation
rules:
- amount > 0
- amount <= order.total
- task: CallPaymentGateway
type: service
action: call_external_api
service: stripe
endpoint: /v1/charges
method: POST
body:
amount: "{process.amount}"
currency: RUB
source: "{order.payment_token}"
timeout: 30s
retry: 3
- gateway: PaymentSuccess?
type: exclusive
branches:
- when: "response.status == 'succeeded'"
goto: UpdateOrderStatus
- when: "response.status == 'failed'"
goto: HandleFailure
- task: UpdateOrderStatus
type: service
action: update_entity
entity: Order
id: "{process.order_id}"
data:
status: paid
paid_at: "{now()}"
payment_id: "{response.id}"
- task: SendReceipt
type: email
to: "{order.customer.email}"
template: payment_receipt
attachments:
- type: pdf
generator: receipt_pdf
data: "{order}"
- task: TriggerFulfillment
type: event
publish: orders.paid
data:
order_id: "{process.order_id}"
error_handlers:
- catch: PaymentGatewayError
retry: 3
delay: 5s
fallback: MarkAsFailed
- catch: NetworkError
retry: 5
delay: 10s
exponential_backoff: true
Пример: Согласование отпуска
# vacation_approval.cifra
process:
id: VacationApproval
name: "Согласование отпуска"
type: human_task_process
input:
employee_id: {type: uuid}
start_date: {type: date}
end_date: {type: date}
reason: {type: text}
steps:
- task: SubmitRequest
name: "Подать заявку"
type: user_form
assignee: "{process.employee_id}"
form:
fields:
- start_date: {type: date, required: true}
- end_date: {type: date, required: true}
- reason: {type: textarea, max_length: 500}
buttons:
- label: "Подать заявку"
action: submit
- label: "Отмена"
action: cancel
- task: ManagerApproval
name: "Согласование руководителя"
type: approval
assignee: "{employee.manager_id}"
form:
title: "Заявка на отпуск от {employee.full_name}"
fields:
- employee: {type: display, value: "{employee.full_name}"}
- dates: {type: display, value: "{start_date} - {end_date}"}
- duration: {type: display, value: "{duration} дней"}
- reason: {type: display, value: "{process.reason}"}
- comment: {type: textarea, label: "Комментарий"}
buttons:
- label: "Одобрить"
action: approve
style: success
- label: "Отклонить"
action: reject
style: danger
sla: 48h
escalation:
timeout: 48h
action: notify_manager_supervisor
- gateway: ManagerDecision
type: exclusive
branches:
- when: "approval.decision == 'approve'"
goto: HRApproval
- when: "approval.decision == 'reject'"
goto: NotifyRejection
- task: HRApproval
name: "Согласование HR"
type: approval
assignee_role: hr_manager
form: {...}
- gateway: HRDecision
type: exclusive
branches:
- when: "approval.decision == 'approve'"
goto: CreateVacation
- when: "approval.decision == 'reject'"
goto: NotifyRejection
- task: CreateVacation
type: service
action: create_entity
entity: Vacation
data:
employee_id: "{process.employee_id}"
start_date: "{process.start_date}"
end_date: "{process.end_date}"
status: approved
- task: NotifyEmployee
type: notification
to: "{process.employee_id}"
channel: [email, in_app]
template: vacation_approved
process:
id: DocumentApproval
name: "Параллельное согласование"
steps:
- task: SubmitDocument
type: user
assignee: author
- gateway: SplitForReview
name: "Разделить на проверки"
type: parallel # AND - все ветки параллельно
branches:
- goto: LegalReview
- goto: FinanceReview
- goto: TechReview
# Параллельные задачи
- task: LegalReview
name: "Проверка юридического отдела"
type: approval
assignee_role: legal_team
- task: FinanceReview
name: "Проверка финансового отдела"
type: approval
assignee_role: finance_team
- task: TechReview
name: "Проверка технического отдела"
type: approval
assignee_role: tech_team
# Ждём завершения ВСЕХ задач
- gateway: JoinReviews
name: "Дождаться всех проверок"
type: parallel_join # Ждать завершения всех веток
wait_for: [LegalReview, FinanceReview, TechReview]
- gateway: AllApproved?
type: exclusive
condition: |
legal.approved == true AND
finance.approved == true AND
tech.approved == true
branches:
- when: true
goto: FinalApproval
- when: false
goto: Reject
process:
id: MultiSupplierQuote
name: "Запрос цен у поставщиков"
steps:
- gateway: RequestQuotes
name: "Запросить цены у всех поставщиков"
type: parallel
branches:
- goto: RequestSupplier1
- goto: RequestSupplier2
- goto: RequestSupplier3
- task: RequestSupplier1
type: service
endpoint: /suppliers/1/quote
- task: RequestSupplier2
type: service
endpoint: /suppliers/2/quote
- task: RequestSupplier3
type: service
endpoint: /suppliers/3/quote
# Продолжить когда ПЕРВЫЙ ответит
- gateway: FirstQuoteReceived
name: "Первый полученный ответ"
type: discriminator # Первый завершённый продолжает процесс
wait_for_first: true
cancel_others: false # Не отменять остальные запросы
- task: SelectBestQuote
type: script
language: python
code: |
all_quotes = [supplier1.quote, supplier2.quote, supplier3.quote]
valid_quotes = [q for q in all_quotes if q is not None]
best_quote = min(valid_quotes, key=lambda q: q.price)
return best_quote
process:
id: MonthlyReporting
name: "Ежемесячная отчётность"
steps:
- task: GetDepartments
type: service
action: query_entities
entity: Department
filters:
active: true
# Цикл по всем департаментам
- loop: ForEachDepartment
name: "Для каждого департамента"
collection: "{departments}"
variable: department
steps:
- task: GenerateDepartmentReport
type: service
action: generate_report
template: monthly_report
data:
department_id: "{department.id}"
month: "{process.month}"
- task: SendToManager
type: email
to: "{department.manager.email}"
subject: "Отчёт за {process.month}"
attachments:
- "{report.file}"
# После завершения цикла
- task: ConsolidateReports
type: service
action: merge_reports
reports: "{loop.all_reports}"
process:
id: RetryableTask
name: "Задача с повторами"
steps:
- task: AttemptOperation
type: service
endpoint: /api/operation
max_attempts: 5
- while: OperationNotSuccessful
condition: "result.status != 'success' AND attempts < 5"
steps:
- task: WaitBeforeRetry
type: wait
duration: "{attempts * 5}s" # Exponential backoff
- task: RetryOperation
type: service
endpoint: /api/operation
- script: IncrementAttempts
code: "attempts += 1"
- gateway: CheckFinalResult
type: exclusive
branches:
- when: "result.status == 'success'"
goto: Success
- when: "attempts >= 5"
goto: GiveUpAndNotify
process:
id: OrderManagement
name: "Управление заказом"
steps:
# CREATE - создать сущность
- task: CreateOrder
type: entity_operation
operation: create
entity: Order
data:
customer_id: "{process.customer_id}"
status: pending
items: "{process.items}"
total: "{calculate_total(items)}"
output: order
# READ - прочитать сущность
- task: GetCustomer
type: entity_operation
operation: read
entity: Customer
id: "{order.customer_id}"
output: customer
# UPDATE - обновить сущность
- task: UpdateOrderStatus
type: entity_operation
operation: update
entity: Order
id: "{order.id}"
data:
status: confirmed
confirmed_at: "{now()}"
# DELETE - удалить (редко используется в процессах)
- task: CancelOrder
type: entity_operation
operation: delete
entity: Order
id: "{order.id}"
# QUERY - запрос с фильтрами
- task: FindPendingOrders
type: entity_operation
operation: query
entity: Order
filters:
status: pending
created_at: ">= {today() - 7d}"
sort:
- field: created_at
direction: desc
limit: 100
output: pending_orders
process:
id: PaymentWithRefund
name: "Оплата с возможностью возврата"
steps:
# Вызов внутреннего API
- task: ProcessPayment
type: api_call
method: POST
endpoint: /api/v1/payments
body:
order_id: "{process.order_id}"
amount: "{process.amount}"
method: card
headers:
Authorization: "Bearer {system.api_token}"
timeout: 30s
output: payment
# Вызов внешнего API (payment gateway)
- task: ChargeCard
type: external_api_call
service: stripe
method: POST
endpoint: /v1/charges
auth:
type: bearer
token: "{env.STRIPE_SECRET_KEY}"
body:
amount: "{payment.amount * 100}" # в копейках
currency: rub
source: "{payment.card_token}"
retry:
max_attempts: 3
delay: 5s
on_error: [network_error, timeout]
output: charge
# Компенсирующая транзакция (если что-то пошло не так)
- on_error:
- task: RefundPayment
type: external_api_call
service: stripe
endpoint: /v1/refunds
body:
charge: "{charge.id}"
process:
id: SafeOrderProcessing
name: "Безопасная обработка заказа"
steps:
- try:
steps:
- task: ReserveInventory
type: service
endpoint: /inventory/reserve
- task: ProcessPayment
type: service
endpoint: /payments/charge
- task: CreateShipment
type: service
endpoint: /shipments/create
catch:
- exception: InventoryError
steps:
- task: NotifyWarehouse
type: notification
message: "Недостаточно товара для заказа {order.id}"
- exception: PaymentError
steps:
- task: ReleaseInventory
type: service
endpoint: /inventory/release/{order.id}
- task: NotifyCustomer
type: email
template: payment_failed
- exception: ShipmentError
steps:
- task: RefundPayment
type: service
endpoint: /payments/refund/{payment.id}
- task: ReleaseInventory
type: service
endpoint: /inventory/release/{order.id}
finally:
# Выполняется ВСЕГДА (успех или ошибка)
steps:
- task: LogOrderProcessing
type: service
endpoint: /audit/log
data:
order_id: "{order.id}"
status: "{process.status}"
timestamp: "{now()}"
process:
id: BookingWithSaga
name: "Бронирование поездки (Saga)"
type: saga # Специальный тип для распределённых транзакций
steps:
# Шаг 1: Бронирование авиабилета
- saga_step: BookFlight
action:
type: service
endpoint: /flights/book
body:
flight_id: "{process.flight_id}"
passenger: "{process.passenger}"
compensation:
type: service
endpoint: /flights/cancel/{flight_booking.id}
# Шаг 2: Бронирование отеля
- saga_step: BookHotel
action:
type: service
endpoint: /hotels/book
body:
hotel_id: "{process.hotel_id}"
guest: "{process.passenger}"
compensation:
type: service
endpoint: /hotels/cancel/{hotel_booking.id}
# Шаг 3: Аренда автомобиля
- saga_step: RentCar
action:
type: service
endpoint: /cars/rent
body:
car_id: "{process.car_id}"
driver: "{process.passenger}"
compensation:
type: service
endpoint: /cars/cancel/{car_rental.id}
# Шаг 4: Оплата
- saga_step: ProcessPayment
action:
type: service
endpoint: /payments/charge
body:
amount: "{flight.price + hotel.price + car.price}"
compensation:
type: service
endpoint: /payments/refund/{payment.id}
# Если любой шаг падает - откатываем ВСЕ предыдущие
on_failure:
- task: RunCompensations
type: saga_rollback
reverse_order: true # Откатывать в обратном порядке
- task: NotifyCustomer
type: email
template: booking_failed
process:
id: OrderEventDriven
name: "Обработка заказа (event-driven)"
trigger: event
event: orders.created
steps:
- task: OnOrderCreated
name: "Обработать новый заказ"
type: handler
code: |
order = event.data.order
# Отправить подтверждение
send_email(
to=order.customer.email,
template="order_confirmation"
)
# Опубликовать событие для других сервисов
publish_event("orders.confirmed", order)
# Ожидание события от другого процесса
- task: WaitForPayment
type: wait_for_event
event: payments.completed
filter: "event.data.order_id == process.order_id"
timeout: 24h
on_timeout: CancelOrder
# Когда событие получено
- task: OnPaymentCompleted
type: handler
trigger: event_received
code: |
# Обновить статус
order.status = "paid"
order.save()
# Запустить фулфилмент
start_process("OrderFulfillment", {
"order_id": order.id
})
process:
id: AsyncProcessing
name: "Асинхронная обработка"
steps:
# Отправить сообщение в очередь
- task: PublishToQueue
type: message_queue
operation: publish
queue: order_processing
exchange: orders
routing_key: new_order
message:
order_id: "{process.order_id}"
priority: high
persistent: true
# Получить сообщение из очереди
- task: ConsumeFromQueue
type: message_queue
operation: consume
queue: payment_results
wait: true
timeout: 60s
output: payment_result
# Batch processing (обработка пакетом)
- task: ProcessBatch
type: message_queue
operation: consume_batch
queue: email_notifications
batch_size: 100
wait_timeout: 5s # Ждать max 5 секунд для заполнения batch
foreach: message
steps:
- task: SendEmail
type: email
to: "{message.recipient}"
template: "{message.template}"
process:
id: MainOrderProcess
name: "Главный процесс заказа"
steps:
- task: CreateOrder
type: entity_operation
operation: create
entity: Order
# Вызов подпроцесса (call activity)
- task: ProcessPayment
type: call_process
process: PaymentProcessing
input:
order_id: "{order.id}"
amount: "{order.total}"
output: payment_result
wait: true # Ждать завершения подпроцесса
- gateway: PaymentSuccess?
type: exclusive
condition: "payment_result.status == 'success'"
branches:
- when: true
goto: Fulfill
- when: false
goto: Cancel
# Асинхронный вызов подпроцесса (fire and forget)
- task: StartAnalytics
type: call_process
process: OrderAnalytics
input:
order_id: "{order.id}"
wait: false # Не ждать завершения
# Процесс 1: Создание заказа
process:
id: CreateOrderProcess
name: "Создание заказа"
steps:
- task: CreateOrder
type: entity_operation
operation: create
entity: Order
output: order
# Установить correlation key
- task: SetCorrelation
type: correlation
operation: set
key: order_id
value: "{order.id}"
# Опубликовать событие с correlation
- task: PublishEvent
type: event
name: orders.created
correlation_key: "{order.id}"
data:
order: "{order}"
---
# Процесс 2: Обработка платежа (запускается событием)
process:
id: PaymentProcess
name: "Обработка платежа"
trigger: event
event: payments.initiated
correlation:
key: order_id # Связать с CreateOrderProcess по order_id
steps:
- task: ProcessPayment
type: service
endpoint: /payments/process
# Отправить результат обратно в CreateOrderProcess
- task: SendPaymentResult
type: event
name: payments.completed
correlation_key: "{process.order_id}"
data:
status: success
payment_id: "{payment.id}"
process:
id: MonitoredProcess
name: "Процесс с мониторингом"
# Определение метрик
metrics:
- name: process_duration
type: duration
description: "Время выполнения процесса"
track: true
- name: task_completion_rate
type: percentage
description: "Процент успешно завершённых задач"
track: true
- name: error_count
type: counter
description: "Количество ошибок"
track: true
# KPI и алерты
kpi:
- metric: process_duration
target: "<= 2h"
alert:
when: "> 4h"
severity: warning
notify: [process_owner, operations_team]
- metric: error_count
target: "< 5%"
alert:
when: ">= 10%"
severity: critical
notify: [dev_team, operations_team]
steps:
- task: DoWork
type: service
endpoint: /api/work
# Мониторинг конкретной задачи
monitoring:
track_duration: true
track_errors: true
log_payload: true # Логировать входные данные
process:
id: AuditedProcess
name: "Процесс с аудитом"
# Настройки аудита
audit:
enabled: true
log_all_tasks: true
log_data_changes: true
retention: 90d # Хранить логи 90 дней
steps:
- task: SensitiveOperation
type: service
endpoint: /api/sensitive
# Расширенный аудит для конкретной задачи
audit:
log_input: true
log_output: true
log_user: true
log_ip_address: true
reason_required: true # Требовать причину выполнения
- task: DataChange
type: entity_operation
operation: update
entity: Customer
# Автоматическое логирование изменений
audit:
track_changes: true
compare_before_after: true
# ecommerce_order.cifra
cifra: 1.0.0
process:
id: EcommerceOrderProcess
name: "Процесс заказа в интернет-магазине"
type: business_process
version: 2.0.0
description: |
Полный процесс обработки заказа от создания до доставки,
включая валидацию, оплату, резервирование товара и отправку.
owner: sales_team
category: sales
# Входные данные
input:
customer_id: {type: uuid, required: true}
items: {type: array, items: {cart_item}, required: true}
shipping_address: {type: address, required: true}
payment_method: {type: enum, values: [card, cash, bank_transfer]}
# Выходные данные
output:
order_id: {type: uuid}
status: {type: enum, values: [completed, cancelled, failed]}
# Метрики
metrics:
- process_duration: {type: duration, target: "<= 30m"}
- conversion_rate: {type: percentage, target: ">= 95%"}
- error_rate: {type: percentage, target: "< 1%"}
# Шаги процесса
steps:
# 1. Валидация
- task: ValidateCart
name: "Проверить корзину"
type: validation
rules:
- items.length > 0
- all(item.quantity > 0 for item in items)
- all(item.product.in_stock for item in items)
# 2. Создать заказ
- task: CreateOrder
name: "Создать заказ"
type: entity_operation
operation: create
entity: Order
data:
customer_id: "{process.customer_id}"
items: "{process.items}"
total: "{sum(item.price * item.quantity for item in items)}"
status: pending
shipping_address: "{process.shipping_address}"
output: order
# 3. Параллельные проверки
- gateway: ParallelChecks
type: parallel
branches:
- goto: CheckInventory
- goto: ValidateAddress
- goto: CheckCustomerCredit
- task: CheckInventory
name: "Проверить наличие товара"
type: service
endpoint: /inventory/check
body: {items: "{order.items}"}
output: inventory_check
- task: ValidateAddress
name: "Валидировать адрес"
type: external_api_call
service: address_validation
endpoint: /validate
body: {address: "{order.shipping_address}"}
output: address_validation
- task: CheckCustomerCredit
name: "Проверить кредитный лимит"
type: service
endpoint: /customers/{customer_id}/credit
output: credit_check
- gateway: JoinChecks
type: parallel_join
wait_for: [CheckInventory, ValidateAddress, CheckCustomerCredit]
# 4. Принятие решения
- gateway: AllChecksPass?
type: exclusive
condition: |
inventory_check.available AND
address_validation.valid AND
credit_check.approved
branches:
- when: true
goto: ReserveInventory
- when: false
goto: CancelOrder
# 5. Резервирование товара
- saga_step: ReserveInventory
action:
type: service
endpoint: /inventory/reserve
body: {order_id: "{order.id}"}
compensation:
type: service
endpoint: /inventory/release/{order.id}
# 6. Обработка платежа
- saga_step: ProcessPayment
action:
type: call_process
process: PaymentProcessing
input:
order_id: "{order.id}"
amount: "{order.total}"
method: "{process.payment_method}"
wait: true
output: payment
compensation:
type: service
endpoint: /payments/refund/{payment.id}
# 7. Создание отправления
- saga_step: CreateShipment
action:
type: service
endpoint: /shipments/create
body:
order_id: "{order.id}"
address: "{order.shipping_address}"
output: shipment
compensation:
type: service
endpoint: /shipments/cancel/{shipment.id}
# 8. Уведомления (асинхронно)
- task: SendConfirmation
type: notification
wait: false # Не блокировать процесс
channels:
- type: email
to: "{customer.email}"
template: order_confirmation
- type: sms
to: "{customer.phone}"
template: order_sms
- type: push
to: "{customer.device_id}"
template: order_push
# 9. Завершение
- task: CompleteOrder
type: entity_operation
operation: update
entity: Order
id: "{order.id}"
data:
status: completed
completed_at: "{now()}"
# 10. Аналитика (fire and forget)
- task: TrackAnalytics
type: call_process
process: OrderAnalytics
input: {order_id: "{order.id}"}
wait: false
# Обработка ошибок
error_handlers:
- catch: InventoryError
steps:
- task: NotifyOutOfStock
type: notification
message: "Товар {product.name} закончился"
- goto: CancelOrder
- catch: PaymentError
retry: 3
delay: 5s
fallback: CancelOrderWithCompensation
- catch: [NetworkError, TimeoutError]
retry: 5
delay: 10s
exponential_backoff: true
# Компенсация (если что-то пошло не так)
compensation:
- task: CancelOrderWithCompensation
type: saga_rollback
steps:
- ReleaseInventory
- RefundPayment
- NotifyCustomer
# Аудит
audit:
enabled: true
log_all_steps: true
retention: 180d
Готово! Полная система описания процессов в CIFRA 🚀