architect/_archive/2025-11-cleanup/platform-v2-cifra/archive/2025-11-10-restructure-v2/UNIVERSAL_ENTITIES.md

Универсальные сущности и паттерны

Дата: 2025-11-10
Версия: 1.0.0
Цель: Концепции из Drupal, WordPress, Django и других продвинутых систем


КРАТКИЙ ОТВЕТ

15 универсальных концепций:

1. VIEWS (Представления) - создание списков без кода
2. TAXONOMIES (Таксономии) - классификация контента
3. MENUS (Меню) - навигация
4. BLOCKS/REGIONS (Блоки) - области контента
5. CONTENT TYPES (Типы контента) - шаблоны сущностей
6. MEDIA LIBRARY (Медиатека) - управление файлами
7. REVISIONS (Ревизии) - версионирование
8. COMMENTS (Комментарии) - обсуждения
9. SEARCH & FACETS (Поиск) - полнотекстовый поиск
10. ALIASES/SLUGS (ЧПУ) - красивые URL
11. REDIRECTS (Перенаправления) - 301/302
12. SEO METADATA (SEO) - мета-теги
13. CACHE STRATEGIES (Кэширование) - производительность
14. QUEUES (Очереди) - фоновые задачи
15. ACTIVITY LOG (Журнал) - история действий

Часть 1: VIEWS (Представления)

Концепция из Drupal

Views - самая мощная фича Drupal. Позволяет создавать списки/отчёты/галереи БЕЗ кода через UI.

Что такое View:

View = Query Builder + Display + Filters + Sorting + Formatting

Пример в CIFRA:

# views/recent_deals.view.cifra
view:
  id: recent_deals
  name: "Недавние сделки"
  description: "Список сделок за последние 30 дней"

  # БАЗА ДАННЫХ (что показываем)
  base_entity: Deal

  # FIELDS (какие поля показываем)
  fields:
    - field: title
      label: "Название сделки"
      sortable: true
      searchable: true

    - field: amount
      label: "Сумма"
      sortable: true
      format: currency

    - field: contact.full_name
      label: "Контакт"
      relationship: contact
      link: true
      link_path: /contacts/{contact.id}

    - field: stage
      label: "Этап"
      format: badge
      badge_colors:
        lead: gray
        proposal: blue
        won: green
        lost: red

    - field: created_at
      label: "Создана"
      sortable: true
      format: date_ago  # "3 дня назад"

  # FILTERS (фильтры)
  filters:
    # Exposed фильтры (видны пользователю)
    - field: stage
      type: select
      label: "Этап"
      options: auto  # Берём из enum
      exposed: true
      multiple: true

    - field: assigned_to
      type: entity_reference
      label: "Менеджер"
      entity: User
      exposed: true

    - field: created_at
      type: date_range
      label: "Дата создания"
      exposed: true

    # Скрытые фильтры (применяются всегда)
    - field: deleted_at
      operator: is_null
      exposed: false

  # SORT (сортировка по умолчанию)
  sorts:
    - field: created_at
      direction: DESC

  # RELATIONSHIPS (связи с другими entity)
  relationships:
    - id: contact
      entity: Contact
      field: contact_id
      required: false  # LEFT JOIN

    - id: company
      entity: Company
      through: contact  # Через contact
      field: company_id

  # PAGINATION
  pagination:
    type: pager
    items_per_page: 50
    expose_items_per_page: true
    options: [25, 50, 100]

  # DISPLAYS (как отображаем)
  displays:
    # Отображение как таблица
    - id: table
      type: table
      enabled: true
      path: /admin/deals
      menu:
        type: normal
        title: "Сделки"
        parent: admin

    # Отображение как REST API
    - id: rest_export
      type: rest_export
      enabled: true
      path: /api/views/recent-deals
      format: json
      authentication: jwt

    # Отображение как RSS
    - id: feed
      type: feed
      enabled: true
      path: /deals/feed.xml
      format: rss
      title_field: title
      description_field: description

    # Отображение как блок (можно встраивать)
    - id: block
      type: block
      enabled: true
      items_to_display: 5
      use_more_link: true
      more_link_path: /admin/deals

  # CONTEXTUAL FILTERS (фильтры из URL)
  contextual_filters:
    - field: assigned_to
      default_value: current_user
      when_empty: show_all

  # AGGREGATION (агрегация)
  aggregation:
    enabled: true
    group_by: [stage]
    aggregates:
      - field: amount
        function: sum
        label: "Общая сумма"

  # ACCESS (права доступа)
  access:
    permission: view_deals
    role: [sales_manager, sales_rep]

  # CACHING (кэширование)
  cache:
    type: time
    duration: 300  # 5 минут

Расширенный пример: Views с relationship

# views/deals_with_tasks.view.cifra
view:
  id: deals_with_tasks
  name: "Сделки с задачами"

  base_entity: Deal

  # Связь с задачами
  relationships:
    - id: tasks
      entity: Task
      field: deal_id
      type: reverse  # Обратная связь (Task → Deal)
      required: false

  fields:
    - field: title
      label: "Сделка"

    - field: tasks.title
      label: "Задача"
      relationship: tasks

    - field: tasks.status
      label: "Статус задачи"
      relationship: tasks

  # Показать только сделки, у которых есть открытые задачи
  filters:
    - field: tasks.status
      relationship: tasks
      operator: in
      value: [open, in_progress]

  # Группировка по сделкам
  aggregation:
    enabled: true
    group_by: [id, title]
    aggregates:
      - field: tasks.id
        function: count
        label: "Количество задач"

Часть 2: TAXONOMIES (Таксономии)

Концепция из Drupal/WordPress

Taxonomy - система классификации контента. Позволяет организовывать контент по категориям, тегам и т.д.

Структура таксономии:

Vocabulary (Словарь)
  └─ Terms (Термины)
      └─ Child Terms (Дочерние термины)

Пример в CIFRA:

# taxonomies/taxonomies.cifra
taxonomies:
  # Таксономия 1: Категории продуктов (иерархическая)
  - id: product_categories
    name: "Категории продуктов"
    type: hierarchical  # Может иметь вложенность
    description: "Классификация продуктов по категориям"

    # Настройки
    settings:
      multiple: false  # Продукт может быть только в одной категории
      required: true   # Обязательно выбрать категорию
      max_depth: 3     # Максимум 3 уровня вложенности

    # Поля термина (дополнительные данные)
    term_fields:
      - icon:
          type: image
          label: "Иконка категории"

      - description:
          type: text
          label: "Описание"

      - featured:
          type: boolean
          label: "Показывать на главной"
          default: false

      - seo_title:
          type: string
          label: "SEO заголовок"

      - seo_description:
          type: text
          label: "SEO описание"

    # Предустановленные термины
    terms:
      - id: electronics
        name: "Электроника"
        weight: 0
        children:
          - id: computers
            name: "Компьютеры"
            children:
              - id: laptops
                name: "Ноутбуки"
              - id: desktops
                name: "Настольные ПК"

          - id: phones
            name: "Телефоны"
            children:
              - id: smartphones
                name: "Смартфоны"
              - id: feature_phones
                name: "Кнопочные телефоны"

      - id: clothing
        name: "Одежда"
        weight: 1
        children:
          - id: mens
            name: "Мужская"
          - id: womens
            name: "Женская"
          - id: kids
            name: "Детская"

  # Таксономия 2: Теги (плоская структура)
  - id: tags
    name: "Теги"
    type: flat  # Без иерархии
    description: "Ключевые слова для контента"

    settings:
      multiple: true  # Можно выбрать много тегов
      required: false
      allow_create: true  # Пользователь может создавать новые теги

    term_fields:
      - color:
          type: color
          label: "Цвет тега"
          default: "#3B82F6"

  # Таксономия 3: Статусы (custom taxonomy)
  - id: deal_statuses
    name: "Статусы сделок"
    type: flat

    settings:
      multiple: false
      required: true
      allow_create: false  # Только предустановленные

    term_fields:
      - color:
          type: color
          label: "Цвет"

      - icon:
          type: string
          label: "Иконка"

      - weight:
          type: integer
          label: "Порядок"
          default: 0

    terms:
      - {id: lead, name: "Лид", color: "#gray", icon: "user-plus", weight: 0}
      - {id: qualification, name: "Квалификация", color: "#blue", weight: 1}
      - {id: proposal, name: "Предложение", color: "#yellow", weight: 2}
      - {id: negotiation, name: "Переговоры", color: "#orange", weight: 3}
      - {id: won, name: "Выиграна", color: "#green", icon: "check", weight: 4}
      - {id: lost, name: "Проиграна", color: "#red", icon: "x", weight: 5}

# Привязка таксономий к entities
entities:
  Product:
    fields:
      # Связь с иерархической таксономией
      category:
        type: taxonomy_term
        vocabulary: product_categories
        required: true

      # Связь с тегами (множественная)
      tags:
        type: taxonomy_term
        vocabulary: tags
        multiple: true
        widget: autocomplete

  BlogPost:
    fields:
      categories:
        type: taxonomy_term
        vocabulary: blog_categories
        multiple: true
        widget: checkboxes

      tags:
        type: taxonomy_term
        vocabulary: tags
        multiple: true
        widget: tags_input  # Инпут с тегами

  Deal:
    fields:
      status:
        type: taxonomy_term
        vocabulary: deal_statuses
        widget: select

# Views с таксономией
views:
  - id: products_by_category
    base_entity: Product

    # Контекстный фильтр по категории
    contextual_filters:
      - field: category
        type: taxonomy_term
        validate: true
        breadcrumb: true  # Показывать в хлебных крошках

    # Группировка по категории
    aggregation:
      enabled: true
      group_by: [category.name]

API для работы с таксономиями:

# Python API
from cifra import taxonomy

# Получить термины таксономии
categories = taxonomy.get_vocabulary('product_categories')

# Создать новый термин
new_category = taxonomy.create_term(
    vocabulary='product_categories',
    name='Аксессуары',
    parent='electronics'
)

# Получить все термины с детьми (дерево)
tree = taxonomy.get_tree('product_categories')

# Привязать термин к entity
product.category = taxonomy.get_term('laptops')
product.save()

# Получить все продукты в категории (включая подкатегории)
products = Product.query.filter(
    category=taxonomy.get_term_with_children('electronics')
)

# Получить breadcrumbs (хлебные крошки)
breadcrumbs = taxonomy.get_breadcrumbs('laptops')
# → [Электроника, Компьютеры, Ноутбуки]

Часть 3: MENUS (Меню навигации)

Концепция из Drupal/WordPress

# menus/site_menus.cifra
menus:
  # Главное меню
  - id: main_menu
    name: "Главное меню"
    description: "Основная навигация сайта"

    items:
      - id: home
        title: "Главная"
        url: /
        weight: 0
        icon: home

      - id: catalog
        title: "Каталог"
        url: /catalog
        weight: 1
        icon: shopping-bag
        children:
          - id: electronics
            title: "Электроника"
            url: /catalog/electronics
            weight: 0

          - id: clothing
            title: "Одежда"
            url: /catalog/clothing
            weight: 1

      - id: about
        title:  компании"
        url: /about
        weight: 2

      - id: contacts
        title: "Контакты"
        url: /contacts
        weight: 3

    # Настройки отображения
    settings:
      max_depth: 2
      expanded: true  # Раскрыть все подменю
      show_icons: true

  # Меню в футере
  - id: footer_menu
    name: "Меню в подвале"
    items:
      - {title: "Политика конфиденциальности", url: /privacy}
      - {title: "Условия использования", url: /terms}
      - {title: "Помощь", url: /help}

  # Административное меню
  - id: admin_menu
    name: "Административное меню"
    access: [admin, manager]

    items:
      - title: "Панель управления"
        url: /admin
        icon: dashboard

      - title: "Контент"
        url: /admin/content
        icon: file-text
        children:
          - {title: "Контакты", url: /admin/contacts}
          - {title: "Сделки", url: /admin/deals}
          - {title: "Продукты", url: /admin/products}

      - title: "Настройки"
        url: /admin/settings
        icon: settings

# Динамическое меню (генерируется из таксономии)
menus:
  - id: categories_menu
    name: "Меню категорий"
    type: dynamic
    source: taxonomy
    vocabulary: product_categories
    max_depth: 2
    url_pattern: /catalog/{term.slug}

Часть 4: BLOCKS & REGIONS (Блоки и области)

Концепция из Drupal

# blocks/site_blocks.cifra
blocks:
  # Блок с недавними статьями
  - id: recent_articles
    name: "Недавние статьи"
    type: view
    view: recent_blog_posts
    display: block

    settings:
      title: "Последние новости"
      items_to_display: 5
      cache: 300  # 5 минут

    visibility:
      pages:
        include: ["/", "/blog", "/blog/*"]
        exclude: ["/blog/archive"]
      roles: ["*"]  # Все роли

  # Блок с HTML контентом
  - id: promo_banner
    name: "Промо-баннер"
    type: html
    content: |
      <div class="promo-banner">
        <h2>Скидка 20% на всё!</h2>
        <p>До конца месяца</p>
        <a href="/sale" class="btn">Купить</a>
      </div>

    visibility:
      pages:
        include: ["/"]
      date_range:
        start: "2025-11-01"
        end: "2025-11-30"

  # Блок с формой поиска
  - id: search_form
    name: "Форма поиска"
    type: form
    form: search_form

  # Блок с меню
  - id: main_nav
    name: "Главная навигация"
    type: menu
    menu: main_menu

# Регионы (области на странице)
regions:
  - id: header
    name: "Шапка"
    blocks: [main_nav, search_form]

  - id: sidebar_left
    name: "Левая колонка"
    blocks: [categories_menu, recent_articles]

  - id: content
    name: "Основной контент"
    # Сюда идёт основной контент страницы

  - id: sidebar_right
    name: "Правая колонка"
    blocks: [promo_banner]

  - id: footer
    name: "Подвал"
    blocks: [footer_menu, contacts_block]

# Layout (раскладка страницы)
layouts:
  - id: two_column
    name: "Две колонки"
    template: |
      <div class="layout-two-column">
        <header>{{ region('header') }}</header>
        <div class="main-wrapper">
          <aside class="sidebar-left">{{ region('sidebar_left') }}</aside>
          <main>{{ region('content') }}</main>
        </div>
        <footer>{{ region('footer') }}</footer>
      </div>

  - id: three_column
    name: "Три колонки"
    template: |
      <div class="layout-three-column">
        <header>{{ region('header') }}</header>
        <div class="main-wrapper">
          <aside class="sidebar-left">{{ region('sidebar_left') }}</aside>
          <main>{{ region('content') }}</main>
          <aside class="sidebar-right">{{ region('sidebar_right') }}</aside>
        </div>
        <footer>{{ region('footer') }}</footer>
      </div>

Часть 5: CONTENT TYPES / BUNDLES (Типы контента)

Концепция из Drupal

# content_types/content_types.cifra
content_types:
  # Тип контента: Статья блога
  - id: blog_post
    name: "Статья блога"
    entity: Node  # Базовая entity
    description: "Статья для блога компании"

    # Поля этого типа контента
    fields:
      - title:
          type: string
          label: "Заголовок"
          required: true
          max_length: 255

      - body:
          type: rich_text
          label: "Содержание"
          required: true

      - summary:
          type: text
          label: "Анонс"
          max_length: 500

      - featured_image:
          type: image
          label: "Изображение"
          allowed_formats: [jpg, png, webp]
          max_size: 2MB

      - category:
          type: taxonomy_term
          vocabulary: blog_categories
          label: "Категория"
          required: true

      - tags:
          type: taxonomy_term
          vocabulary: tags
          label: "Теги"
          multiple: true

      - author:
          type: entity_reference
          entity: User
          label: "Автор"
          default: current_user

      - published_at:
          type: datetime
          label: "Дата публикации"
          default: now

      - seo_title:
          type: string
          label: "SEO заголовок"
          max_length: 70

      - seo_description:
          type: text
          label: "SEO описание"
          max_length: 160

    # Настройки отображения
    display:
      full:
        # Полное отображение статьи
        template: blog_post_full
        fields:
          - featured_image: {format: large}
          - title: {format: h1}
          - author: {format: link}
          - published_at: {format: "d F Y"}
          - body: {format: html}
          - tags: {format: links}

      teaser:
        # Анонс статьи (для списков)
        template: blog_post_teaser
        fields:
          - featured_image: {format: medium, link: true}
          - title: {format: h3, link: true}
          - summary: {format: plain}
          - read_more: {label: "Читать далее", link: true}

    # URL pattern
    url_pattern: /blog/{year}/{month}/{slug}

    # Комментарии
    comments:
      enabled: true
      moderation: true
      threading: true
      max_depth: 3

    # Workflow (статусы публикации)
    workflow:
      states: [draft, review, published, archived]
      default_state: draft

    # Права доступа
    permissions:
      create: [editor, admin]
      edit_own: [author, editor, admin]
      edit_any: [admin]
      delete_own: [author, editor, admin]
      delete_any: [admin]

  # Тип контента: Продукт
  - id: product
    name: "Продукт"
    entity: Node

    fields:
      - name: {type: string, required: true}
      - sku: {type: string, unique: true, required: true}
      - description: {type: rich_text}
      - price: {type: decimal, required: true}
      - images: {type: image, multiple: true, max: 10}
      - category: {type: taxonomy_term, vocabulary: product_categories}
      - specifications: {type: key_value, label: "Характеристики"}

    display:
      full:
        template: product_full
      teaser:
        template: product_card

    url_pattern: /product/{sku}

Часть 6: MEDIA LIBRARY (Медиатека)

# media/media_library.cifra
media:
  # Типы медиа
  types:
    - id: image
      name: "Изображение"
      allowed_extensions: [jpg, jpeg, png, gif, webp]
      max_size: 5MB

      # Автоматическая генерация размеров
      image_styles:
        - id: thumbnail
          width: 150
          height: 150
          mode: crop

        - id: medium
          width: 600
          height: 400
          mode: scale

        - id: large
          width: 1200
          height: 800
          mode: scale

        - id: og_image  # Для social media
          width: 1200
          height: 630
          mode: crop

      # EXIF данные
      extract_metadata: true
      metadata_fields:
        - camera_model
        - focal_length
        - iso
        - aperture

    - id: document
      name: "Документ"
      allowed_extensions: [pdf, doc, docx, xls, xlsx, ppt, pptx]
      max_size: 10MB

      # Извлечение текста для поиска
      extract_text: true

    - id: video
      name: "Видео"
      allowed_extensions: [mp4, webm, avi, mov]
      max_size: 100MB

      # Генерация превью
      generate_thumbnail: true
      thumbnail_time: 5s  # Кадр на 5 секунде

    - id: audio
      name: "Аудио"
      allowed_extensions: [mp3, wav, ogg]
      max_size: 20MB

  # Хранилища
  storage:
    - id: local
      type: filesystem
      path: /var/www/media
      public_url: https://example.com/media

    - id: s3
      type: s3
      bucket: company-media
      region: eu-west-1
      cdn_url: https://cdn.example.com

  # Организация медиа
  folders:
    - id: products
      name: "Фото продуктов"
      storage: s3

    - id: blog
      name: "Изображения для блога"
      storage: local

    - id: documents
      name: "Документы"
      storage: s3

  # Права доступа
  permissions:
    upload: [editor, admin]
    edit: [editor, admin]
    delete: [admin]

  # Оптимизация
  optimization:
    images:
      compress: true
      quality: 85
      convert_to_webp: true
      strip_metadata: false  # Сохранить EXIF

    videos:
      compress: false
      generate_formats: [mp4, webm]

Часть 7: REVISIONS (Версионирование контента)

# revisions/content_revisions.cifra
revisions:
  # Какие entity версионируются
  enabled_entities:
    - Deal:
        track_changes: true
        store_full_copy: false  # Хранить только изменения
        max_revisions: 50

    - BlogPost:
        track_changes: true
        store_full_copy: true  # Хранить полную копию
        auto_save_interval: 30s  # Автосохранение каждые 30 секунд

    - Contract:
        track_changes: true
        store_full_copy: true
        require_revision_message: true  # Обязательный комментарий

  # Что отслеживается
  tracked_fields:
    Deal:
      - amount  # Изменения суммы
      - stage   # Изменения статуса
      - assigned_to  # Изменения ответственного

  # История изменений
  change_history:
    format: diff  # Показывать diff изменений
    show_user: true
    show_timestamp: true
    show_ip_address: true

  # Восстановление
  restore:
    enabled: true
    require_permission: restore_revisions
    notify_on_restore: true

# API для работы с версиями

Python API:

# Получить все версии
revisions = deal.get_revisions()

# Получить конкретную версию
old_version = deal.get_revision(revision_id=5)

# Сравнить версии
diff = deal.compare_revisions(revision_a=5, revision_b=7)

# Откатиться к версии
deal.restore_revision(revision_id=5, message="Откат к версии от 10.11")

# История изменений
history = deal.get_change_history()
# → [
#   {user: "Ivan", time: "2025-11-10 15:30", changes: {amount: 10000 → 15000}},
#   {user: "Petr", time: "2025-11-10 14:20", changes: {stage: "lead" → "proposal"}}
# ]

Часть 8: COMMENTS (Комментарии)

# comments/comment_system.cifra
comments:
  # На каких entities разрешены комментарии
  enabled_entities:
    - BlogPost:
        mode: threaded  # Древовидные комментарии
        max_depth: 5
        order: newest_first
        moderation: false
        anonymous_allowed: true
        edit_time_limit: 15m  # Можно редактировать 15 минут

    - Deal:
        mode: flat  # Плоский список
        moderation: false
        anonymous_allowed: false
        mentions_enabled: true  # @username упоминания
        attachments_enabled: true

    - Task:
        mode: threaded
        max_depth: 3
        real_time_updates: true  # WebSocket обновления

  # Поля комментария
  comment_fields:
    - author: {type: user, required: true}
    - body: {type: rich_text, required: true}
    - created_at: {type: datetime, auto: true}
    - updated_at: {type: datetime, auto: true}
    - parent: {type: comment, nullable: true}  # Для вложенных
    - attachments: {type: file, multiple: true}

  # Модерация
  moderation:
    enabled: true
    auto_approve_registered: true
    auto_approve_threshold: 10  # После 10 одобренных - автоодобрение
    spam_filter: akismet
    require_email: true

  # Уведомления
  notifications:
    on_new_comment:
      notify: [content_author, parent_comment_author]
      channels: [email, in_app]

    on_mention:
      notify: [mentioned_user]
      channels: [email, in_app, push]

  # Реакции (лайки)
  reactions:
    enabled: true
    types: [like, love, helpful, insightful]

Часть 9: SEARCH & FACETS (Поиск с фасетами)

# search/search_config.cifra
search:
  # Поисковый движок
  engine: elasticsearch  # или: meilisearch, typesense, algolia

  connection:
    host: elasticsearch.example.com
    port: 9200
    index_prefix: cifra_

  # Индексируемые entities
  indexed_entities:
    - Product:
        fields:
          - name: {boost: 3}  # Название важнее
          - description: {boost: 1}
          - category.name: {boost: 2}
          - tags.name: {boost: 1}

        settings:
          analyzer: russian  # Морфология русского языка
          suggest: true  # Автодополнение

    - BlogPost:
        fields:
          - title: {boost: 3}
          - body: {boost: 1}
          - tags.name: {boost: 2}

        settings:
          analyzer: russian
          highlight: true  # Подсветка найденного

  # Facets (фасеты для фильтрации)
  facets:
    Product:
      - field: category
        type: hierarchical
        label: "Категория"
        max_values: 100

      - field: price
        type: range
        label: "Цена"
        ranges:
          - {from: 0, to: 1000, label: "До 1000"}
          - {from: 1000, to: 5000, label: "1000-5000"}
          - {from: 5000, to: 10000, label: "5000-10000"}
          - {from: 10000, label: "Свыше 10000"}

      - field: brand
        type: terms
        label: "Бренд"
        max_values: 50

      - field: in_stock
        type: boolean
        label:  наличии"

      - field: rating
        type: range
        label: "Рейтинг"
        ranges:
          - {from: 4, label: "4+ звёзд"}
          - {from: 3, to: 4, label: "3-4 звезды"}

  # Поисковая страница
  search_page:
    path: /search
    results_per_page: 24
    sort_options:
      - {field: relevance, label: "По релевантности"}
      - {field: created_at, direction: desc, label: "Сначала новые"}
      - {field: price, direction: asc, label: "Сначала дешёвые"}
      - {field: price, direction: desc, label: "Сначала дорогие"}

    # Did you mean (подсказки)
    suggestions:
      enabled: true
      max_suggestions: 3

    # Автодополнение
    autocomplete:
      enabled: true
      min_chars: 3
      max_results: 10

Часть 10: ALIASES & SLUGS (ЧПУ - Человеко-Понятные URL)

# aliases/url_aliases.cifra
aliases:
  # Автоматическая генерация алиасов
  auto_generate:
    enabled: true

    patterns:
      BlogPost: /blog/{year}/{month}/{slug}
      Product: /product/{category.slug}/{slug}
      Deal: /deals/{id}
      Contact: /contacts/{id}

  # Генерация slug из названия
  slug:
    source_field: title  # Или name
    transliterate: true  # Транслитерация (кириллица → латиница)
    separator: "-"
    lowercase: true
    max_length: 100

    # Правила транслитерации
    transliteration:
      а: "a"
      б: "b"
      в: "v"
      # ... и т.д.

  # Уникальность
  unique:
    check: true
    on_conflict: append_number  # Добавить цифру: "my-post-2"

  # Редиректы при изменении
  redirects:
    create_on_change: true  # Создать редирект со старого URL
    redirect_type: 301  # Permanent redirect

Часть 11: REDIRECTS (Перенаправления)

# redirects/redirects.cifra
redirects:
  # Простые редиректы
  - from: /old-page
    to: /new-page
    type: 301  # Permanent

  - from: /temporary
    to: /other
    type: 302  # Temporary

  # Редиректы с wildcard
  - from: /old-blog/*
    to: /blog/*
    type: 301

  # Регулярные выражения
  - from: /product-(\d+)
    to: /products/$1
    type: 301
    regex: true

  # Условные редиректы
  - from: /special-offer
    to: /sale
    type: 302
    conditions:
      date_range:
        start: "2025-11-01"
        end: "2025-11-30"

  # Автоматические редиректы
  auto_redirects:
    on_url_change: true
    on_delete: false
    retention: 1y  # Хранить 1 год

Часть 12: SEO METADATA (SEO метаданные)

# seo/seo_settings.cifra
seo:
  # Глобальные настройки
  global:
    site_name: "Моя компания"
    default_title_suffix: " | Моя компания"
    default_description: "Лучшие товары и услуги"
    default_image: /images/og-default.jpg

  # Настройки для content types
  content_types:
    BlogPost:
      title_pattern: "{title} | Блог"
      description_source: summary
      image_source: featured_image
      canonical: auto

      # Open Graph
      open_graph:
        type: article
        article_author: "{author.name}"
        article_published_time: "{published_at}"

      # Twitter Card
      twitter_card:
        card: summary_large_image
        creator: "{author.twitter}"

    Product:
      title_pattern: "{name} - купить в {site_name}"
      description_pattern: "{name}. {short_description}. Цена: {price} руб."
      image_source: images[0]

      # Schema.org structured data
      schema:
        type: Product
        properties:
          name: "{name}"
          description: "{description}"
          image: "{images[0].url}"
          price: "{price}"
          priceCurrency: "RUB"
          availability: "{in_stock ? 'InStock' : 'OutOfStock'}"

  # Sitemap
  sitemap:
    enabled: true
    path: /sitemap.xml
    entities:
      - BlogPost: {priority: 0.8, changefreq: weekly}
      - Product: {priority: 0.9, changefreq: daily}
    exclude:
      - path: /admin/*
      - path: /user/*

  # Robots.txt
  robots:
    enabled: true
    path: /robots.txt
    content: |
      User-agent: *
      Disallow: /admin/
      Disallow: /api/
      Sitemap: https://example.com/sitemap.xml

Часть 13: CACHE STRATEGIES (Кэширование)

# cache/cache_config.cifra
cache:
  # Глобальные настройки
  default_ttl: 300  # 5 минут

  # Стратегии кэширования
  strategies:
    # Кэш для entity
    entity:
      enabled: true
      backend: redis
      ttl: 3600

      # Invalidation (когда сбрасывать)
      invalidate_on:
        - entity_update
        - entity_delete

    # Кэш для views
    view:
      enabled: true
      backend: redis
      ttl: 300

      # Кэш на основе query
      cache_key:
        - view_id
        - display_id
        - filters
        - sort
        - page

    # HTTP кэш
    http:
      enabled: true
      public_paths: ["/", "/blog/*", "/products/*"]
      private_paths: ["/admin/*", "/user/*"]

      headers:
        Cache-Control: "public, max-age=300"
        Vary: "Accept-Encoding, Cookie"

    # CDN
    cdn:
      enabled: true
      provider: cloudflare
      purge_on:
        - entity_update
        - deployment

  # Backends
  backends:
    - id: redis
      type: redis
      host: redis.example.com
      port: 6379
      db: 0

    - id: memcached
      type: memcached
      servers: [memcached.example.com:11211]

  # Warming (прогрев кэша)
  warming:
    enabled: true
    cron: "0 */6 * * *"  # Каждые 6 часов
    urls:
      - /
      - /catalog
      - /blog

Часть 14: QUEUES & JOBS (Очереди и фоновые задачи)

# queues/queue_config.cifra
queues:
  # Определение очередей
  queues:
    - id: default
      priority: 0
      workers: 4
      retry: 3
      timeout: 300s

    - id: email
      priority: 10  # Высокий приоритет
      workers: 2
      retry: 5
      timeout: 60s

    - id: heavy
      priority: -10  # Низкий приоритет
      workers: 1
      retry: 1
      timeout: 3600s  # 1 час

  # Backend
  backend: redis
  connection:
    host: redis.example.com
    port: 6379

  # Типы задач
  jobs:
    # Отправка email
    - id: send_email
      queue: email
      handler: email_service.send
      retry: 5
      retry_delay: 60s

    # Генерация отчёта
    - id: generate_report
      queue: heavy
      handler: reports.generate
      timeout: 1800s

    # Импорт данных
    - id: import_csv
      queue: default
      handler: import.process_csv
      retry: 3

    # Обработка изображений
    - id: process_image
      queue: default
      handler: media.process_image
      batch: true  # Можно группировать
      batch_size: 10

  # Планировщик (cron)
  scheduled:
    - job: cleanup_old_files
      schedule: "0 2 * * *"  # 2:00 каждый день
      queue: default

    - job: send_daily_digest
      schedule: "0 9 * * *"  # 9:00 каждый день
      queue: email

Часть 15: ACTIVITY LOG (Журнал активности)

# activity/activity_log.cifra
activity_log:
  # Что логировать
  tracked_events:
    # CRUD операции
    - entity_created
    - entity_updated
    - entity_deleted

    # User actions
    - user_login
    - user_logout
    - user_password_changed

    # Бизнес-события
    - deal_won
    - deal_lost
    - order_shipped
    - payment_received

  # Форматирование сообщений
  messages:
    entity_created: "{user.name} создал(а) {entity_type} '{entity.label}'"
    entity_updated: "{user.name} обновил(а) {entity_type} '{entity.label}'"
    entity_deleted: "{user.name} удалил(а) {entity_type} '{entity.label}'"
    deal_won: "{user.name} выиграл(а) сделку '{deal.title}' на сумму {deal.amount}"

  # Хранение
  storage:
    backend: database
    table: activity_log
    retention: 180d  # Хранить 180 дней
    archive_to: s3  # Архивировать в S3

  # Доступ
  access:
    view_own: [user]
    view_team: [manager]
    view_all: [admin]

Заключение

Полная CIFRA спецификация теперь включает:

# complete_application.cifra

# 1. БАЗОВЫЕ КОМПОНЕНТЫ
entities: {...}
processes: {...}
rules: {...}
api: {...}

# 2. БЕЗОПАСНОСТЬ
security: {...}

# 3. UI/UX
ui: {...}
menus: {...}
blocks: {...}

# 4. КОНТЕНТ-СИСТЕМА (из CMS)
content_types: {...}      # ✅ НОВОЕ
taxonomies: {...}         # ✅ НОВОЕ
views: {...}              # ✅ НОВОЕ
media: {...}              # ✅ НОВОЕ
revisions: {...}          # ✅ НОВОЕ
comments: {...}           # ✅ НОВОЕ
aliases: {...}            # ✅ НОВОЕ
redirects: {...}          # ✅ НОВОЕ

# 5. ПОИСК И SEO
search: {...}             # ✅ НОВОЕ
seo: {...}                # ✅ НОВОЕ

# 6. ПРОИЗВОДИТЕЛЬНОСТЬ
cache: {...}              # ✅ НОВОЕ
queues: {...}             # ✅ НОВОЕ

# 7. МОНИТОРИНГ
activity_log: {...}       # ✅ НОВОЕ
integrations: {...}
notifications: {...}
reports: {...}
tests: {...}
deployment: {...}
localization: {...}
scheduling: {...}

Теперь CIFRA = Drupal + Django + WordPress + Custom App Builder! 🚀

Можно создать:
- CRM/ERP системы
- E-commerce магазины
- Блог-платформы
- Корпоративные порталы
- SaaS приложения
- И всё что угодно!

Все в одном формате .cifra 🎯