Дата создания: 2025-11-10
Версия: 1.0
Статус: Архитектурная спецификация
CIFRA Platform построена на 4 мета-уровнях абстракции данных, которые формируют иерархию от базовой платформы до пользовательских данных.
Эта модель отличается от технической абстракции (DB → ORM → DTO → API → UI) и описывает концептуальные слои системы.
┌─────────────────────────────────────────────────┐
│ УРОВЕНЬ 4: ПОЛЬЗОВАТЕЛЬСКИЕ ДАННЫЕ │
│ (Records, Content, User-Created Data) │
│ Контакты, Заказы, Товары, Статьи │
└─────────────────────────────────────────────────┘
↓ created using
┌─────────────────────────────────────────────────┐
│ УРОВЕНЬ 3: НАСТРОЙКА КОНФИГУРАЦИИ │
│ (Configuration Instance Settings) │
│ Включенные модули, Темы, Параметры │
└─────────────────────────────────────────────────┘
↓ instance of
┌─────────────────────────────────────────────────┐
│ УРОВЕНЬ 2: КОНФИГУРАЦИИ │
│ (Application Templates) │
│ CRM.cifra, ERP.cifra, AdminPanel.cifra │
└─────────────────────────────────────────────────┘
↓ built on
┌─────────────────────────────────────────────────┐
│ УРОВЕНЬ 1: ПЛАТФОРМА │
│ (CIFRA Core Engine) │
│ EntityMeta, BaseField, Module System │
└─────────────────────────────────────────────────┘
Сама CIFRA - ядро платформы, базовые классы, метаклассы, фреймворк.
Это неизменяемая основа, на которой строятся все приложения.
# 1. МЕТАКЛАССЫ
class EntityMeta(type):
"""Базовый метакласс для всех сущностей"""
_registry = {}
class ModuleMeta(type):
"""Метакласс для модулей"""
_modules = {}
# 2. БАЗОВЫЕ КЛАССЫ
class BaseEntity:
"""Базовый класс для всех Entity"""
class BaseField:
"""Базовый класс для всех полей"""
class BaseModule:
"""Базовый класс для модулей"""
# 3. CORE СИСТЕМЫ
class EntityAPI:
"""Unified API для работы с Entity"""
class FieldAPI:
"""API для работы с полями"""
class PluginSystem:
"""Система плагинов"""
class ThemeEngine:
"""Движок тем"""
class ProcessEngine:
"""BPMN процессы"""
class SecurityManager:
"""OAuth, RBAC, RLS"""
1. CIFRA Core:
# cifra/core/entity.py
class EntityMeta(type):
def __new__(mcs, name, bases, namespace, **kwargs):
# Автоматическая генерация:
# - SQLAlchemy models
# - Pydantic schemas
# - FastAPI endpoints
# - Admin UI
...
# cifra/core/fields.py
class StringField(BaseField):
field_type = "string"
class EmailField(StringField):
validators = [EmailValidator()]
class UUIDField(BaseField):
field_type = "uuid"
2. CIFRA CLI:
cifra init my-app # Создать новое приложение
cifra generate config.cifra # Генерация кода
cifra run config.cifra # Запуск приложения
cifra migrate # Миграции БД
3. CIFRA Studio (GUI):
- Визуальный редактор конфигураций
- Drag-and-drop компоновка модулей
- Preview изменений
Шаблоны приложений в формате .cifra файлов.
Это готовые конфигурации для типовых задач (CRM, ERP, Admin Panel, E-commerce).
# crm.cifra - Конфигурация CRM системы
project:
name: "CRM System"
type: "crm"
version: "1.0.0"
# Какие модули используются
modules:
- id: auth
source: "cifra.core.auth"
- id: contacts
source: "cifra.modules.contacts"
entities: [Contact, Company]
- id: deals
source: "cifra.modules.deals"
entities: [Deal, Pipeline]
- id: tasks
source: "cifra.modules.tasks"
entities: [Task, TaskComment]
# Какие компоненты собраны
components:
- id: crm_core
modules: [auth, contacts, deals, tasks]
theme: admin_classic
# Схемы данных
entities:
Contact:
fields:
first_name: {type: string, required: true}
last_name: {type: string, required: true}
email: {type: email, unique: true}
phone: {type: phone}
company: {type: reference, entity: Company}
Deal:
fields:
title: {type: string, required: true}
amount: {type: decimal, precision: 10, scale: 2}
stage: {type: enum, options: [lead, qualified, proposal, won, lost]}
contact: {type: reference, entity: Contact}
expected_close_date: {type: date}
# Бизнес-процессы
processes:
- id: deal_lifecycle
entity: Deal
steps:
- create_lead
- qualify
- send_proposal
- negotiate
- close_won
# UI конфигурация
ui:
navigation:
- label: "Контакты"
path: /contacts
icon: users
- label: "Сделки"
path: /deals
icon: briefcase
dashboards:
- id: sales_dashboard
widgets:
- type: metric
entity: Deal
aggregation: sum
field: amount
1. admin_panel.cifra - Голая админка + аналитика
project:
type: admin_panel
modules: [auth, users, roles, audit_log, analytics]
components:
- admin_core:
modules: [auth, users, roles]
features: [crud, filters, search]
- analytics:
modules: [analytics]
features: [charts, reports, dashboards]
2. cms.cifra - Система управления контентом
project:
type: cms
modules: [auth, content, media, menus, blocks, taxonomies, views]
entities:
Article:
fields:
title: {type: string}
body: {type: text, wysiwyg: true}
author: {type: reference, entity: User}
category: {type: taxonomy, vocabulary: article_categories}
3. ecommerce.cifra - Интернет-магазин
project:
type: ecommerce
modules: [auth, products, cart, orders, payments, delivery]
entities:
Product:
fields:
name: {type: string}
price: {type: decimal}
images: {type: media, multiple: true}
category: {type: taxonomy}
Order:
fields:
customer: {type: reference, entity: User}
items: {type: collection, entity: OrderItem}
total: {type: decimal}
status: {type: enum, options: [pending, paid, shipped, delivered]}
Параметры конкретного экземпляра приложения.
Это индивидуальные настройки, которые делает каждый пользователь для СВОЕЙ копии CRM или Admin Panel.
# instance_settings.yaml - Настройки экземпляра
# Базовая информация
instance:
id: "crm-acme-corp"
name: "ACME Corp CRM"
based_on: "crm.cifra" # Используем готовую конфигурацию
version: "1.0.0"
created_at: "2025-11-10T10:00:00Z"
owner: "admin@acme.com"
# Какие модули ВКЛЮЧЕНЫ
enabled_modules:
- auth: {enabled: true}
- contacts: {enabled: true}
- deals: {enabled: true}
- tasks: {enabled: true}
- invoices: {enabled: false} # ОТКЛЮЧИЛИ этот модуль
- reports: {enabled: true}
# Настройки модулей
module_settings:
auth:
allow_registration: true
require_email_verification: true
password_min_length: 8
oauth_providers: [google, github]
contacts:
default_view: "table"
items_per_page: 25
export_formats: [csv, xlsx, pdf]
deals:
stages: [lead, qualified, proposal, negotiation, won, lost]
default_currency: "RUB"
enable_forecasting: true
# Тема оформления
theme:
selected: "admin_material" # Выбрали Material Design
primary_color: "#1976D2"
secondary_color: "#FF5722"
logo: "/uploads/acme-logo.png"
favicon: "/uploads/acme-favicon.ico"
# Кастомизация UI
ui_customization:
navigation:
- label: "Контакты"
path: /contacts
icon: users
visible: true
- label: "Сделки"
path: /deals
icon: briefcase
visible: true
- label: "Счета" # ДОБАВИЛИ свой пункт меню
path: /invoices
icon: file-text
visible: false # Скрыли, т.к. модуль отключен
dashboard:
widgets:
- type: deals_pipeline
position: {row: 1, col: 1}
size: {width: 2, height: 1}
- type: sales_chart
position: {row: 1, col: 3}
size: {width: 1, height: 1}
# Кастомные поля
custom_fields:
Contact:
- name: telegram
type: string
label: "Telegram"
required: false
- name: lead_source
type: enum
options: [website, referral, cold_call, event]
label: "Источник лида"
# Интеграции
integrations:
- service: sendgrid
enabled: true
api_key: "{env.SENDGRID_API_KEY}"
- service: stripe
enabled: false
# Безопасность
security:
roles:
- name: sales_rep
permissions:
Contact: [read, create, update:own]
Deal: [read, create, update:own]
- name: sales_manager
permissions:
Contact: [read, create, update, delete]
Deal: [read, create, update, delete]
Report: [read]
# Workflow правила
workflows:
- trigger: {entity: Deal, event: created}
condition: "deal.amount > 100000"
actions:
- notify: {user: sales_manager, message: "Крупная сделка создана"}
- trigger: {entity: Deal, event: stage_changed}
condition: "deal.stage == 'won'"
actions:
- create: {entity: Invoice, from: deal}
- email: {to: deal.contact.email, template: congratulations}
Компания A (строгая CRM):
instance_settings:
deals:
approval_required: true # Сделки требуют одобрения
stages: [lead, qualified, proposal, approved, won, lost]
security:
force_2fa: true # Обязательная двухфакторная аутентификация
Компания B (гибкая CRM):
instance_settings:
deals:
approval_required: false # Сделки без одобрения
stages: [new, working, closed]
security:
force_2fa: false
Реальные данные, которые создают пользователи приложения в процессе работы.
Это контент, который хранится в БД.
-- Таблица contacts (создана из Entity Contact)
INSERT INTO contacts (id, first_name, last_name, email, phone, company_id) VALUES
('550e8400-...', 'Иван', 'Петров', 'ivan@example.com', '+79001234567', '660e9500-...'),
('660e9500-...', 'Мария', 'Сидорова', 'maria@example.com', '+79007654321', NULL);
-- Таблица deals (создана из Entity Deal)
INSERT INTO deals (id, title, amount, stage, contact_id, expected_close_date) VALUES
('770ea600-...', 'Внедрение CRM', 500000.00, 'proposal', '550e8400-...', '2025-12-01'),
('880eb700-...', 'Консалтинг', 150000.00, 'qualified', '660e9500-...', '2025-11-20');
-- Таблица tasks (создана из Entity Task)
INSERT INTO tasks (id, title, description, assignee_id, due_date, status) VALUES
('990ec800-...', 'Позвонить клиенту', 'Обсудить условия договора', 'user-123', '2025-11-11', 'pending'),
('aa0ed900-...', 'Подготовить презентацию', NULL, 'user-456', '2025-11-15', 'in_progress');
1. CRM - Контакты и Сделки:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"first_name": "Иван",
"last_name": "Петров",
"email": "ivan@example.com",
"phone": "+79001234567",
"company": {
"id": "660e9500-...",
"name": "ООО Рога и Копыта"
},
"deals": [
{
"id": "770ea600-...",
"title": "Внедрение CRM",
"amount": 500000.00,
"stage": "proposal"
}
],
"created_at": "2025-01-15T10:30:00Z",
"updated_at": "2025-11-10T14:20:00Z"
}
2. E-commerce - Товары и Заказы:
{
"id": "product-001",
"name": "iPhone 15 Pro",
"price": 89990.00,
"category": "Смартфоны",
"stock": 25,
"images": [
"/media/iphone-15-pro-1.jpg",
"/media/iphone-15-pro-2.jpg"
]
}
{
"id": "order-12345",
"customer": {
"id": "user-789",
"name": "Анна Иванова",
"email": "anna@example.com"
},
"items": [
{
"product_id": "product-001",
"quantity": 1,
"price": 89990.00
}
],
"total": 89990.00,
"status": "paid",
"created_at": "2025-11-10T15:45:00Z"
}
3. CMS - Статьи:
{
"id": "article-567",
"title": "Как выбрать CRM систему",
"body": "<p>В этой статье мы расскажем...</p>",
"author": {
"id": "user-123",
"name": "Алексей Смирнов"
},
"category": "Бизнес",
"tags": ["CRM", "Бизнес", "Продажи"],
"published_at": "2025-11-01T09:00:00Z",
"views": 1523
}
УРОВЕНЬ 1 (Платформа) - определяет ВОЗМОЖНОСТИ
↓
УРОВЕНЬ 2 (Конфигурация) - выбирает ЧТО использовать
↓
УРОВЕНЬ 3 (Настройки) - настраивает КАК использовать
↓
УРОВЕНЬ 4 (Данные) - создает КОНТЕНТ
Уровень 1 (Платформа):
# cifra/core/fields.py
class EmailField(StringField):
"""Поле для email с валидацией"""
field_type = "email"
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.validators.append(EmailValidator())
def to_sqlalchemy(self):
return sa.Column(sa.String(255), nullable=not self.required)
def to_pydantic(self):
return (EmailStr, ...) # Pydantic EmailStr validation
Уровень 2 (Конфигурация):
# crm.cifra
entities:
Contact:
fields:
email:
type: email # ← Используем EmailField из платформы
required: true
unique: true
label: "Email адрес"
Уровень 3 (Настройки):
# instance_settings.yaml
custom_fields:
Contact:
- name: backup_email # ← Добавляем ВТОРОЙ email
type: email
label: "Запасной Email"
required: false
validation_rules:
Contact.email:
- check: unique # ← Проверка уникальности
- check: not_disposable # ← Запрет одноразовых email
Уровень 4 (Данные):
-- contacts table
INSERT INTO contacts (id, email, backup_email) VALUES
('uuid-1', 'ivan@company.com', 'ivan.personal@gmail.com'),
('uuid-2', 'maria@company.com', NULL);
Создание новой конфигурации:
# Используем CIFRA CLI
cifra init my-crm --template crm
# Результат: my-crm.cifra файл
Создание экземпляра:
# Генерация кода из конфигурации
cifra generate my-crm.cifra
# Создается:
# - SQLAlchemy models
# - Pydantic schemas
# - FastAPI endpoints
# - Admin UI
# - БД (PostgreSQL)
# - instance_settings.yaml
Создание данных:
# Запуск приложения
cifra run my-crm.cifra
# Пользователи создают данные через UI:
# - Добавляют контакты
# - Создают сделки
# - Загружают файлы
Уровень 4 → файлы:
# Экспорт пользовательских данных
cifra export data --format json > data.json
cifra export data --format csv --entity Contact > contacts.csv
Уровень 3 → файл:
# Экспорт настроек экземпляра
cifra export settings > instance_settings.yaml
Уровень 2 → файл:
# Уже есть файл (my-crm.cifra)
Шаг 1: Платформа (разработчики CIFRA добавляют модуль)
# cifra/modules/invoices.py
class InvoiceModule(BaseModule):
entities = [Invoice, InvoiceItem, Payment]
Шаг 2: Конфигурация (обновляем crm.cifra)
modules:
- id: invoices
source: "cifra.modules.invoices"
entities: [Invoice, InvoiceItem, Payment]
Шаг 3: Настройки (пользователь включает модуль)
enabled_modules:
- invoices: {enabled: true}
module_settings:
invoices:
default_currency: "RUB"
payment_methods: [bank_transfer, credit_card]
Шаг 4: Данные (пользователь создает счета)
INSERT INTO invoices (id, number, customer_id, total) VALUES
('inv-001', 'INV-2025-001', 'customer-123', 50000.00);
Шаг 1: Платформа (поле существует)
class PhoneField(StringField):
field_type = "phone"
Шаг 2: Конфигурация (поле определено в Entity)
entities:
Contact:
fields:
phone: {type: phone}
Шаг 3: Настройки (пользователь добавляет второй телефон)
custom_fields:
Contact:
- name: mobile_phone
type: phone
label: "Мобильный"
- name: work_phone
type: phone
label: "Рабочий"
Шаг 4: Данные (пользователь заполняет)
{
"phone": "+79001234567",
"mobile_phone": "+79001234567",
"work_phone": "+74951234567"
}
Шаг 1: Платформа (используем как есть)
Шаг 2: Конфигурация (создаем library.cifra)
project:
name: "Library Management"
entities:
Book:
fields:
title: {type: string}
author: {type: string}
isbn: {type: string, unique: true}
available: {type: boolean, default: true}
Reader:
fields:
name: {type: string}
email: {type: email}
card_number: {type: string, unique: true}
Loan:
fields:
book: {type: reference, entity: Book}
reader: {type: reference, entity: Reader}
borrowed_at: {type: datetime}
due_date: {type: date}
returned_at: {type: datetime, nullable: true}
processes:
- id: book_loan
steps:
- check_availability
- create_loan
- send_reminder_email # За день до due_date
- process_return
Шаг 3: Настройки (библиотека настраивает)
module_settings:
loans:
loan_period_days: 14
max_books_per_reader: 3
late_fee_per_day: 10.00
reminder_days_before: 1
Шаг 4: Данные (библиотекари работают)
INSERT INTO books (id, title, author, isbn) VALUES
('book-1', '1984', 'George Orwell', '978-0451524935');
INSERT INTO loans (id, book_id, reader_id, borrowed_at, due_date) VALUES
('loan-1', 'book-1', 'reader-123', '2025-11-10', '2025-11-24');
Где хранится:
/opt/cifra/ # Установка CIFRA
├── core/ # Ядро
│ ├── entity.py # EntityMeta
│ ├── fields.py # Поля
│ └── api.py # API
├── modules/ # Встроенные модули
│ ├── auth/
│ ├── contacts/
│ └── deals/
├── engines/ # Движки
│ ├── process_engine.py
│ ├── theme_engine.py
│ └── security_manager.py
└── cli/ # CIFRA CLI
└── main.py
Как обновляется:
pip install --upgrade cifra
Где хранится:
/opt/cifra/templates/ # Встроенные шаблоны
├── crm.cifra
├── erp.cifra
├── admin_panel.cifra
└── ecommerce.cifra
~/.cifra/hub/ # Загруженные из CIFRA Hub
├── advanced-crm.cifra
└── custom-erp.cifra
/my-project/ # Пользовательские
└── my-custom-app.cifra
Как создаются:
# Из шаблона
cifra init my-app --template crm
# С нуля
cifra init my-app --blank
# Из Hub
cifra hub install advanced-crm
Где хранится:
/my-project/
├── my-app.cifra # Конфигурация (readonly)
├── instance_settings.yaml # Настройки (редактируются)
├── .env # Секреты
└── generated/ # Сгенерированный код
├── models/
├── schemas/
└── api/
Как изменяются:
# Через CLI
cifra config set theme admin_material
# Через API
PATCH /api/settings
{
"theme": "admin_material"
}
# Через Admin UI
https://my-app.com/admin/settings
Где хранится:
PostgreSQL Database:
├── contacts # Таблица
├── deals
├── tasks
└── ...
Redis Cache:
├── session:user-123
├── cache:deals-list
└── ...
File Storage:
/my-project/uploads/
├── avatars/
├── documents/
└── media/
Как создаются:
# Через API
POST /api/contacts
{
"first_name": "Ivan",
"email": "ivan@example.com"
}
# Через Admin UI
https://my-app.com/admin/contacts/create
# Импорт
cifra import contacts.csv
Уровень 1 → Уровень 2:
- ❌ Конфигурации НЕ МОГУТ изменить код платформы
- ✅ Конфигурации МОГУТ использовать любые возможности платформы
Уровень 2 → Уровень 3:
- ❌ Настройки НЕ МОГУТ изменить базовую конфигурацию
- ✅ Настройки МОГУТ расширить конфигурацию (custom fields)
- ✅ Настройки МОГУТ отключить модули
Уровень 3 → Уровень 4:
- ❌ Данные НЕ МОГУТ изменить структуру
- ✅ Данные ПОДЧИНЯЮТСЯ правилам валидации
Безопасное выполнение кастомного кода:
# instance_settings.yaml
custom_validators:
Contact:
email:
function: |
# ✅ БЕЗОПАСНО: ограниченный Python
def validate(value):
if '@' not in value:
raise ValidationError("Invalid email")
return True
# ❌ ЗАПРЕЩЕНО:
# - import os
# - exec()
# - __import__()
# - file I/O
# - network calls
Механизм изоляции:
# cifra/core/sandbox.py
class SafeExecutor:
"""Безопасное выполнение пользовательского кода"""
ALLOWED_BUILTINS = ['len', 'str', 'int', 'float', 'bool', 'list', 'dict']
def execute(self, code: str, context: dict):
# Удаляем опасные builtins
safe_globals = {
'__builtins__': {k: __builtins__[k] for k in self.ALLOWED_BUILTINS}
}
# Выполняем с timeout
with timeout(seconds=1):
exec(code, safe_globals, context)
cifra --version
# CIFRA v1.0.0
# Обновление
pip install cifra==2.0.0
# Совместимость
cifra check-compatibility my-app.cifra
# ✅ Compatible with CIFRA v2.0.0
# crm-v1.0.0.cifra
project:
version: "1.0.0"
requires_cifra: ">=1.0.0,<2.0.0"
Миграция конфигурации:
cifra migrate my-app.cifra --from 1.0.0 --to 2.0.0
# instance_settings.yaml
version: 1
# При изменении структуры настроек:
# version: 2
Alembic миграции:
# Создать миграцию
cifra migrate create "add_backup_email_field"
# Применить
cifra migrate up
# Откат
cifra migrate down
Один экземпляр платформы → много клиентов:
УРОВЕНЬ 1: ПЛАТФОРМА (одна)
↓
УРОВЕНЬ 2: КОНФИГУРАЦИЯ CRM (одна)
↓
УРОВЕНЬ 3: НАСТРОЙКИ
├── Клиент A (instance-a.yaml)
├── Клиент B (instance-b.yaml)
└── Клиент C (instance-c.yaml)
↓
УРОВЕНЬ 4: ДАННЫЕ
├── БД Клиента A (schema: tenant_a)
├── БД Клиента B (schema: tenant_b)
└── БД Клиента C (schema: tenant_c)
Изоляция данных:
# Все запросы автоматически фильтруются по tenant_id
class TenantMiddleware:
async def __call__(self, request):
tenant_id = request.headers.get('X-Tenant-ID')
# Все Entity запросы получат фильтр
with tenant_context(tenant_id):
return await self.app(request)
# SELECT * FROM contacts WHERE tenant_id = 'tenant-a'
# cifra/core/registry.py
class EntityRegistry:
"""Регистр всех Entity классов"""
@classmethod
def get(cls, name: str) -> Type[BaseEntity]:
return cls._registry[name]
@classmethod
def list(cls) -> List[str]:
return list(cls._registry.keys())
# Использование в конфигурации
entity_class = EntityRegistry.get('Contact')
# cifra/core/settings.py
class InstanceSettings:
"""Управление настройками экземпляра"""
def __init__(self, config_path: str, settings_path: str):
self.config = self.load_config(config_path)
self.settings = self.load_settings(settings_path)
def get(self, key: str, default=None):
# Сначала в settings, потом в config, потом default
return self.settings.get(key) or self.config.get(key) or default
def set(self, key: str, value):
self.settings[key] = value
self.save_settings()
# Использование
settings = InstanceSettings('crm.cifra', 'instance_settings.yaml')
theme = settings.get('theme', default='admin_classic')
# cifra/core/entity_manager.py
class EntityManager:
"""CRUD операции с учетом настроек"""
def __init__(self, entity_class: Type[BaseEntity], settings: InstanceSettings):
self.entity_class = entity_class
self.settings = settings
async def create(self, data: dict):
# Применяем кастомные валидаторы из настроек
for field, value in data.items():
validators = self.settings.get(f'custom_validators.{self.entity_class.__name__}.{field}', [])
for validator in validators:
validator(value)
# Применяем кастомные поля
custom_fields = self.settings.get(f'custom_fields.{self.entity_class.__name__}', [])
# Создаем запись
instance = self.entity_class(**data)
await instance.save()
# Выполняем workflows
workflows = self.settings.get('workflows', [])
for workflow in workflows:
if workflow['trigger']['entity'] == self.entity_class.__name__:
await self.execute_workflow(workflow, instance)
return instance
4 уровня абстракции:
- Платформа (Core)
- Конфигурации (Templates)
- Настройки (Instance Settings)
- Данные (User Records)
Разделение ответственности:
- Каждый уровень решает СВОИ задачи
- Нижний уровень не зависит от верхнего
- Верхний уровень использует нижний
Изоляция:
- Изменения на верхнем уровне НЕ влияют на нижний
- Безопасность через песочницу
Версионирование:
- Каждый уровень версионируется независимо
- Миграции между версиями
Масштабирование:
- Multi-tenancy
- Shared nothing architecture
УРОВЕНЬ 1: ЯДРО ОС (Linux Kernel)
↓
УРОВЕНЬ 2: ДИСТРИБУТИВ (Ubuntu, Fedora)
↓
УРОВЕНЬ 3: НАСТРОЙКИ ПОЛЬЗОВАТЕЛЯ (dotfiles, preferences)
↓
УРОВЕНЬ 4: ПОЛЬЗОВАТЕЛЬСКИЕ ФАЙЛЫ (documents, photos)
УРОВЕНЬ 1: DRUPAL CORE
↓
УРОВЕНЬ 2: DISTRIBUTION (Drupal Commerce, OpenAtrium)
↓
УРОВЕНЬ 3: CONFIGURATION (enabled modules, theme settings)
↓
УРОВЕНЬ 4: CONTENT (nodes, users, taxonomy terms)
Реализация Уровня 1 (Platform Core):
- EntityMeta метакласс
- Базовые поля (StringField, EmailField, etc.)
- Entity API
- Module System
Создание Уровня 2 (Configuration Templates):
- admin_panel.cifra
- crm.cifra
- cms.cifra
Разработка Уровня 3 (Settings Manager):
- CRUD для настроек
- Admin UI для изменения
- Валидация настроек
Автогенерация Уровня 4 (Database Schema):
- Alembic миграции
- SQLAlchemy models
- CRUD endpoints
Версия: 1.0
Дата: 2025-11-10
Автор: CIFRA Architecture Team