Дата: 2025-11-10
Версия: 1.0.0
Цель: Инвентаризация недостающих компонентов системы
✅ Иерархическая композиция (Элементы → Модули → Компоненты)
✅ Архитектура классов (Метапрограммирование, Descriptors, Factory)
✅ Метастандарты (BPMN, DMN, OpenAPI, GraphQL, ArchiMate)
✅ Именование (CIFRA Platform, CIFRA Spec)
✅ Описание процессов (Business Process, Workflow, Saga)
1. PERMISSIONS & SECURITY (безопасность и права)
2. UI/UX SPECIFICATION (описание интерфейсов)
3. INTEGRATIONS (внешние системы)
4. NOTIFICATIONS & ALERTS (уведомления)
5. REPORTS & ANALYTICS (отчёты и аналитика)
6. TESTING (тестирование)
7. DEPLOYMENT & DEVOPS (деплой и мониторинг)
8. LOCALIZATION (мультиязычность)
9. VERSIONING & MIGRATIONS (версионирование)
10. SCHEDULING & CRON (планировщик задач)
# security/rbac.cifra
security:
authentication:
type: jwt
token_expiration: 3600
refresh_token: true
providers:
- local # Email + Password
- oauth:
google:
client_id: "{env.GOOGLE_CLIENT_ID}"
client_secret: "{env.GOOGLE_CLIENT_SECRET}"
github:
client_id: "{env.GITHUB_CLIENT_ID}"
client_secret: "{env.GITHUB_CLIENT_SECRET}"
# Определение ролей
roles:
- id: admin
name: "Администратор"
description: "Полный доступ ко всей системе"
permissions: ["*"] # Все права
- id: sales_manager
name: "Менеджер по продажам"
description: "Управление сделками и клиентами"
permissions:
- contacts:read
- contacts:create
- contacts:update
- deals:* # Все права на сделки
- reports:sales:read
- id: sales_rep
name: "Менеджер продаж"
description: "Работа со своими сделками"
permissions:
- contacts:read
- contacts:create
- deals:read
- deals:create
- deals:update:own # Только свои сделки
- id: customer
name: "Клиент"
description: "Доступ к своим заказам"
permissions:
- orders:read:own
- profile:read:own
- profile:update:own
# Права (permissions)
permissions:
# Format: resource:action[:scope]
# CRUD для контактов
- id: contacts:read
name: "Просмотр контактов"
resource: Contact
action: read
- id: contacts:create
name: "Создание контактов"
resource: Contact
action: create
- id: contacts:update
name: "Редактирование контактов"
resource: Contact
action: update
- id: contacts:delete
name: "Удаление контактов"
resource: Contact
action: delete
# Специальные права
- id: deals:update:own
name: "Редактировать свои сделки"
resource: Deal
action: update
scope: own # Только принадлежащие пользователю
condition: "resource.owner_id == user.id"
- id: deals:approve
name: "Одобрять сделки"
resource: Deal
action: approve
condition: "resource.amount < 100000 OR user.role == 'admin'"
# Field-level security (права на уровне полей)
field_security:
Contact:
email:
read: [admin, sales_manager, sales_rep]
write: [admin, sales_manager]
phone:
read: [admin, sales_manager, sales_rep]
write: [admin, sales_manager, sales_rep]
company:
read: ["*"] # Все могут читать
write: [admin, sales_manager]
Deal:
amount:
read: [admin, sales_manager, sales_rep:own]
write: [admin, sales_manager]
commission:
read: [admin, sales_manager]
write: [admin]
# security/abac.cifra
security:
abac_policies:
# Политика: Менеджер может редактировать сделки своего региона
- id: regional_deal_access
name: "Доступ к сделкам региона"
effect: allow
principals:
roles: [sales_manager]
resources:
type: Deal
actions: [read, update]
conditions:
- "user.region == resource.customer.region"
# Политика: После 18:00 нельзя одобрять сделки > 50000
- id: after_hours_limit
name: "Ограничение одобрений после 18:00"
effect: deny
principals:
roles: [sales_manager]
resources:
type: Deal
actions: [approve]
conditions:
- "current_time().hour >= 18"
- "resource.amount > 50000"
# Политика: VIP клиенты видят специальные цены
- id: vip_pricing
name: "Специальные цены для VIP"
effect: allow
principals:
attributes:
customer_type: VIP
resources:
type: Product
actions: [read]
transform:
price: "resource.price * 0.85" # 15% скидка
# Row-Level Security (RLS)
row_level_security:
Contact:
- policy: own_contacts
condition: "owner_id == current_user.id"
roles: [sales_rep]
- policy: team_contacts
condition: "owner.team_id == current_user.team_id"
roles: [sales_manager]
- policy: all_contacts
condition: "true"
roles: [admin]
Order:
- policy: customer_own_orders
condition: "customer_id == current_user.id"
roles: [customer]
- policy: all_orders
condition: "true"
roles: [admin, sales_manager]
# ui/contact_form.cifra
ui:
forms:
- id: create_contact_form
name: "Создание контакта"
entity: Contact
mode: create
layout: two_column # one_column, two_column, grid
sections:
- id: personal_info
title: "Личная информация"
fields:
- first_name:
label: "Имя"
required: true
placeholder: "Введите имя"
validation:
- type: min_length
value: 2
message: "Минимум 2 символа"
- last_name:
label: "Фамилия"
required: true
- email:
label: "Email"
required: true
type: email
help_text: "Мы не передаём email третьим лицам"
- phone:
label: "Телефон"
type: phone
mask: "+7 (999) 999-99-99"
- id: company_info
title: "Информация о компании"
collapsible: true
collapsed: false
fields:
- company:
label: "Компания"
type: relation
entity: Company
display_field: name
searchable: true
allow_create: true # Можно создать новую компанию
- position:
label: "Должность"
type: string
- id: additional
title: "Дополнительно"
fields:
- tags:
label: "Теги"
type: tags
max_tags: 10
suggestions: [vip, partner, lead]
- notes:
label: "Примечания"
type: textarea
rows: 5
max_length: 1000
buttons:
- type: submit
label: "Создать контакт"
style: primary
icon: save
- type: cancel
label: "Отмена"
style: secondary
validation:
on_submit: true
inline: true # Валидация при вводе
hooks:
before_submit: |
# JavaScript код для обработки перед отправкой
if (data.email.includes('+')) {
confirm('Email содержит +, продолжить?')
}
after_submit: |
# После успешного создания
notify('Контакт создан успешно')
navigate('/contacts/' + result.id)
# ui/contact_list.cifra
ui:
lists:
- id: contacts_list
name: "Список контактов"
entity: Contact
# Колонки таблицы
columns:
- field: full_name
label: "Имя"
sortable: true
searchable: true
width: 200px
render: |
<div class="flex items-center">
<Avatar src="{row.avatar}" />
<div>
<div class="font-medium">{row.full_name}</div>
<div class="text-sm text-gray-500">{row.position}</div>
</div>
</div>
- field: email
label: "Email"
sortable: true
searchable: true
- field: company.name
label: "Компания"
sortable: true
link: "/companies/{row.company.id}"
- field: tags
label: "Теги"
render: |
{row.tags.map(tag => <Badge>{tag}</Badge>)}
- field: created_at
label: "Создан"
sortable: true
format: date
format_pattern: "DD.MM.YYYY"
- field: actions
label: ""
width: 100px
render: |
<ActionMenu>
<MenuItem onClick="{editContact}">Редактировать</MenuItem>
<MenuItem onClick="{deleteContact}">Удалить</MenuItem>
<MenuItem onClick="{sendEmail}">Отправить email</MenuItem>
</ActionMenu>
# Фильтры
filters:
- field: company
type: select
label: "Компания"
options: "query(Company, {}, {name: 1})"
- field: tags
type: multiselect
label: "Теги"
- field: created_at
type: date_range
label: "Дата создания"
# Поиск
search:
enabled: true
placeholder: "Поиск по имени, email, телефону..."
fields: [first_name, last_name, email, phone]
# Действия над выбранными
bulk_actions:
- id: delete
label: "Удалить"
icon: trash
confirm: "Удалить выбранные контакты?"
- id: export
label: "Экспорт в Excel"
icon: download
- id: assign_tag
label: "Добавить тег"
icon: tag
form:
fields:
- tag: {type: select, options: [vip, partner, lead]}
# Pagination
pagination:
page_size: 50
page_size_options: [25, 50, 100, 200]
# Экспорт
export:
formats: [excel, csv, pdf]
# ui/sales_dashboard.cifra
ui:
dashboards:
- id: sales_dashboard
name: "Дашборд продаж"
layout: grid
refresh_interval: 60s # Автообновление каждую минуту
widgets:
# Карточки с метриками
- type: metric_card
position: {row: 1, col: 1, width: 3, height: 1}
metric: total_revenue
title: "Общая выручка"
query: |
SELECT SUM(amount) as value
FROM deals
WHERE status = 'won'
AND created_at >= current_date - interval '30 days'
format: currency
trend:
query: |
SELECT SUM(amount) as previous_value
FROM deals
WHERE status = 'won'
AND created_at >= current_date - interval '60 days'
AND created_at < current_date - interval '30 days'
show_percentage: true
- type: metric_card
position: {row: 1, col: 4, width: 3, height: 1}
title: "Новые сделки"
query: |
SELECT COUNT(*) as value
FROM deals
WHERE created_at >= current_date - interval '7 days'
icon: trending_up
color: green
# График
- type: chart
position: {row: 2, col: 1, width: 8, height: 4}
title: "Выручка по месяцам"
chart_type: line
query: |
SELECT
DATE_TRUNC('month', created_at) as month,
SUM(amount) as revenue,
COUNT(*) as deals_count
FROM deals
WHERE status = 'won'
AND created_at >= current_date - interval '12 months'
GROUP BY month
ORDER BY month
x_axis: month
y_axis: [revenue, deals_count]
options:
smooth: true
fill: true
# Таблица топ клиентов
- type: table
position: {row: 2, col: 9, width: 4, height: 4}
title: "Топ клиенты"
query: |
SELECT
c.name,
COUNT(d.id) as deals_count,
SUM(d.amount) as total_revenue
FROM customers c
JOIN deals d ON d.customer_id = c.id
WHERE d.status = 'won'
GROUP BY c.id
ORDER BY total_revenue DESC
LIMIT 10
columns:
- {field: name, label: "Клиент"}
- {field: deals_count, label: "Сделок"}
- {field: total_revenue, label: "Выручка", format: currency}
# Воронка продаж
- type: funnel
position: {row: 6, col: 1, width: 6, height: 4}
title: "Воронка продаж"
stages:
- {name: "Лиды", query: "SELECT COUNT(*) FROM deals WHERE stage = 'lead'"}
- {name: "Квалификация", query: "SELECT COUNT(*) FROM deals WHERE stage = 'qualification'"}
- {name: "Предложение", query: "SELECT COUNT(*) FROM deals WHERE stage = 'proposal'"}
- {name: "Переговоры", query: "SELECT COUNT(*) FROM deals WHERE stage = 'negotiation'"}
- {name: "Выиграно", query: "SELECT COUNT(*) FROM deals WHERE stage = 'won'"}
# Фильтры для всего дашборда
filters:
- field: date_range
type: date_range
label: "Период"
default: last_30_days
- field: sales_rep
type: select
label: "Менеджер"
query: "SELECT id, name FROM users WHERE role = 'sales_rep'"
# integrations/external_apis.cifra
integrations:
# Stripe (платёжный шлюз)
- id: stripe
name: "Stripe Payments"
type: rest_api
base_url: https://api.stripe.com
auth:
type: bearer
token: "{env.STRIPE_SECRET_KEY}"
endpoints:
- id: create_charge
path: /v1/charges
method: POST
params:
amount: {type: integer, required: true}
currency: {type: string, default: "rub"}
source: {type: string, required: true}
- id: create_refund
path: /v1/refunds
method: POST
params:
charge: {type: string, required: true}
# SendGrid (email)
- id: sendgrid
name: "SendGrid Email Service"
type: rest_api
base_url: https://api.sendgrid.com/v3
auth:
type: bearer
token: "{env.SENDGRID_API_KEY}"
endpoints:
- id: send_email
path: /mail/send
method: POST
body_schema:
personalizations:
- to: [{email: string, name: string}]
subject: string
from: {email: string, name: string}
content:
- type: text/html
value: string
# Google Maps (геокодирование)
- id: google_maps
name: "Google Maps API"
type: rest_api
base_url: https://maps.googleapis.com/maps/api
auth:
type: api_key
param: key
value: "{env.GOOGLE_MAPS_KEY}"
endpoints:
- id: geocode
path: /geocode/json
method: GET
params:
address: {type: string, required: true}
# Twilio (SMS)
- id: twilio
name: "Twilio SMS"
type: rest_api
base_url: https://api.twilio.com/2010-04-01
auth:
type: basic
username: "{env.TWILIO_ACCOUNT_SID}"
password: "{env.TWILIO_AUTH_TOKEN}"
endpoints:
- id: send_sms
path: /Accounts/{account_sid}/Messages.json
method: POST
params:
To: {type: phone, required: true}
From: {type: phone, required: true}
Body: {type: string, required: true, max_length: 1600}
# integrations/message_queues.cifra
integrations:
message_queues:
# Kafka
- id: kafka
type: kafka
brokers:
- kafka1.example.com:9092
- kafka2.example.com:9092
- kafka3.example.com:9092
topics:
- name: orders.created
partitions: 6
replication_factor: 3
config:
retention.ms: 604800000 # 7 days
- name: payments.completed
partitions: 6
consumers:
- name: order_processor
topics: [orders.created]
group_id: order-processing-group
auto_offset_reset: earliest
producers:
- name: order_events
topics: [orders.created, orders.updated]
# RabbitMQ
- id: rabbitmq
type: rabbitmq
host: rabbitmq.example.com
port: 5672
vhost: /
auth:
username: "{env.RABBITMQ_USER}"
password: "{env.RABBITMQ_PASSWORD}"
exchanges:
- name: orders
type: topic
durable: true
queues:
- name: email_notifications
durable: true
arguments:
x-message-ttl: 86400000 # 24 hours
- name: sms_notifications
durable: true
bindings:
- queue: email_notifications
exchange: orders
routing_key: "order.*.email"
# integrations/storage.cifra
integrations:
storage:
# AWS S3
- id: s3_documents
type: s3
bucket: company-documents
region: eu-west-1
auth:
access_key_id: "{env.AWS_ACCESS_KEY_ID}"
secret_access_key: "{env.AWS_SECRET_ACCESS_KEY}"
folders:
invoices: /invoices/{year}/{month}/
contracts: /contracts/{customer_id}/
reports: /reports/{year}/
lifecycle:
- id: archive_old_files
transition:
days: 90
storage_class: GLACIER
# MinIO (S3-compatible)
- id: minio_uploads
type: s3
endpoint: https://minio.example.com
bucket: user-uploads
auth:
access_key: "{env.MINIO_ACCESS_KEY}"
secret_key: "{env.MINIO_SECRET_KEY}"
public_url: https://cdn.example.com
# notifications/system.cifra
notifications:
channels:
# Email
- id: email
type: email
provider: sendgrid
from:
email: noreply@example.com
name: "CRM System"
templates:
- id: welcome_email
subject: "Добро пожаловать в CRM!"
body_html: templates/welcome.html
body_text: templates/welcome.txt
variables: [user_name, login_url]
- id: order_confirmation
subject: "Заказ #{order_number} подтверждён"
body_html: templates/order_confirmation.html
# SMS
- id: sms
type: sms
provider: twilio
from: "+79991234567"
templates:
- id: order_shipped
body: "Ваш заказ #{order_number} отправлен. Трек-номер: {tracking_number}"
# Push notifications
- id: push
type: push
provider: firebase
credentials: "{env.FIREBASE_CREDENTIALS}"
templates:
- id: new_message
title: "Новое сообщение"
body: "{sender_name}: {message_preview}"
icon: /icons/message.png
click_action: /messages/{message_id}
# In-app notifications
- id: in_app
type: in_app
storage: database
retention: 30d # Хранить 30 дней
# Правила отправки
rules:
# Уведомление при создании заказа
- trigger: entity_created
entity: Order
channels: [email, sms, in_app]
recipients:
- type: entity_field
field: customer
template: order_confirmation
conditions:
- "order.total > 0"
# Уведомление менеджера о новом лиде
- trigger: entity_created
entity: Deal
stage: lead
channels: [email, in_app, push]
recipients:
- type: entity_field
field: assigned_to
template: new_lead_assigned
priority: high
# Напоминание об истекающей задаче
- trigger: scheduled
schedule: "0 9 * * *" # Каждый день в 9:00
channels: [email, in_app]
template: task_due_reminder
query: |
SELECT * FROM tasks
WHERE due_date = current_date
AND status != 'completed'
# Настройки пользователя (preferences)
user_preferences:
- channel: email
frequency: immediate # immediate, hourly, daily, weekly
enabled_events: [order_created, deal_won, task_assigned]
- channel: push
frequency: immediate
enabled_events: [new_message, task_due]
quiet_hours:
start: "22:00"
end: "08:00"
# reports/sales_reports.cifra
reports:
- id: monthly_sales_report
name: "Отчёт по продажам за месяц"
category: sales
type: tabular
parameters:
- month: {type: month, required: true}
- sales_rep: {type: relation, entity: User, required: false}
query: |
SELECT
u.name as sales_rep,
COUNT(d.id) as deals_count,
SUM(CASE WHEN d.status = 'won' THEN d.amount ELSE 0 END) as won_amount,
SUM(CASE WHEN d.status = 'lost' THEN d.amount ELSE 0 END) as lost_amount,
ROUND(100.0 * COUNT(CASE WHEN d.status = 'won' THEN 1 END) / COUNT(*), 2) as conversion_rate
FROM deals d
JOIN users u ON d.assigned_to = u.id
WHERE DATE_TRUNC('month', d.created_at) = :month
AND (:sales_rep IS NULL OR d.assigned_to = :sales_rep)
GROUP BY u.id, u.name
ORDER BY won_amount DESC
columns:
- {field: sales_rep, label: "Менеджер", width: 200}
- {field: deals_count, label: "Всего сделок", align: center}
- {field: won_amount, label: "Выиграно", format: currency}
- {field: lost_amount, label: "Проиграно", format: currency}
- {field: conversion_rate, label: "Конверсия", format: percentage}
totals:
- deals_count: sum
- won_amount: sum
- lost_amount: sum
- conversion_rate: avg
export_formats: [excel, pdf, csv]
schedule:
frequency: monthly
day_of_month: 1
time: "09:00"
recipients: [sales_manager@example.com]
- id: customer_lifetime_value
name: "Customer Lifetime Value"
type: chart
chart_type: scatter
query: |
SELECT
c.name,
COUNT(o.id) as orders_count,
SUM(o.total) as total_spent,
DATE_PART('day', MAX(o.created_at) - MIN(o.created_at)) as days_active
FROM customers c
JOIN orders o ON o.customer_id = c.id
GROUP BY c.id
HAVING COUNT(o.id) > 1
axes:
x: days_active
y: total_spent
size: orders_count
label: name
# tests/contact_tests.cifra
tests:
unit:
- name: "Contact validation"
entity: Contact
test_cases:
- name: "Valid contact creation"
action: create
data:
first_name: "Иван"
last_name: "Петров"
email: "ivan@example.com"
expect:
status: success
result:
full_name: "Иван Петров"
- name: "Invalid email"
action: create
data:
first_name: "Иван"
last_name: "Петров"
email: "invalid-email"
expect:
status: error
error_code: validation_error
error_field: email
integration:
- name: "Order fulfillment process"
process: OrderFulfillment
test_cases:
- name: "Successful order"
setup:
- create_entity: Product
data: {sku: "TEST-001", stock: 100}
- create_entity: Customer
data: {email: "test@example.com"}
input:
product_id: "{created.Product.id}"
customer_id: "{created.Customer.id}"
quantity: 5
expect:
process_status: completed
entities_created: [Order, Shipment]
final_state:
Order.status: shipped
Product.stock: 95
- name: "Out of stock"
input:
product_id: "{product.id}"
quantity: 200 # Больше чем stock
expect:
process_status: failed
error: "Insufficient stock"
e2e:
- name: "User can create and complete order"
type: browser
steps:
- action: navigate
url: /products
- action: click
selector: "[data-test='add-to-cart']"
- action: click
selector: "[data-test='checkout']"
- action: fill
selector: "[name='email']"
value: "test@example.com"
- action: click
selector: "[data-test='submit-order']"
- action: wait_for
selector: "[data-test='order-confirmation']"
- action: assert
selector: "[data-test='order-status']"
text: "Order placed successfully"
# deployment/production.cifra
deployment:
environments:
- id: development
name: "Development"
url: https://dev.example.com
auto_deploy: true
branch: develop
- id: staging
name: "Staging"
url: https://staging.example.com
auto_deploy: false
branch: main
requires_approval: true
- id: production
name: "Production"
url: https://example.com
auto_deploy: false
branch: main
requires_approval: true
approvers: [cto@example.com, lead@example.com]
infrastructure:
type: kubernetes
cluster: production-cluster
services:
- name: api
replicas: 3
image: company/api:latest
port: 8000
resources:
cpu: 1
memory: 2Gi
env:
DATABASE_URL: "{secrets.database_url}"
REDIS_URL: "{secrets.redis_url}"
- name: worker
replicas: 2
image: company/worker:latest
resources:
cpu: 0.5
memory: 1Gi
databases:
- type: postgresql
version: "14"
size: 100GB
backup:
frequency: daily
retention: 30d
- type: redis
version: "7"
size: 10GB
monitoring:
- service: prometheus
scrape_interval: 15s
metrics:
- http_requests_total
- http_request_duration_seconds
- database_connections
- service: grafana
dashboards:
- System Overview
- Application Metrics
- Business Metrics
- service: sentry
dsn: "{env.SENTRY_DSN}"
sample_rate: 1.0
traces_sample_rate: 0.1
logging:
- service: loki
retention: 30d
labels:
- service
- environment
- level
alerts:
- name: high_error_rate
condition: "error_rate > 5%"
duration: 5m
severity: critical
notify: [ops-team@example.com, slack://ops-channel]
- name: high_latency
condition: "p95_latency > 2s"
duration: 10m
severity: warning
notify: [dev-team@example.com]
# localization/i18n.cifra
localization:
default_locale: ru_RU
supported_locales:
- ru_RU
- en_US
- de_DE
- zh_CN
# Переводы
translations:
Contact:
ru_RU:
singular: "Контакт"
plural: "Контакты"
fields:
first_name: "Имя"
last_name: "Фамилия"
email: "Email"
phone: "Телефон"
en_US:
singular: "Contact"
plural: "Contacts"
fields:
first_name: "First Name"
last_name: "Last Name"
email: "Email"
phone: "Phone"
# Форматирование
formatting:
ru_RU:
date: "DD.MM.YYYY"
time: "HH:mm"
datetime: "DD.MM.YYYY HH:mm"
currency: "# ##0,00 ₽"
number: "# ##0,##"
phone: "+7 (###) ###-##-##"
en_US:
date: "MM/DD/YYYY"
time: "hh:mm A"
datetime: "MM/DD/YYYY hh:mm A"
currency: "$#,##0.00"
number: "#,##0.##"
phone: "+1 (###) ###-####"
# Валюты
currencies:
- code: RUB
symbol: "₽"
name:
ru_RU: "Российский рубль"
en_US: "Russian Ruble"
- code: USD
symbol: "$"
name:
ru_RU: "Доллар США"
en_US: "US Dollar"
# versioning/migrations.cifra
versioning:
# Версионирование CIFRA спецификаций
schema_version: 2.0.0
migrations:
- version: 2.0.0
date: "2025-11-10"
description: "Добавлено поле commission в Deal"
up: |
ALTER TABLE deals
ADD COLUMN commission DECIMAL(15,2);
UPDATE deals
SET commission = amount * 0.05
WHERE status = 'won';
down: |
ALTER TABLE deals
DROP COLUMN commission;
- version: 1.9.0
date: "2025-10-15"
description: "Добавлена таблица tags"
up: |
CREATE TABLE tags (
id UUID PRIMARY KEY,
name VARCHAR(100) UNIQUE,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE TABLE contact_tags (
contact_id UUID REFERENCES contacts(id),
tag_id UUID REFERENCES tags(id),
PRIMARY KEY (contact_id, tag_id)
);
down: |
DROP TABLE contact_tags;
DROP TABLE tags;
# Обратная совместимость
compatibility:
api_versions:
- version: v1
deprecated: false
sunset_date: null
- version: v0
deprecated: true
sunset_date: "2026-01-01"
migration_guide: /docs/v0-to-v1-migration
# scheduling/jobs.cifra
scheduling:
jobs:
# Ежедневная отправка отчётов
- id: daily_sales_report
name: "Ежедневный отчёт по продажам"
schedule: "0 9 * * *" # Каждый день в 9:00
timezone: Europe/Moscow
action:
type: generate_report
report: daily_sales
send_to: [sales-team@example.com]
# Очистка старых записей
- id: cleanup_old_logs
name: "Очистка старых логов"
schedule: "0 2 * * 0" # Каждое воскресенье в 2:00
action:
type: execute_query
query: |
DELETE FROM audit_logs
WHERE created_at < NOW() - INTERVAL '90 days'
# Напоминания об истекающих задачах
- id: task_reminders
name: "Напоминания о задачах"
schedule: "0 */4 * * *" # Каждые 4 часа
action:
type: run_process
process: SendTaskReminders
# Синхронизация с внешней системой
- id: sync_with_external_crm
name: "Синхронизация с внешней CRM"
schedule: "*/15 * * * *" # Каждые 15 минут
retry:
max_attempts: 3
delay: 5m
action:
type: call_integration
integration: external_crm
endpoint: sync_contacts
CIFRA PLATFORM = Всё для создания бизнес-приложений
✅ ОХВАТИЛИ:
1. Данные (Entity, Fields)
2. Логика (Classes, Methods)
3. Процессы (BPMN-like workflows)
4. Архитектура (Иерархическая композиция)
5. Стандарты (BPMN, OpenAPI, GraphQL)
🔴 ДОБАВИЛИ СЕГОДНЯ:
6. Безопасность (RBAC, ABAC, RLS)
7. UI/UX (Forms, Lists, Dashboards)
8. Интеграции (APIs, Queues, Storage)
9. Уведомления (Email, SMS, Push)
10. Отчёты (Reports, Analytics)
11. Тестирование (Unit, Integration, E2E)
12. DevOps (Deployment, Monitoring, Alerts)
13. Локализация (i18n, l10n)
14. Версионирование (Migrations)
15. Планировщик (Cron, Jobs)
# complete_crm.cifra
cifra: 1.0.0
# 1. Данные
entities: {...}
# 2. Процессы
processes: {...}
# 3. Правила
rules: {...}
# 4. API
api: {...}
# 5. Безопасность
security: {...}
# 6. UI
ui: {...}
# 7. Интеграции
integrations: {...}
# 8. Уведомления
notifications: {...}
# 9. Отчёты
reports: {...}
# 10. Тестирование
tests: {...}
# 11. Deployment
deployment: {...}
# 12. Локализация
localization: {...}
# 13. Планировщик
scheduling: {...}
Результат: Одна спецификация → Полноценное Enterprise приложение 🚀