# Описания компонентов прикладного слоя

Источник поля `Documentation` у элементов `ApplicationComponent` в модели ArchiMate. Заголовок второго уровня — имя каталога в `apps/` либо идентификатор элемента для компонентов, которых в `apps/` нет.

Каждое описание построено на анализе исходного кода компонентных репозиториев: первый абзац — стек и репозитории, второй — назначение и место в продукте, третий — реализация и связи. Там, где доказательств в коде недостаточно, это отмечено явно.

Конкретные домены заменены на `<домен>` — файл коммитится в репозиторий и не должен содержать данных инсталляции.

## ams-sync

Репозитории: platform/ams-sync — синхронизация учётных записей с внешним провайдером идентификации; рядом лежит platform/ams без активности с апреля 2025. Стек: Python, чистая архитектура (`cmd` → `internal/app` → `controller` → `usecase` → `adapter`/`repository`), kafka-python (`KafkaConsumer`), requests с ретраями, PyJWT, pydantic-settings; адаптеры к Zitadel Management API v1 и к generic/sarex-backend как провайдеру аутентификации.

Компонент переносит учётные записи из Django-монолита во внешний провайдер идентификации: пользователь, заведённый или изменённый в платформе, автоматически появляется и обновляется в AMS (Access Management Service) вместе с профилем, e-mail, принадлежностью организации и метаданными, на которых затем строится авторизация в доменных сервисах. Работает в двух режимах — постоянный сервис, читающий Kafka-топик `ams-sync` и обрабатывающий события по одному, и консольный режим массовой миграции пользователей и компаний, использовавшийся при первичном переезде на Zitadel.

Технически организация в Zitadel выбирается по конфигурации хоста, импорт идёт через `/management/v1/users/human/_import` для одиночных пользователей и `/admin/v1/import` для батчей, следом устанавливаются метаданные учётной записи. Отсутствующие имя и фамилия подставляются заглушками, то есть компонент рассчитан на импорт неполных легаси-данных. Проверка живости — TCP, HTTP-эндпоинтов сервис не публикует и входящих вызовов от других компонентов не принимает; этим объясняется его отсутствие в графе межсервисных вызовов, выведенном из манифестов.

## attachments

Репозитории: pdm/attachments — REST-сервис хранения и выдачи файловых вложений. Стек: Python, FastAPI, Pydantic, PostgreSQL (psycopg2 + пул соединений, сырой SQL), SQLAlchemy/Alembic для схемы и миграций, S3 через boto3 (presigned URL), OpenTelemetry, JSON-логирование.

Компонент отвечает за универсальные вложения к произвольным сущностям платформы: пользователь прикрепляет файл — фото с объекта, скан, приложение к документу — к записи любого типа, а сервис хранит сам файл в объектном хранилище, а метаданные о нём в реляционной БД. Модель `Attachment` содержит `name`, `company_id` (мультиарендность), `model_name` — имя сущности-владельца, `instance_id`/`instance_uid` — ссылку на конкретный экземпляр, `author_id`, а также имена объектов в S3 для оригинала и превью. Полиморфная привязка «`model_name` + `instance_id`» позволяет использовать один сервис для вложений к замечаниям, документам, задачам и другим объектам, не заводя отдельных таблиц под каждый домен. В жизненном цикле проекта компонент задействован прежде всего на этапах полевой работы и согласований, когда к записи нужно приложить подтверждающие материалы. Выдача файлов идёт по временным ссылкам: клиент скачивает содержимое напрямую из хранилища, минуя сервис.

Реализация следует слоистой структуре в Go-подобной раскладке каталогов: `cmd/app` создаёт приложение, `internal/controller/http/v1` содержит роутер, `internal/service` — прикладную логику, `internal/repository` — доступ к БД, а `internal/usecase/interfaces.py` описывает протоколы `RepositoryInterface` и `S3ClientInterface`, внедряемые через `Depends`. HTTP-контракт включает загрузку файла (`UploadFile` с промежуточной записью во временный файл и выгрузкой в S3), выборку списка с фильтрами, получение одной записи и удаление; ссылки на скачивание формируются функцией `create_presigned_url`. Репозиторий работает не через ORM, а сырыми SQL-запросами psycopg2 с `RealDictCursor` поверх пула соединений — SQLAlchemy-модели нужны лишь как источник метаданных для Alembic. Приложение инструментировано трассировкой OpenTelemetry. Не подтверждён механизм генерации превью: поле `thumbnail_object_name` в модели есть, кода его формирования в репозитории нет.

## auth-flow

Репозитории: platform/auth-flow-frontend — SPA-обработчик OIDC-редиректов (login / callback / logout / error); platform/frontend/core/auth — модуль авторизации микрофронтенд-ядра; infra/zitadel-auth-proxy — Helm-чарт oauth2-proxy; infra/oauth2-facade — сервис-фасад OAuth2 (в репозитории только точка входа и конфиг). Стек: TypeScript, React, Webpack 5, внутренний `sdk-js` и его модуль `zitadel` поверх oidc-client, Zitadel как OIDC-провайдер, Authorization Code flow; в инфраструктуре — oauth2-proxy, Kubernetes/Helm.

Компонент реализует вход пользователя в платформу и поддержание сессии: страницы `/login`, `/logout`, `/auth/callback` и `/auth/error` образуют изолированный маршрут авторизации, через который проходит любой пользователь перед доступом к проектам, документам и моделям. Конфигурация OIDC не зашита в сборку, а читается из localStorage (`AUTHORITY`, `CLIENT_ID`), что позволяет одному бандлу обслуживать разные контуры и разных заказчиков; при отсутствии этих значений приложение падает с явной ошибкой. Запрашиваемые скоупы — `openid profile email offline_access urn:zitadel:iam:user:metadata`, то есть вместе с профилем подтягиваются пользовательские метаданные Zitadel (принадлежность к организации), на которых далее строится авторизация в доменных сервисах. Отдельно проработан сценарий ошибки: параметры разбираются из query и показывается страница с возможностью скопировать диагностический текст. Компонент не хранит бизнес-данных и не участвует в жизненном цикле проекта напрямую — он является входной точкой ко всем остальным приложениям.

Технически это отдельный SPA-микрофронтенд: `App.tsx` маршрутизирует по `window.location.pathname` без react-router, в проде разрешены лишь `/auth/callback` и `/auth/error`, любой другой путь принудительно переписывается в callback через `history.replaceState`. На странице callback вызывается `zitadel.userManager.signinCallback()`, полученный `User` сохраняется утилитой `setTokensInfo`, а токены транслируются в host-приложение через оконные события — это и есть механизм интеграции с оболочкой микрофронтенда; для выхода используется отдельный ключ в storage и идентификатор вкладки. Фоновое обновление токенов сознательно отключено (`automaticSilentRenew: false`). Модуль `platform/frontend/core/auth` — вторая, «ядровая» реализация: класс `Auth` с MobX-состоянием, монтируемый в оболочку. На стороне инфраструктуры доступ к сервисам может дополнительно закрываться oauth2-proxy с прокидыванием access-токена. Серверная часть авторизации подтверждена лишь фрагментарно: `oauth2-facade` содержит только точку входа и конфиг, а выпуск и валидация токенов выполняются во внешнем Zitadel.

## bim

Репозитории: platform/bim-backend-v2 — основной Go-сервис BIM-моделей, элементов, свойств и статусов; aero/bimbackend — предыдущее поколение того же домена на Flask/Celery (сравнения, слияние, архивация, оптимизация мешей); platform/bim-api-metadata-inserter-v4 — batch-джоб загрузки метаданных сконвертированной модели в БД. Стек: Go (go-pg, gorilla/mux, validator, zap, Prometheus), PostgreSQL с шардированием по нескольким инстансам, партиционированием таблиц элементов и материализованными представлениями; Python (Flask, peewee, Celery, PostgreSQL ltree, boto3/S3, JWT).

Компонент — ядро работы с информационными моделями здания: он хранит перечень BIM-моделей проекта, дерево их элементов, свойства элементов и статусную модель, по которой ведётся учёт хода строительства. Ключевые сущности — `bim` (модель, привязанная к проекту, документу и компании, с трансформацией и статусной моделью), `bim_element` (элемент с иерархией и категорией), таблицы свойств (строковых, числовых, логических), история изменений и корпоративный шаблон статусов `company_status_model`. Статусная модель по умолчанию — категория «Строительство» со статусами «Неопределённый», «Не приступали», «В работе», «Готово», «Отклонение», у каждого свой цвет и разрешённые переходы: это напрямую питает раскраску модели во вьюере и отчётность о проценте готовности. Пользователь получает по API дерево элементов, фильтрует их по статусам и свойствам, выгружает свойства в CSV, назначает статусы и настраивает собственные статусные модели на уровне компании. Более раннее поколение дополнительно закрывает сопоставление проектной модели с данными обмеров: задачи сравнения, расчёт отклонений, слияние моделей, откат изменений, архивирование.

Архитектурно bim-backend-v2 построен по слоям cmd → config → controller/http/v1 → usecase → entity: отдельные бинарники HTTP-сервера и миграций, роутеры `bim`, `bim_internal` и `company_status_model`, на каждый эндпоинт свой файл с юнит-тестами и сгенерированными моками. Публичный контур отделён от служебного `bim_internal` (создание модели, синхронизация свойств, выборка элементов по статусу), предназначенного для межсервисных вызовов. Данные распределены по нескольким кластерам Postgres: конфиг задаёт до трёх наборов реквизитов подключения плюс границы диапазонов id, по которым выбирается инстанс; подключение к БД идёт по TLS, есть отдельная схема v3 и интеграция с legacy-контуром Django. Metadata-inserter — не сервис, а джоб: он читает описание входов и параметров из окружения, скачивает из объектного хранилища файлы метаданных и свойств (msgpack + gzip), нормализует типы параметров Revit, создаёт партиции под модель, пакетно вставляет элементы и свойства в транзакции, обновляет агрегаты модели и пересобирает материализованное представление, после чего переводит статус модели из `Pending` в `OK`. Точная граница ответственности между v2 и aero/bimbackend в текущем проде по коду не устанавливается — обе кодовые базы живые.

## ac-bim-converter

Репозитории: algorithms/ifc_converter — Python-ядро конвертации IFC в glTF и извлечения свойств; algorithms/ifc-converter-job — Go-обёртка, запускающая ядро как job; pdm/nwd-converter — Go-воркер RPC поверх RabbitMQ, конвертирующий файлы Autodesk в формат `.s3d`; platform/nwd-gltf-converter — .NET-плагин к Autodesk Navisworks; platform/bim-converter — пустой репозиторий. Стек: Python + ifcopenshell, NumPy; Go (envconfig, validator, resty, zap), RabbitMQ, S3, Docker; C#/.NET с Autodesk.Navisworks.Api и SharpGLTF; целевые форматы — glTF/GLB, `.s3d`, JSON-файлы свойств.

Компонент отвечает за подготовку исходных проектных моделей к просмотру и анализу в платформе: пользователь загружает файл в САПР-формате (IFC, NWD/Navisworks и другие форматы Autodesk), а конвертер превращает его в облегчённое геометрическое представление для веб-вьюера и в машинно-читаемый набор свойств и категорий элементов. Помимо геометрии извлекаются данные экземпляров и категорий, материалы и матрицы размещения, то есть на выходе получается не «картинка», а структурированная модель, пригодная для дерева элементов, фильтров и назначения статусов. Именно эти артефакты далее загружает metadata-inserter в базу BIM, поэтому конвертер является обязательным звеном между загрузкой документа в CDE и появлением работоспособной модели в интерфейсе. В жизненном цикле проекта компонент срабатывает при каждой публикации новой версии модели, а также при повторной обработке уже загруженных файлов.

Реализация распадается на два типа исполнителей. Первый — эфемерный джоб: `ifc-converter-job` получает описания входов, выходов и параметров JSON-структурами в переменных окружения, валидирует их, скачивает исходный IFC из объектного хранилища, запускает встроенный Python-код и выгружает результат обратно; само ядро на Python собирает glTF вручную — формирует JSON-структуру сцены, пишет бинарные буферы, принимает геометрию из итератора ifcopenshell, сохраняет свойства в JSON и упаковывает результат в zip. Второй тип — постоянный воркер: `nwd-converter` поднимает RPC поверх RabbitMQ (консьюмеры `input` и `cancel`), принимает сообщение с bucket/key входа и выхода, параметрами Navisworks, метаданными (компания, документ, комплект) и идентификаторами задачи оркестрации, скачивает файл, вызывает консольный конвертер через `os/exec` с разбором кодов ошибок, выгружает `.s3d` и возвращает статус со временем выполнения. `nwd-gltf-converter` — плагин, устанавливаемый в каталог Plugins Autodesk Navisworks Manage; в репозитории лежат преимущественно скомпилированные сборки, исходных файлов поиск не находит. Репозиторий `platform/bim-converter` пуст, поэтому будущая консолидированная реализация неизвестна.

## cde

Репозитории: pdm/cde-api — основной Go-сервис среды общих данных (документы, версии, комплекты, права, штампы, подписи, публичные ссылки); platform/cde-orchestration-demo — оркестратор процессов CDE на Camunda 8/Zeebe с набором воркеров; generic/cde-v2-write-service — пустой репозиторий. Стек: Go (go-pg, Fiber, zeebe-client, OpenTelemetry), PostgreSQL, S3/MinIO, Apache Kafka (transactional outbox + outbox-relay), Valkey/Redis для кеша прав, RabbitMQ в оркестраторе, Camunda 8 и BPMN, AsyncAPI для контрактов событий, Helm/Kubernetes.

Компонент реализует среду общих данных (Common Data Environment) — центральное хранилище проектной документации с версионированием, правами доступа и регламентом согласования. Модель данных, восстановленная по миграциям, включает проект, «диск» (пространство компании), документ с типами, версиями и связями, комплект (bundle) с атрибутами, датами и признаками маркировки, файл-источник, постраничное представление, состояние многочастной загрузки, права, workflow, штамп со схемой позиционирования, QR-метку, электронную подпись, публичную ссылку с автоудалением, события разметки и changelog. Это покрывает полный документооборот стройки: загрузку чертежей и разделов, сборку комплектов, простановку штампов «В производство работ», QR-кодов и ЭЦП, выдачу публичных ссылок подрядчикам, фиксацию замечаний и истории изменений. Отдельно решается задача вывода из эксплуатации legacy-сервисов: мутирующие запросы `documentation-api` и `documentation-api-v2` проксируются в cde-api, чтобы бизнес-логика и публикация событий выполнялись в одном месте.

cde-api построен на чистой архитектуре с явным разделением слоёв: бизнес-логика в сущностях, usecase управляет транзакциями через Unit of Work, write-репозитории работают в рамках одной транзакции, read-репозитории держат отдельный пул и допускают параллельные выборки; эндпоинты сегментированы по потребителям — `app` (фронтенд), `internal` (межсервисные), `external` (внешние интеграции) и `public` (без авторизации). Событийная интеграция реализована строго по паттерну transactional outbox: сервис не содержит Kafka-продюсера, а пишет строку в таблицу `outbox` в той же транзакции, что и бизнес-запись; воркер relay собирает конверт «metadata + payload» с идентификатором, типом, временем и трассировкой события и публикует по одному топику на тип (`documents.document.created.v1`, `documents.bundle.uploaded.v1` и др.), проставляя заголовок арендатора; гарантии — at-least-once с идемпотентностью потребителя, контракты обязательны к описанию в AsyncAPI. В состав входят также бинарники миграций и файлового стрима и собственный пакет клиента Zeebe с воркерами на типы BPMN service task, пробросом трассировки из переменных процесса и продлением аренды задачи. Оркестратор — исполнительная часть процессов: отдельные воркеры копирования, создания версий, разметки, подписи, разбиения PDF и обновления комплектов плюс HTTP-сервер и адаптеры к pdm, bim, flows и system-log.

## checklists

Репозитории: proc/checklists-backend — HTTP-сервис чек-листов и результатов их заполнения. Отдельный фронтенд-репозиторий не найден. Стек: Python, FastAPI, Pydantic v2, Piccolo ORM + Piccolo Admin (русская локаль), PostgreSQL (JSONB), OpenTelemetry, JWT-аутентификация собственным middleware.

Компонент реализует функцию типовых чек-листов (шаблонов проверок) и фиксации результатов их прохождения. Администратор создаёт чек-лист, состоящий из упорядоченных шагов, каждый из которых содержит элементы ввода. Элементы ввода типизированы ограничениями — строковые и выбор из вариантов с привязкой цвета к варианту, что позволяет строить цветовую индикацию результата. Исполнитель на объекте заполняет чек-лист, и создаётся результат, привязанный к произвольной сущности платформы через пару `entity_type` / `entity_id` — то есть чек-лист может навешиваться на любой объект: замечание, работу, актив, согласование. Все сущности мультиарендные: фильтрация и проверки прав идут по `company_id`. Результаты поддерживают блокировку — фиксацию после согласования; блокировку инициирует не пользователь, а смежный сервис.

Архитектура слоистая: контроллеры HTTP (публичный `/api/v1` и служебный `/internal/api/v1`) → сервисный слой → модели Piccolo. Публичные роутеры — `/checklists` и `/results` с пагинацией limit/offset, сортировкой и фильтрами. Внутренний API содержит только `/results`, включая массовую операцию блокировки, которую вызывает сервис согласований flows (`PATCH /internal/v1/results/lock`). Аутентификация — middleware, декодирующий JWT и наполняющий контекст пользователя, откуда берутся `company_id` и автор записи. Конкурентный доступ решён через `SELECT ... FOR UPDATE` на уровне Piccolo. Данные хранятся в PostgreSQL, миграции ведутся с июня 2025 по март 2026, поля включают JSONB — снимок структуры шагов и элементов ввода в результате, что фиксирует состав проверки на момент её прохождения. Поверх БД поднята админка Piccolo Admin для ручного управления. Внешних брокеров, S3 или gRPC в коде не обнаружено.

## comparisons

Репозитории: pdm/comparisons-backend — исходный Go-сервис сравнений; pdm/comparisons-api-v2 — переписанная на Fiber версия с чистой архитектурой; platform/comparisons-frontend — микрофронтенд UI сравнений; platform/bim-2-bim-comparisons-frontend — фактически пуст. Стек: Go (go-pg, Fiber, validator), PostgreSQL; TypeScript, React, MobX, Material-UI, Webpack Module Federation, внутренние `sdk-js` и `ui-kit`, локализация en / zh-CN; Docker-образы задач в реестре контейнеров.

Компонент отвечает за сравнение проектных данных между собой и выявление изменений и отклонений. Поддерживаются несколько типов сравнений, видимых и в коде, и в иконках интерфейса: `c2c` (облако точек к облаку), `c2s` (облако к модели/поверхности), `abap`, `pdf2pdf` (сравнение PDF-чертежей), `deviation` (отклонения) и `bim2bim` в версии v2. Пользователь выбирает диск и документы-источники, задаёт параметры и допуск (tolerance), запускает сравнение и затем видит список сравнений со статусом выполняющегося процесса. Результат раскладывается на элементы и изменения, которые можно фильтровать по набору полей и редактировать — то есть инженер верифицирует найденные расхождения, а не просто получает отчёт. Сравнения удаляются мягко, что подтверждается отдельной миграцией. Сценарий применяется при контроле соответствия построенного проекту и при отслеживании изменений между версиями документации.

Бэкенд v1 — Go-сервис с бинарниками API и миграций, таблицами `comparisons`, `elements`, `changes`, `deviation_element`. Каждый тип сравнения оформлен как отдельный пакет с единым набором шагов: проверка прав → создание документа → создание модели → создание workflow, то есть тяжёлые вычисления делегируются внешнему оркестратору, а результат возвращается через эндпоинт `webhook`. Интеграции реализованы клиентами к сервису документации (включая имя бакета), к сервису workflow (запуск и статус по типам сравнения) и к рабочим пространствам. Версия v2 построена на Fiber со слоями контроллеры → usecases → services → репозитории, с JWT-middleware; её ключевое отличие — пакет, который прямо в коде собирает DAG задач (slug, docker-образ, входы, требования к ресурсам, связи `needs`), например импорт в bim-api с последующей сборкой облака. Фронтенд — модуль микрофронтенда с MVVM на MobX: слой репозиториев (типы, диски, документы, сравнения, workflow), слой view-model и usecase удаления; хосты бэкендов резолвятся через общий SDK, интеграция с общей панелью документов платформы выполнена переиспользуемым компонентом. Какая из версий бэкенда сейчас в проде, по коду не определяется.

## contracts

Репозитории: platform/contracts — бэкенд договоров; platform/contracts-frontend — интерфейс договоров. Стек: Go, Fiber v3, pgx/v5 + pgxpool, squirrel, ULID, SQL-миграции, PostgreSQL (управляемый, с TLS), Helm + GitLab CI на стенды stage/preprod/prod; TypeScript, React, MobX, Feature-Sliced Design с контролем границ слоёв через eslint, внутренний `sdk-js`.

Компонент ведёт реестр договоров (контрактов) компании и связанных с ними подрядчиков. Договор описывается номером, подрядчиком, датой начала и крайним сроком, стоимостью и текстовым описанием и может быть привязан к ресурсу платформы — объекту или проекту. Это даёт коммерческий контур поверх производственных данных: подрядчик, срок и стоимость становятся атрибутами, к которым можно привязывать факт выполнения работ; на договор, в частности, ссылается предписание. На фронтенде пользователь работает со списком договоров, выбирает подрядчиков и компанию, причём текущая компания хранится в localStorage и отслеживается отдельным хуком, что типично для мультикомпанийной платформы. Компонент относительно молодой: одна первичная миграция и API версии `v0`.

Бэкенд реализован по чистой архитектуре: бинарники HTTP-сервера и CLI → приложение → контроллер `v0` с маршрутами создания, списка, получения по id, обновления и удаления → сервис → usecase → репозиторий PostgreSQL. Идентификатор договора — ULID, хранится строкой. Схема: таблица `contracts` с номером, `tenant_id`, `resource_id` (UUID), подрядчиком в JSONB, датами, стоимостью `DECIMAL(19,4)`, описанием и таймстампами, индексы по арендатору, ресурсу и номеру, триггер обновления `updated_at`, мягкое удаление. Мультиарендность реализована через `tenant_id` и middleware проверки принадлежности пользователя компании поверх JWT. Запросы частично константный SQL, частично конструктор squirrel для фильтров. Деплой — Helm-чарт в неймспейсы по стендам, ingress-префикс `/contracts/api/` на соответствующих доменах API. Фронтенд построен по FSD с жёстким контролем границ слоёв; в слое `entities` — договоры, подрядчики и компании, каждая со связкой store + repository + adapter, причём тип DTO в адаптерах компаний и подрядчиков указывает, что часть справочных данных берётся из Django-монолита, а не из Go-сервиса договоров.

## control-interface

Репозитории: platform/srx-admin. Прямого репозитория с именем `control-interface` в инстансе нет; соответствие установлено по коду: srx-admin деплоится в неймспейсы `control-interface-stage / -preprod / -prod`, а его модули публикуются по путям `modules.<домен>/control-interface/modules/admin/remoteEntry.js` и `.../modules/assets/remoteEntry.js`, которые зарегистрированы в шелле generic/sarex-frontend как модули `administration` и `assets`. Стек: TypeScript, React, MobX, Material-UI и собственный `ui-kit`, Webpack 5 Module Federation, монорепозиторий npm-workspaces (`services/*` + `packages/app-kit`), FSD-слои, внутренний `sdk-js`, Helm + GitLab CI.

Функционально это административный контур платформы — интерфейс управления. Модуль `admin` даёт разделы «Пользователи», «Атрибуты», «Роли», «Места работы», «Проекты» и «Функциональные группы»; каждый раздел доступен по отдельному признаку прав, и пользователь при входе перенаправляется на первый доступный ему раздел. Модуль `assets` управляет реестром активов компании: деревом активов, правами доступа к ресурсам и массовыми действиями над выбранными активами. Отдельный крупный сценарий — пакетный импорт активов из XLSX: пользователь выбирает проект и файл (до 400 МБ, только `.xlsx`), система создаёт задание импорта и показывает таблицу заданий со статусами, счётчиками ошибок и предупреждений и ссылками на файлы с их расшифровкой. Таким образом компонент — точка входа администратора компании в справочники, оргструктуру, права и наполнение реестра активов.

Технически это микрофронтенд-монорепозиторий: два независимо собираемых и публикуемых remote-модуля и общая библиотека `app-kit` с переиспользуемыми сущностями, фичами динамических селектов по атрибутам, отделам, группам и правам и общими типами. Модули подключаются в шелл по URL `remoteEntry.js`, при этом конфиг эндпоинтов содержит варианты для stage, preprod, prod и закрытого контура с относительными путями. Состояние — MobX-сторы уровня фичи и виджета с пагинацией limit/offset и фильтрами по статусу и проекту. Работа с API идёт через слой `shared/api` поверх общего `httpService`; импорт актива отправляется как `multipart/form-data` с полями файла, организации, автора и ресурса, а скачивание шаблона XLSX разбирает заголовок `Content-Disposition`. Контекст текущей компании и пользователя приходит из шелла, права — из контекста администрирования. Собственного хранилища у компонента нет: это презентационный слой над бэкендами платформы. Не установлено, входят ли в тот же ArchiMate-компонент другие приложения, деплоящиеся в неймспейсы `control-interface-*`.

## cross-section

Репозитории: aero/cross-section — фронтенд-модуль построения сечений в 3D-вьюере (деплоится как статика); aero/cross-secttions-to-dwg-job — Go-джоб экспорта сечения в DWG. API сечений обслуживает aero/drawings-api. Стек: TypeScript, React, MobX, Material-UI, внутренние `pixi-viewer` и `sdk-js`, Storybook, Helm; Go (go-pg, gotools, SDK вложений), PostgreSQL с TLS, объектное хранилище, Python-код генерации DWG внутри базового образа.

Компонент даёт инженеру инструмент построения поперечных сечений по облакам точек и BIM-документам прямо во вьюере платформы, а затем выгрузки полученного сечения в DWG для работы в CAD. Сценарий в интерфейсе выражен явным конечным автоматом: пользователь выбирает ось сечения (X/Y/Z), указывает центр сечения кликом по облаку точек, корректирует и перемещает секущий бокс, дожидается обработки изображения сечения и вводит имя, после чего сечение сохраняется. Сохранённые сечения показываются списком с датой создания, легендой документов и цветовой раскраской — каждому документу-источнику присваивается свой цвет; их можно показывать и скрывать, зумить, удалять и экспортировать. Вкладка экспортов показывает созданные выгрузки со статусом и кнопкой скачивания. Компонент применяется на этапе контроля и обмера построенного: сечение по лазерному сканированию сопоставляется с проектной геометрией и уходит в CAD.

Фронтенд — микрофронтенд с ленивой загрузкой, встраиваемый в общий вьюер: он получает от хоста экземпляр вьюера, карту документов и идентификатор компании. Доменное состояние — MobX-классы: хранилище сечений, само сечение с документами, цветами, экспортами и признаком видимости, сценарий с описанным автоматом и расчётом размеров бокса, а также слой обработки с генерацией цветов и разрешением идентификаторов документов. Отрисовка идёт через собственные PIXI-компоненты с чанковой загрузкой геометрии сечения. Обращения к бэкенду инкапсулированы в слое эндпоинтов поверх общего `httpService` с выбором хоста по окружению сборки. Джоб экспорта — отдельный контейнер, запускаемый как задача workflow: он создаёт временный каталог, читает сечение из PostgreSQL, выгружает точки в файл, создаёт целевой DWG, вызывает Python-код конвертации с параметром толщины линии, затем загружает результат как вложение через SDK и проставляет идентификатор вложения в запись экспорта. Подключение к БД — управляемый PostgreSQL с TLS.

## django

Репозитории: generic/sarex-backend — легаси-монолит платформы на Django/DRF, ядро доменной модели и API; generic/sarex-frontend — основной SPA-хост, в который встраиваются модули микрофронтендов. Стек: Python, Django (миграции от 2.2 до 4.2), DRF, PostgreSQL, ClickHouse, MongoDB, Celery + Redis, Kafka, S3, django-guardian, django-channels, SimpleJWT + JWKS, Zitadel (OIDC), Prometheus, Sentry, OpenTelemetry, Helm; фронтенд — TypeScript, React, MobX, Material-UI, Webpack 5 с Module Federation, PWA.

Компонент реализует ядро продукта: компании и пользователи с ролями, должностями, подразделениями и подрядчиками, объекты строительства, миссии аэрофотосъёмки и их импорт, ортофотопланы, облака точек, поверхности и меши. Отдельный слой закрывает фотограмметрию и измерения: измерения, вложения, сравнение объёмов и поверхностей, экспорт облаков точек и ортомозаик, PDF-подложки, интеграция с Metashape. Аналитический блок даёт дашборды, виджеты, метрики с атрибутами и значениями, вычисляемые метрики, фильтры, группировки и импорт значений из XLSX — инструмент отслеживания прогресса работ и КПЭ проекта. Приложение карты отвечает за кадастровые данные и заметки на ортофотоплане, отдельный модуль — за ТОиР. Сквозные механизмы — уведомления, согласования, замечания, рабочие процессы и журнал действий — покрывают весь жизненный цикл: от съёмки и загрузки данных до контроля качества и приёмки. Фронтенд собирает всё это в единое рабочее место с 2D/3D-вьюером и разделами рабочих пространств, документации, договоров, трансмитталов, RFI, замечаний, инспекций, предписаний, аналитики, помещений, активов и администрирования.

Технически бэкенд — классический слоёный Django-монолит с приложениями базовой модели, ядра, аналитики, карты, ТОиР, фотограмметрии, активностей, ресурсов и аутентификации, с DRF-роутерами и вьюсетами под `/api/`, админкой, метриками и swagger в отладочном режиме. Асинхронная обработка вынесена в Celery (импорт миссий, активности, уведомления), состояние — в PostgreSQL, аналитические выборки дополнительно идут в ClickHouse, файлы — в S3 с чанковой загрузкой и проверкой хешей. Интеграция с остальной платформой идёт через Kafka-продюсер, HTTP-шлюз к внутренним сервисам (в частности к system-log) и внутренние эндпоинты, включая интроспекцию пользователей, выдачу публичного ключа и сервисных токенов. Аутентификация двухрежимная: собственные JWT с ротацией и JWKS-эндпоинтом и Zitadel как внешний OIDC-провайдер; права — через django-guardian и модели прав на уровне объектов. Фронтенд построен как host-приложение с ленивыми маршрутами и fallback на ошибку загрузки модуля; Module Federation настроен на общие зависимости, внешние модули подключаются как отдельные бандлы.

## documentations

Репозитории: pdm/documentation-api — основной Go-сервис документации (документы, диски, версии, права, обработка файлов); pdm/documentation-api-v2 — переписанная версия домена с проксированием в cde-api; pdm/documentation-frontend — микрофронтенд раздела «Документация». Стек: Go (go-pg, minio-go S3, Valkey/Redis, RabbitMQ, Mailgun/SMTP, OpenTelemetry, Sentry, JWT), в v2 — Fiber, swaggo, отдельные бинарники API, файлового стрима и миграций; PostgreSQL с TLS; фронтенд — TypeScript, React, MobX, Material-UI, axios с ретраями.

Компонент — рабочая среда данных проекта: пользователь работает с «дисками» компании, деревом папок и документами, у каждого документа есть версии-комплекты и физические файлы, страницы с превью, атрибуты, права доступа и связи с другими документами. Через него проходит весь документооборот проекта: загрузка и версионирование проектной документации, штампы и QR-маркировка, электронная подпись, согласования, трансмитталы, подписки на обновление и удаление, корзина и восстановление, changelog версий, избранное и шаблоны наименования файлов. Сервис также отвечает за преобразование инженерных форматов: загруженные IFC, NWC/NWD, RFT, DWG, DXF, PDF, DOCX, облака точек и ортофото ставятся в очередь на обработку и превращаются в просматриваемые в платформе модели и растры. Отдельная функция — публичные ссылки на документы и папки, позволяющие передать файл внешнему участнику без учётной записи. Фронтенд-модуль встраивается в основной SPA и даёт полноценный файловый менеджер с деревом дисков, таблицей документов, контекстным меню, диалогами загрузки и скачивания, правами, поиском и фильтрами.

Технически documentation-api — Go-сервис поверх PostgreSQL с миграциями в коде; модель данных включает документ, диск, комплект, файл-источник и его страницы, состояние многочастной загрузки, права, workflow, проект, штамп, QR, ЭЦП, публичную ссылку, связанные документы, избранное, changelog, шаблон наименования, хеш файла и сессии загрузки. Файлы лежат в S3 с потоковой многочастной загрузкой, горячие данные кэшируются в Valkey. Обработка файлов вынесена в контейнерные джобы: отдельный пакет клиентов workflow формирует и запускает задание для каждого формата с образом из реестра контейнеров и общей версией образов, поддерживается рестарт. Сервис интегрирован с Django-монолитом (компании, пользователи, сервисные аккаунты, настройки), с bim-api, cde-api, workspaces, flows, автоматизацией, system-log, трансмитталами и разметкой через RabbitMQ; авторизация — Zitadel плюс подпись в URL для публичных ссылок и файлового стрима. documentation-api-v2 повторяет тот же домен в чистой архитектуре с публичным и внутренним контурами и отдельным файловым сервером, при этом мутирующие вызовы проксируются в cde-api, а оставшиеся легаси-вызовы помечаются специальным логгером — то есть домен находится в процессе миграции.

## document-link

Репозитории: pdm/document-link-frontend — публичное веб-приложение страницы «ссылка на документ». Отдельного бэкенда нет: серверная часть реализована в pdm/documentation-api (таблица `document_public_link`, настройки секрета и срока жизни JWT публичной ссылки). Стек: TypeScript, Next.js (app router), React, SWR, dayjs, PostCSS/Tailwind.

Компонент решает задачу передачи документа наружу контура платформы: сотрудник проекта создаёт публичную ссылку на документ или папку, а получатель — подрядчик, заказчик, проверяющий — открывает её в браузере без учётной записи. Страница показывает карточку документа: имя, тип с иконкой формата, размер, даты, служебные атрибуты — и даёт скачать файл. Это типовой сценарий выдачи рабочей документации и актов внешним участникам стройки, когда полноценный доступ к среде общих данных не нужен и не разрешён. Приложение публичное, поэтому вынесено в отдельный деплой, а не в основной SPA. Срок жизни ссылки ограничивается на стороне documentation-api через JWT с настраиваемым временем экспирации.

Технически это тонкий Next.js-фронтенд: маршрут `/[uuid]` принимает идентификатор публичной ссылки, компонент модального окна через SWR запрашивает публичный эндпоинт `documentations/api/v1/public/documents/public_link/{uuid}`, а вспомогательный компонент рендерит поля карточки. Собственного хранилища и серверной логики в репозитории нет — вся выдача метаданных и подписанных ссылок на файл делается публичным эндпоинтом documentation-api, который валидирует JWT публичной ссылки. Форматирование размера и дат выполняется на клиенте, иконки типов документов подбираются по расширению. Базовый URL API берётся из окружения сборки, что позволяет разворачивать одну сборку на всех стендах. Аутентификация пользователя отсутствует по определению — контроль доступа полностью сводится к валидности и сроку действия ссылки.

## drawings

Репозитории: aero/drawings-api — Go-сервис поперечных сечений и их экспорта; является серверной частью компонента cross-section. Стек: Go, gorilla/mux, go-pg + миграции, envconfig, zap, Prometheus, внутренние библиотеки gotools и sdk-go (пакет workflows); PostgreSQL (управляемый, с TLS); Docker + Helm.

Компонент отвечает за построение чертёжных данных по результатам аэросъёмки и лазерного сканирования: пользователь задаёт поперечные сечения (профили) по поверхности или облаку точек объекта и получает геометрию сечения для анализа и выпуска чертежей. Это типовая задача земляных работ и линейных объектов — контроль профиля насыпи, выемки, дороги, откоса — когда нужно сопоставить фактическую поверхность с проектной по заданной линии. Сервис хранит сами сечения и отдельно задания на их экспорт, что позволяет выгружать результаты в файлы для передачи в CAD. Он работает в связке с фотограмметрическим контуром платформы, получая исходные поверхности и вложения по внутренним URL. В жизненном цикле проекта компонент применяется на этапе исполнительной съёмки и контроля выполненных объёмов.

Технически это компактный Go-сервис с плоской структурой: бинарник с маршрутизатором, health-проверкой и метриками Prometheus, домен сечений с моделями, интерфейсом хранилища, реализацией на PostgreSQL и репозиторием workflow. HTTP-слой содержит операции создания, получения, получения данных и удаления сечений, а также создания, получения и удаления экспорта и приёма webhook — то есть экспорт выполняется асинхронно во внешнем workflow, который по завершении вызывает webhook сервиса. Схема БД ведётся собственными миграциями, включая мягкое удаление сечений. Конфигурация — через переменные окружения, включая сертификат для TLS-подключения к БД; логирование — zap с прокидыванием request-id. Запуск заданий опирается на общий SDK работы с workflow, что связывает сервис с движком фоновой обработки платформы; из значений Helm видны внутренний адрес сервиса для других компонентов и адрес сервиса вложений. Точный формат экспортируемых файлов по прочитанным фрагментам не восстановлен.

## eav

Репозитории: platform/eav_python — работающий сервис EAV (атрибуты, схемы атрибутов, значения) и справочника активов; platform/eav — репозиторий с gRPC-контрактом EAV, без серверной реализации. Стек: Python, Django + DRF, django-filter, Celery, PostgreSQL (в том числе сырой SQL для пересчёта иерархии), pandas + openpyxl, jsonschema; в platform/eav — protobuf 3 и сгенерированный Go-код.

Компонент даёт платформе универсальную модель «сущность — атрибут — значение»: любые доменные объекты (документы, активы, элементы модели, метрики, замечания, инспекции) можно расширять произвольными пользовательскими атрибутами без изменения схемы БД. Администратор описывает атрибуты и их типы (целое, дробное, дата, дата-время, логическое, справочные Choice и MultiChoice со списками значений), группирует их в схемы и привязывает схемы к типам объектов. Второй крупный блок — активы: иерархический классификатор объекта строительства (структура проекта, секция, этаж, помещение) с внешними идентификаторами, родительскими связями и правами доступа, фактически играющий роль WBS/дерева объекта. Массовое наполнение справочников выполняется импортом Excel-файла с листами «Справочники» и «Аттрибуты» по шаблону, который сервис же и выдаёт; предусмотрен обратный экспорт. Именно через этот компонент атрибутивная информация попадает в документацию, аналитику, замечания и BIM-разделы платформы.

Технически eav_python — Django-сервис с приложениями атрибутов (атрибут, группа, схема, связь схемы и атрибута, варианты значений, перечисление типов), активов (актив, права, процессы импорта и экспорта) и общего ядра; URL смонтированы как несколько версий API для атрибутов и схем и две версии для активов, есть админка. Импорт реализован как Celery-задача с мягким и жёстким таймаутом, лимитами на размер файла и число активов, статусами от `pending` до `committed` и раздельными файлами исходника, ошибок и предупреждений; пайплайн разложен на модули разбора колонок, нормализации, валидации, сборки атрибутов и сохранения с типизированными кодами ошибок (циклическая иерархия, дубль внешнего идентификатора, отсутствующий атрибут) и последующим пересчётом иерархии сырым SQL. Мультиарендность обеспечивается фильтрацией по организации и правами на основе токена, метаданные валидируются jsonschema. Репозиторий platform/eav содержит только proto-файл и сгенерированный Go-код сервиса EAV с методами CRUD и фильтрации, причём целевой Go-пакет указывает на bim-backend-v2 — это незавершённая попытка вынести контракт EAV в gRPC, а не самостоятельный сервис. Потребители держат локальные копии атрибутов и синхронизируют их отдельными командами (`sync_eav` в issues и inspections).

## faas

Репозитории: не найдены. Поиск по проектам GitLab по запросам «faas», «openfaas», «nuclio», «knative», «lambda», «serverless» результатов не даёт; по «function» найден единственный PoC-обработчик событий S3 в облачных функциях. Поиск по коду в ключевых сервисах даёт совпадения только внутри вендоренных библиотек OpenTelemetry (семантические соглашения `faas.name`, `faas.trigger`), то есть к коду платформы отношения не имеет. В issues и merge request'ах упоминаний тоже нет.

Прямых доказательств существования компонента с таким именем нет — ни репозитория, ни группы, ни упоминаний в коде и тикетах. По косвенным признакам функцию «функции как сервис» в платформе выполняет связка движка workflow и множества одноразовых job-контейнеров: есть семейство workflows-api / workflows-engine / workflows-backend / workflows-frontend, инфраструктурный argo-workflows, шаблоны и инструменты workflow, а также группы job-репозиториев в aero/jobs, pdm/jobs, generic/processing и algorithms — от разрезания и склейки PDF и генерации документов из шаблона до конвертации DXF в поверхность и расчёта объёмов.

Ровно эта модель видна в коде потребителей: documentation-api для каждого формата собирает имя контейнерного образа из реестра и версии образов и запускает задачу через адрес движка, а результат принимает по webhook; тот же приём используют drawings-api, comparisons и issues (генерация предписаний). Таким образом, faas в архитектуре — с высокой вероятностью логическое имя для слоя эфемерных вычислительных функций-джобов, запускаемых движком workflow поверх Kubernetes, а не отдельная кодовая база. Это интерпретация по косвенным признакам, а не подтверждённый факт: перед фиксацией в модели значение компонента стоит уточнить у команды платформы.

## flows

Репозитории: proc/flows-backend — сервис маршрутов согласования документации; proc/flows-frontend — микрофронтенд конструктора маршрутов. Стек: Python, FastAPI, SQLAlchemy + Alembic, PostgreSQL (JSONB, массивы), sqladmin, Celery, FastStream + Kafka (SASL/SCRAM), httpx, pandas (расчёт рабочих дней), JWT-middleware, OpenTelemetry; фронтенд — TypeScript, React, MobX, Material-UI, rsbuild + Module Federation.

Компонент реализует согласование и выпуск проектной документации: пользователь настраивает маршрут (`Flow`) из последовательных шагов (`Step`) с назначенными согласующими, а каждый документ проходит по маршруту в виде ревью (`Review`) с фиксацией решений участников и статусов. Основные сущности — маршрут, шаг, ревью, документ, статус, действие пользователя и очередь задач согласующего с приоритетами, длительностями и сроками, пересчитываемыми по рабочим дням. Поддерживаются типы маршрутов и шагов, минимальное число согласующих на шаге, массовые операции над списками маршрутов и согласующих, режимы уведомлений о завершении. Отдельный блок — трансмитталы: у маршрута есть флаг автоматической передачи после согласования, шаблоны передачи и фильтры по статусам и типам документов, а созданные передачи привязываются к ревью с записью в историю действий. Применяется на стадии выпуска и приёмки рабочей документации, где нужны формализованные круги согласования и подтверждённая передача комплектов.

Технически это монолитный FastAPI-сервис со слоями роутеры → CRUD-менеджеры (маршрут, ревью, шаг, статус, документ, действие пользователя, очередь задач) → модели SQLAlchemy. Роутеры смонтированы под внешним путём `/flows/api/v1`, отдельно вынесен внутренний роутер; авторизация — middleware разбора JWT и декларативная таблица правил вида `base.can_view_review` с точечными правилами для отдельных URL. Исходящие события публикуются в Kafka через FastStream: смена статуса документа, создание и завершение ревью, изменение состава согласующих. Интеграции по HTTP: Django-монолит (пользователи, токены, предки документов), сервис ресурсов, чек-листы (в том числе блокировка результатов через внутренний эндпоинт) и EAV с кешированием типов атрибутов. Есть админка на sqladmin с собственной аутентификацией, фоновый пересчёт кеша нагрузки согласующих в отдельном потоке и тяжёлые агрегирующие SQL-запросы для счётчиков. Важно не путать с платформенным семейством `workflows`: flows — доменный сервис согласования документов со своей моделью и БД, тогда как workflows-engine — универсальный исполнитель фоновых задач; историческое имя внутренней секции настроек в flows-backend (`settings.workflows`) и создаёт путаницу.

## iam

Репозитории: platform/iams-v2 — сервис управления пользователями, ресурсами и правами; platform/srx-rebac — репозиторий пуст. Стек: Go (гексагональная архитектура), PostgreSQL, SpiceDB (ReBAC) по gRPC, Zitadel Management API v2, Kafka (SCRAM), S3, Helm/Kubernetes с настройками Istio, k6 для нагрузочных тестов.

Компонент — платформенный IAM: он владеет иерархией ресурсов, компаниями и организациями, пользователями, сервисными аккаунтами и разрешениями, которые все остальные модули используют как единый источник прав на объект строительства или проект. Из архитектурных решений видно разделение: `Resource` — мета-модель иерархии, `Project` — её реализация; права описаны в модели ReBAC схемой SpiceDB. Сервис отвечает на прикладные вопросы «какие права у пользователя на ресурс», «какие ресурсы доступны пользователю», «какие сервисные аккаунты действуют на ресурсе», а также отдаёт списки пользователей с фильтрами по ресурсу и разрешению — именно на эти ответы опираются flows, issues и inspections при фильтрации данных. Пользователи заводятся во внешнем провайдере идентификации: адаптер создаёт, обновляет и ищет пользователей в Zitadel и пишет им метаданные, которые затем приходят в другие сервисы заголовком `identity`. Организация в Zitadel выбирается правилами по домену email или логина, то есть поддерживается мультиарендность заказчиков.

Архитектурно это гексагональный Go-сервис с тремя бинарниками — сервер, CLI и наполнение данными — и адаптерами SpiceDB, Zitadel, Kafka и S3. SpiceDB подключается gRPC-клиентом и используется для чтения и записи отношений и авторизации ресурсов с ретраями; у SpiceDB собственный Postgres-datastore, отдельный от базы приложения, а миграция схемы и запись `.zed`-схемы вынесены в pre/post-хуки Helm. HTTP API включает выборку пользователей, проверку разрешений, поиск ресурсов и сервисных аккаунтов, CRUD ресурсов и виджетов, массовое обновление прав и отдельный внешний административный контур, который монтируется только при включённой аутентификации и принимает legacy-токены для обратной совместимости. Kafka используется для публикации доменных событий об изменении ресурсов и состояния пользователей, а бэкфиллы в закрытых контурах гоняются как Kubernetes Job из чарта; потребители этих топиков видны, в частности, в inspections-backend. Есть подробный контур нагрузочных тестов на k6 с порогами по времени ответа. Провайдер идентификации в коде — Zitadel; Keycloak в этой части не используется (он встречается только как auth-сервер Camunda в оркестраторе CDE).

## inspections

Репозитории: proc/inspections-backend — бэкенд модуля «События / Проверки»; proc/inspections-frontend — микрофронтенд с календарём событий и бронированием слотов. Стек: Python 3.12, FastAPI, Piccolo ORM + Piccolo Admin, PostgreSQL (JSONB, массивы, интервалы, триггеры, advisory-локи), FastStream + Kafka, httpx, OpenTelemetry, XLSX-экспорт, отдельные образы API и Kafka-приложения; фронтенд — TypeScript, React, MobX, Material-UI, DevExpress Scheduler, rsbuild + Module Federation.

Компонент ведёт события и проверки на объекте в продукте строительного контроля: инспекция — это запланированный осмотр с типом, датой и временем, ответственными, локацией (в том числе идентификатором помещения), набором настраиваемых атрибутов, статусом и историей изменений с парами «было — стало». Сервис даёт CRUD событий и их типов с конфигурируемыми атрибутами и связью с типами замечаний из issues, проверяет занятость ответственных (пересечение по времени, запрет текущего дня — настройки уровня компании), рассылает уведомления и выгружает реестр событий в XLSX. Отдельная подсистема — бронирование слотов: правила доступности для связки «проект + тип события» бывают цикличными по дням недели или разовыми по датам, интервал ограничен рабочим днём кратно тридцати минутам, задаются целевые сервисные аккаунты и лимит участников, а само бронирование идемпотентно по внешнему идентификатору. Практически это планирование выездов инспекторов и приёмок с контролем ёмкости; отдельной сущности «рабочий календарь специалиста» в платформе нет — доступность исполнителя определяется его событиями.

Реализация — два приложения из одной кодовой базы: HTTP API со слоями контроллер → сервис → БД/клиенты, синглтонами в состоянии приложения и контекстом на запрос, и отдельный Kafka-консьюмер на FastStream. Роутеры — события и бронирование слотов; права двухуровневые: глобальные из токена либо права сервисных аккаунтов на конкретные типы событий, проверка вынесена в зависимость. JWT не проверяется по подписи (доверие шлюзу), поддерживаются два формата — обычный payload и base64-метаданные Zitadel в заголовке `identity`. Исходящие события версионируются в имени топика (`inspections.inspection.created.v1`, статусы, типы); входящие — события активов EAV для обновления локальной копии таблицы атрибутов и топики IAM для клона пользователей, подразделений, должностей и сервисных аккаунтов. По HTTP сервис ходит в Django-монолит за пользователями, в EAV за атрибутами и в движок workflow за отправкой писем; есть массовые скрипты синхронизации, админка Piccolo, мягкое удаление, создание правила бронирования по умолчанию через триггер PostgreSQL и защита конкурентных изменений через advisory-локи и оптимистичную блокировку по `updated_at`.

## issues

Репозитории: proc/issues-backend — сервис замечаний и предписаний; proc/issues-frontend — микрофронтенд реестра замечаний. Сюда же переехала логика архивных remarks-*. Стек: Python, Django 4.2 + DRF, drf-spectacular, PostgreSQL (в том числе полнотекстовый поиск), Celery + Redis, Kafka, S3 (boto3), pandas + Pillow (XLSX), ReportLab (PDF), SimpleJWT с несколькими бэкендами включая Zitadel, внутренняя библиотека `sarex_cli` для фильтров EAV, OpenTelemetry.

Компонент закрывает работу с замечаниями строительного контроля: замечание с типом, статусами и настраиваемыми статусными моделями, ответственными, комментариями, вложениями-фотографиями, историей изменений и атрибутами из EAV. Пользователь ставит «пин» на странице документа, в ячейке XLSX или на задаче календарно-сетевого графика и заводит замечание с описанием, сроком устранения, ответственными и графическими пометками поверх чертежа. Замечание связывается с контекстом платформы: помещением, ресурсом или проектом, ревью из flows, событием из inspections и рабочим пространством. Отдельное приложение реализует предписания — документы, формируемые по набору замечаний, со своими статусами. Продуктовый сценарий — фиксация дефекта на объекте с фото, назначение ответственного и срока, движение по статусной модели с проверкой прав на переход, выпуск предписания и выгрузка реестра в Excel и PDF для заказчика или подрядчика. Есть также реестр шифров и ежемесячные счётчики для нумерации.

Технически это классический Django-проект с разделением на API (вьюсеты, сериализаторы, фильтры, сервисы), доменные модели, предписания и общее ядро с аутентификацией, правами и миксинами. Экспорт вынесен в отдельный пакет: сборщик данных с пулом потоков, экспортёр Excel на pandas и экспортёр PDF на ReportLab с русскими шрифтами; при большом числе замечаний экспорт уходит в Celery, результат складывается с ограниченным сроком жизни, и пользователь получает уведомление. Celery на Redis обслуживает уведомления (создание, изменение, назначение ответственного, массовые рассылки), публикацию событий в Kafka с трассировкой и синхронизацию с OLAP-сервисом. Права строятся на токене компании и уточняются правилами на уровне типа замечания и допустимости перехода статуса, в том числе через кеш. Атрибуты EAV держатся локальной копией: миграция первичного импорта и management-команда синхронизации тянут активы пачками под сервисным токеном, а фильтрация по атрибутам строится маппером из общей библиотеки. Вложения хранятся в S3; фронтенд организован по слоям API → репозитории → сторы → view-model → представления и подключает диалог создания документа из модуля документации.

## mapper

Репозитории: platform/mapper — агрегирующий сервис (BFF) поверх нескольких API. Стек: Python, FastAPI, httpx (async с ретраями), Redis/RedisJSON (опционально отключается), PyJWT, Helm/Kubernetes.

Компонент решает узкую продуктовую задачу — склеивать данные из разных сервисов в один ответ для интерфейса, чтобы фронтенд не делал N запросов и не соединял сущности на клиенте. Реализованы два сценария. Первый — реестр документов на диске: документы из сервиса документации объединяются с данными о согласовании из flows по ключу документа, так что в списке сразу видно состояние маршрута согласования. Второй — заметки: записи сервиса notes объединяются со связями по идентификатору для произвольной пары «сервис / сущность / экземпляр». Компонент оперирует чужими сущностями (документ, ревью и шаг согласования, заметка, связь), собственной доменной модели и базы данных не имеет. Применяется в интерфейсах работы с проектной документацией и с комментариями к объектам платформы.

Технически это два GET-эндпоинта — по документам диска и по заметкам — обслуживаемых менеджером сервисов: обёрткой над httpx-сессией с прокидыванием пользовательского токена и кешированием ответа в Redis через RedisJSON по ключу «пользователь + URL» с TTL из конфигурации. Слияние данных выполняют чистые функции, индексирующие ответы по идентификаторам. Внешние адреса заданы переменными окружения: сервис документации, flows, notes и Django-монолит — это прямое подтверждение зависимости компонента от flows и documentations. Аутентификация — зависимость, которая понимает два варианта: Zitadel (заголовок авторизации плюс base64-метаданные в `identity`) и legacy-JWT платформы, разбираемый без проверки подписи. Таймаут запросов вынесен в конфигурацию, сервис деплоится одним Deployment без БД и брокеров. Не установлено, какие именно фронтенд-модули сегодня используют эти эндпоинты.

## measurements

Репозитории: aero/measurements — сервис геопространственных измерений по растрам аэрофотосъёмки. Стек: Python, FastAPI, GDAL/osgeo (чтение GeoTIFF, в том числе напрямую из S3), boto3, pyproj, NumPy, OpenCV, SciPy, Pillow, Sentry, OpenTelemetry.

Компонент даёт инструменты измерений по материалам аэрофотосъёмки и лазерного сканирования: по ортофотопланам, цифровым моделям местности и рельефа и тепловизионным растрам он считает величины, нужные при контроле земляных работ и мониторинге стройплощадки. Поддерживаются точечные запросы (высота или температура в точке и в наборе точек), построение профиля вдоль ломаной с достройкой промежуточных точек, расчёт объёма по замкнутому контуру в нескольких режимах, включая объём относительно цифровой модели, и расчёт разности объёмов между двумя съёмками — то есть выполненного за период объёма работ. Дополнительно отдаётся служебная информация по растру: метаданные, статистика по каналам и границы покрытия по тайловым зумам, а также пересчёт координат между системами. Типичное применение — обмер отвалов и котлованов, контроль объёмов вывоза и завоза грунта, тепловые обследования кровель и фасадов.

Реализация — stateless-сервис на FastAPI без собственной БД: роутеры под общим префиксом (точка, набор точек, профиль, объём, разность объёмов, преобразование координат, информация о GeoTIFF), pydantic-модели запросов и вычислительный слой с открытием датасета и чтением блоков, преобразованием «пиксель ↔ координата» и трансформациями систем координат с кешированием, расчётом высот, температур, масок и объёмов. Растры читаются напрямую из объектного хранилища: конфигурация хранит несколько учётных записей S3 и настраивает GDAL под них, открытые датасеты кешируются. Маски полигонов строятся через OpenCV и Pillow, аппроксимация для температурных расчётов — методом наименьших квадратов из SciPy. Аутентификация — собственное middleware, понимающее и JWT из заголовка, и base64-метаданные, с обращением во внешний сервис; наблюдаемость — Sentry и трассировка OpenTelemetry. Тесты покрывают модели и точечные роутеры с моками GDAL-зависимостей. Не установлено, какие клиенты вызывают сервис и как именно исходные растры попадают в хранилище.

## message-hub

Репозитории: planning/message-hub — центральный событийный хаб домена планирования; pdm/dps_message_hub — узкий консьюмер событий по активам для домена PDM. Стек: Python 3.12, FastStream, Kafka через aiokafka (SASL + SSL), Redis (кеш и менеджер сокетов), python-socketio, SQLAlchemy Core с сырыми SQL-запросами к PostgreSQL, boto3/S3, httpx, Jinja2; в dps_message_hub — FastStream + async psycopg с пулом.

Компонент отвечает за асинхронную интеграцию сервисов платформы: он принимает события из Kafka и превращает их в побочные действия, которые не должны блокировать пользовательские API. Для пользователя это выражается в том, что после изменения задач календарно-сетевого плана автоматически пересчитывается аналитика, обновляются атрибуты объектов, отправляются письма, формируются экспортные файлы (в том числе HTML → PDF), пишется системный журнал действий и выполняется автопланирование. Отдельная ветка обработки — синхронизация проектных сущностей и ресурсов: создание, обновление или удаление проекта при изменении ресурса. Хаб также транслирует изменения в браузер по WebSocket, обеспечивая живое обновление доски проекта у нескольких пользователей одновременно. Второй репозиторий решает более узкую задачу: слушает broadcast-топик активов и переносит обновления атрибутов и события разметки в базу документации домена PDM.

Технически planning/message-hub — не HTTP-сервис, а ASGI-приложение FastStream с четырьмя Kafka-роутерами (активы, планирование, проектные сущности, ресурсы), общим обработчиком повторов и политикой подтверждения, плюс health-эндпоинты, проверяющие брокер и Redis. Сервисный слой обращается к смежным сервисам по HTTP (BI, EAV, issues, PDF, PM, projects), кэширует пользователей и токены в Redis, пишет в PostgreSQL напрямую SQL-запросами (системный лог, сводные поля, разделы активов, проектные сущности), складывает экспорт в S3 и рендерит письма Jinja-шаблонами. dps_message_hub построен строго по чистой архитектуре с разделением на домен, приложение, инфраструктуру и интерфейс, использует внедрение зависимостей FastStream, транзакции через отдельный компонент, middleware повторов и одну consumer-группу с чтением с начала топика. Ключевое отличие: planning/message-hub — «толстый» хаб с десятком бизнес-обработчиков, WebSocket и множеством интеграций, dps_message_hub — тонкий однотопиковый сервис свежей архитектуры только для атрибутов активов.

## notes

Репозитории: aero/notes-backend — REST API заметок, документов, ссылок и вложений; aero/notes-frontend — фронтенд-модуль заметок, встраиваемый в 2D/3D-просмотрщик. Стек: Python, FastAPI, SQLAlchemy + Alembic, PostgreSQL с полнотекстовым поиском (TSVECTOR), httpx, PyJWT, профилирование SQL; фронтенд — React + TypeScript, MobX, Material-UI, react-hook-form, react-dropzone, снятие скриншота вида, собственный переводчик.

Компонент реализует пользовательские заметки и примечания на объектах проекта: пользователь может создать заметку на 2D-чертеже или в 3D-модели, задать срок, цвет, приложить фото и файлы, связать её с документом и другими проектными сущностями. Заметка оперирует сущностями «заметка», «связь», «документ» и «вложение» и привязывается к внешним сущностям через перечисления сервиса и типа сущности, то есть служит универсальным механизмом комментирования объектов разных сервисов платформы. Отдельный сценарий — формирование документа по заметке: во фронтенде есть форма создания документа с типом, атрибутами и вложенными табличными полями, а в бэкенде — запуск задачи генерации документа. Есть фильтрация по датам и статусам, поиск, режимы отображения подсказок и видимости заметок, отправка скриншота вида вместе с заметкой. Применяется на этапах авторского надзора и строительного контроля, когда замечание нужно зафиксировать прямо на модели или чертеже.

Технически бэкенд построен по схеме роутеры → обобщённый CRUD → модели SQLAlchemy; роутеры — заметки, связи, документы и вложения с общим префиксом из настроек. Полнотекстовый поиск реализован кастомным типом TSVECTOR и соответствующими миграциями. Доступ проверяется декларативной таблицей прав и middleware интеграции с legacy-аутентификацией, сессия БД живёт в отдельном middleware с ContextVar. Вложения не хранятся в самой БД: файлы отправляются во внешний файловый сервис по httpx. Есть опциональный подмодуль интеграции со сторонней системой со своей моделью-прокси, JWT-авторизацией и отдельным роутером, включаемый флагом конфигурации. Генерация документов инициируется через шаблон задачи и клиент создания документа. Фронтенд организован как встраиваемый модуль со стором MobX, собственным контекстом и режимами работы в 2D и 3D; интерфейс разбит на список с фильтром, создание заметки, создание документа и общие компоненты — зона перетаскивания файлов, слайдер изображений, действия над заметкой и отправка вида.

## pm

Репозитории: planning/pm-backend — ядро календарно-сетевого планирования; planning/pm-frontend — интерфейс диаграммы Ганта и управления задачами. Стек: Python, Django 5 + DRF, PostgreSQL с SQL-триггерами и функциями, Celery + Redis, Kafka, ClickHouse, S3, Zitadel-аутентификация плюс собственный JWT-бэкенд, OpenTelemetry и Sentry, pandas/NumPy, Jinja2 (HTML-шаблон Ганта для PDF), парсеры XML и XER; рядом с Django смонтировано FastAPI-приложение, документация описывает новый слоёный стиль на FastAPI + async SQLAlchemy. Фронтенд — React + TypeScript, MobX, Material-UI, Webpack 5, Storybook.

Компонент закрывает управление проектом во времени: иерархия задач, длительности, связи предшествования, календари (включая производственные с масками рабочих дней и праздниками), базовые планы, фактические значения и проценты выполнения, ресурсы и их назначения на задачи и элементы модели. Пользователь может импортировать существующий график из MS Project (XML), Primavera (XER), корпоративного шаблона XLSX и отраслевых форматов, работать с ним на диаграмме Ганта и выгружать обратно в PDF с настраиваемой детализацией, условным форматированием и составом колонок. Поддерживаются детализированные задачи и срезы значений для учёта выполнения, визуальные профили оформления, комментарии к задачам, связи задач с внешними сущностями и связи между проектами. Автопланирование и пересчёт запускаются асинхронно, что позволяет работать с крупными графиками без блокировки интерфейса.

Технически бэкенд — DRF-приложение с набором вьюсетов: проекты, задачи, детализированные задачи, значения, состояния проекта, ресурсы и их назначения, связи задач, атрибуты проекта, настройки, визуальные профили, связи проектов, календари, комментарии, связи сущностей и описания; отдельно вынесен внешний API с урезанным набором для интеграций. Импорт реализован иерархией парсеров с типизированными ошибками разбора файла, календаря, иерархии, связей и базовых планов и запускается Celery-задачами. Экспорт в PDF собирается провайдерами на pandas с обогащением атрибутами, базовыми планами, связями и пользователями, рендерится Jinja-шаблоном и отдаётся внешнему PDF-сервису. Модель данных включает проект, задачу с локальным индексом, путём, прогрессом и распределением, связи задач, значения атрибутов (в том числе привязку к активам), календари, базовые планы, срезы значений, системный лог и собственную модель прав по типу модели, экземпляру и действию. Взаимодействие с остальной платформой идёт через Kafka (события подхватывает message-hub) и ClickHouse для аналитики. Не установлено, какая часть API уже переехала на встроенное FastAPI-приложение.

## prescriptions

Репозитории: proc/prescriptions-frontend — микрофронтенд предписаний; бэкенд — приложение `prescriptions` внутри proc/issues-backend, публикуемое по пути `/issues/api/prescriptions`. Отдельного репозитория бэкенда не существует. Стек: фронтенд — React + TypeScript, rsbuild + Module Federation, MobX, Material-UI, react-hook-form + zod, внутренний `sdk-js` с провайдером Zitadel; бэкенд — Python, Django + DRF, django-filter, PostgreSQL; генерация документов делегируется движку workflow.

Компонент реализует выдачу предписаний подрядчику по результатам строительного контроля. Предписание собирается из зафиксированных замечаний, привязывается к договору и подрядчику (наименование, ИНН, идентификаторы), к объекту или ресурсу и компании, получает уникальный в рамках компании номер и проходит согласование по статусам «Черновик → На согласовании → Согласовано / Не согласовано → Передано / Не передано». По выбранному шаблону формируется официальный документ (docx, затем pdf) с реквизитами сторон: застройщик, подрядчик, субподрядчик, лица строительного контроля, номера приказов, адрес и наименование объекта. Пользователь редактирует состав замечаний, генерирует документ, экспортирует его и удаляет версии; все действия фиксируются в истории предписания. Компонент используется на этапе строительно-монтажных работ как формализованный выход процесса инспекций и замечаний.

Технически бэкенд — Django-приложение внутри issues-backend: модель предписания с автором, компанией, ресурсом, подрядчиком, договором, идентификатором шаблона-комплекта, номером с уникальным ограничением в пределах компании, статусом генерации и мягким удалением; настраиваемые по компаниям статусные модели с цветами и журнал истории с типами событий (создано, изменено, смена статуса, старт/финиш/ошибка генерации, добавление и удаление замечаний). Связь с замечаниями — «многие ко многим» по их публичным идентификаторам, фильтрация выполняется кастомными фильтрами, поддерживающими и GET со списком через запятую, и POST со списком значений. Генерация формирует тело задания для движка workflow — имя, список задач со slug, docker-образом, лимитом повторов и входными данными — и складывает результат по заданному пути, то есть предписание напрямую зависит от компонента фоновой обработки. Фронтенд собран rsbuild с Module Federation, авторизуется через Zitadel, ходит в хосты issues, documentations, checklists, файлового сервиса, EAV, шлюза и оркестратора, подтягивает удалённый компонент диалога создания документа из модуля документации и содержит фичи редактирования состава замечаний, генерации, экспорта и удаления документа.

## processing

Под этим именем сходятся две связанные, но разные сущности — платформенный движок процессов и инфраструктура фоновых джобов; ниже описаны обе.

Репозитории: platform/workflows-engine — исполнитель воркфлоу; platform/workflows-api — HTTP API воркфлоу, задач и запусков; platform/workflows-backend — предшествующая монолитная реализация; platform/workflows-frontend — микрофронтенд мониторинга; generic/processing/job_template и generic/processing/remove-object-from-s3 — шаблон и типовой пример контейнерного задания. Отдельно: platform/srx-processing — несмотря на имя, это ETL-скрипт наполнения отраслевых справочников, к движку процессов отношения не имеющий. Стек: Go (pgx в движке, go-pg в API), PostgreSQL, RabbitMQ/AMQP, Kubernetes client-go, zap, mock-тесты; фронтенд — React + TypeScript, MobX, Material-UI, виртуализация списков, внутренний `sdk-js`; джобы — Python, boto3, pydantic, внутренняя библиотека `workflows-tools`, Docker.

Компонент — внутренняя «фабрика» тяжёлых вычислений платформы: любая длительная операция (конвертация модели, генерация документа, обработка облака точек, экспорт, обслуживание файлов) оформляется как workflow — направленный граф задач, каждая из которых выполняется в отдельном контейнере. Продуктовые сервисы не выполняют такую работу сами, а публикуют задание и отслеживают его статус; результат складывается в хранилище и возвращается пользователю как готовый файл или обновлённые данные. Ровно через этот механизм работают documentations (конвертация форматов), comparisons (сравнения), drawings и cross-section (экспорт в DWG), prescriptions (генерация документа). Для инженера поддержки есть отдельный интерфейс: список воркфлоу с фильтром по компаниям, конвейер задач по слоям с индикаторами состояния, просмотр логов запуска, отмена выполняющегося запуска и перезапуск задачи с ручной правкой параметров, входных объектов и требований к ресурсам — это делает компонент точкой наблюдаемости и ручного вмешательства в фоновую обработку.

Движок построен по чистой архитектуре: сущности воркфлоу, задачи, запуска и описания job, слои сценариев, оркестратор принятия решений о запуске, контроллер периодического опроса состояний и исполнители двух типов — Kubernetes Job и отправка сообщения в очередь RabbitMQ стороннему воркеру (именно так работает, например, nwd-converter). API — отдельный HTTP-сервер с контроллерами v1 и авторизационным middleware; наблюдаемые эндпоинты: список и карточка воркфлоу с фильтрами и пагинацией, перезапуск задачи, чтение логов запуска. Схема БД общая с прежней реализацией и включает блокировки воркфлоу, логи и прогресс запусков, требования к сервисам, параметры и зависимости по умолчанию и конфигурацию исполнения. Внешне сервис публикуется под хостом `orchestrator` (`/orchestrator/api`), логи запусков смотрятся в SigNoz. Вторая часть компонента — сами задания: каждая фоновая операция упакована в собственный Docker-образ по единому шаблону, в который ставится общая библиотека `workflows-tools` и копируется точка входа. Параметры передаются не аргументами, а JSON-структурами в переменных окружения, валидируются pydantic-моделями, доступ к хранилищу инкапсулирован в отдельном модуле, реквизиты S3-аккаунта также приходят из окружения — это соответствует контракту движка, где в описании задачи указываются образ, slug, лимит повторов и входы. Формально не установлено, какой из репозиториев (workflows-backend или workflows-engine) работает в проде; вывод о замещении сделан по датам миграций и структуре кода.

## projects

Репозитории: planning/projects-backend — API карточки и витрины проектов; planning/projects-frontend — интерфейс страницы проекта и витрины. Стек: Python, FastAPI, async SQLAlchemy 2.0, Alembic (собственная схема БД), PostgreSQL с JSONB, массивами и UUID, boto3 (S3 для фотографий), PyJWT, httpx, настройки для Superset; фронтенд — React + TypeScript, MobX + TanStack React Query, Material-UI, Webpack 5, leaflet (карта), виртуализация списков.

Компонент отвечает за витрину проектов и карточку конкретного проекта — верхнеуровневый вход пользователя в платформу. Здесь проект описывается атрибутами и местоположением, снабжается фотографиями, группируется по настраиваемым признакам компании и отображается карточками в общем списке. Внутри проекта пользователь работает с настраиваемыми вкладками и разделами: каждый раздел — это виджет с показателями, который администратор может добавить, отредактировать, переупорядочить или удалить прямо в интерфейсе, переключив режим администрирования в шапке проекта. Поддерживаются разные типы разделов, включая встраивание внешней аналитики через iframe (в конфигурации присутствует Superset) и выбор объектов из дерева активов. Таким образом компонент выступает «обложкой» проекта, агрегирующей данные остальных модулей на всём жизненном цикле.

Технически бэкенд следует слоёной архитектуре: роутеры API v1 (проект, вкладка, раздел, фотография, витрина) → сценарии → репозитории → модели, зависимости собираются в отдельном модуле, проверки доступа вынесены в слой безопасности поверх разбора JWT. Помимо публичного API есть служебный контур `/internal` (создание и обновление проекта, массовое обновление разделов), используемый другими сервисами платформы, и служебный роутер health-проверок. Собственные таблицы живут в отдельной схеме БД — комментарий в коде прямо указывает, что имена в `public` уже заняты, а таблица проектов заменяет прежний синк из legacy-контура. Модели: проект с JSONB-атрибутами, координатами и UUID, вкладка, раздел с JSONB-конфигурацией и порядком, фотография с порядком и привязкой к проекту, настройки компании с группировками. Файлы фотографий кладутся в S3, справочные данные берутся из сервиса ресурсов. Фронтенд использует MobX-сторы в связке с React Query, страницу проекта с шапкой, карточкой описания и показателями, модальные окна управления разделами и виртуализированное дерево объектов для выбора активов. Миграции датированы июлем 2026 года и содержат ссылки на этапность и legacy-синк — компонент, вероятно, находится в стадии замещения прежнего решения.

## remarks

Репозитории: proc/remarks-frontend — активный микрофронтенд работы с замечаниями; proc/remarks-api, proc/remarks-cli, proc/export-remarks — архивные (`_archived_`) бэкенд, CLI и экспорт; proc/issues-backend — действующий бэкенд, куда переехала вся логика. Стек: фронтенд — TypeScript, React, MobX, Material-UI, TanStack Table + TanStack Virtual, внутренний `sdk-js`, внутренний пакет переводов; бэкенд — см. компонент issues (Django/DRF, PostgreSQL, Celery + Redis, Kafka, S3, экспорт в XLSX и PDF).

С точки зрения архитектуры это пользовательский модуль замечаний, сохранивший историческое имя: собственный `remarks-api` архивирован, и модуль работает поверх сервиса issues. Пользователь ставит «пин» на странице документа, ячейке XLSX или задаче календарно-сетевого графика и заводит замечание с описанием, сроком устранения, ответственными (сотрудники, подразделения, должности), вложениями, графическими и текстовыми пометками поверх чертежа, комментариями и произвольными атрибутами. Замечания типизированы и имеют настраиваемые статусные модели с правами на переходы, что позволяет вести цикл «выдано → в работе → устранено → проверено» под регламент конкретного заказчика. Замечание привязано к документу и его версии, к рабочему пространству и к ресурсу или проекту, а также может быть связано с процедурой согласования и с предписаниями. Доступны табличное и списочное представления, фильтры с сохранением, настройка видимых колонок, история изменений и массовое редактирование; результат выгружается в XLSX и PDF-отчёты, в том числе с изображениями вложений.

Технически это микрофронтенд-модуль, экспортируемый в host-приложение со своим провайдером и MobX-стором и порталами для встраивания панелей, общающийся по HTTP через общий `httpService` с сервисом issues. На стороне бэкенда работают модели замечания, его изменений, типа, статусов и их связей, прав на переход и на тип, вложений, комментариев и записей атрибутов. Права строятся на JWT и наборе разрешений просмотра, редактирования, администрирования и надзора, дополнительно уточняемых на уровне типа замечания и сервисных аккаунтов. Атрибуты вынесены в собственную EAV-модель, синхронизируемую с внешним сервисом EAV миграцией первичного импорта и management-командой. Асинхронная часть — Celery-задачи уведомлений, синхронизации с OLAP-сервисом, публикации событий в Kafka и фоновой генерации больших экспортов с сохранением файлов в S3. При переносе компонента в модель ArchiMate стоит явно зафиксировать, что «remarks» и «issues» — это один бэкенд и два имени, иначе связи между элементами получатся дублирующими.

## resources

Репозитории: platform/sarex-resources — бэкенд реестра ресурсов; planning/resources-frontend — интерфейс. Стек: Python, Django 4.1–5.1 + DRF, django-filter, model_utils, PostgreSQL с расширением ltree и PostGIS, requests + pydantic для HTTP-клиента к сервису пользователей, админка Django.

Компонент ведёт единый реестр ресурсов платформы — иерархию объектов строительства (проект, объект, участок и далее вниз по дереву) с типами, географическим положением, кодами и правами доступа. Идентификатор ресурса (`resource_id`, `public_id`) служит сквозным ключом проекта во всех остальных сервисах, а сам реестр — общей точкой проверки прав: к нему привязываются права пользователей и сервисных аккаунтов, права на уровне компании, фотографии, состав проектной команды, график работ по проекту и идентификаторы виджетов планирования. По графу вызовов контура к нему обращаются documentations, flows, issues, pm, processing, rfi и transmittal; по коду компонентных репозиториев — также inspections, contracts, prescriptions и projects.

Технически дерево хранится в PostgreSQL с расширением ltree: в проекте есть собственное приложение `apps.ltree` с полем `LTreeField` и lookup'ами для запросов по поддереву, а координаты объекта ведутся через `django.contrib.gis` поверх PostGIS. Мультиарендность обеспечивается hash-индексами по `tenant_id` и сервисному аккаунту, у моделей — мягкое удаление и таймстампы через миксины. API опубликован в двух версиях (`urls.py` и `urls_v2.py` с расширенным `ResourceExpandedViewSet`). Брокеров сообщений в коде нет: интеграция со смежными сервисами только синхронная, по HTTP.

## reviews

Репозитории: proc/reviews-frontend — микрофронтенд рабочего места согласующего; proc/flows-backend — бэкенд маршрутов согласования; proc/flows-frontend — UI конструктора маршрутов; proc/export-reviews — сервис экспорта отчётов по согласованиям. Отдельного репозитория `reviews-backend` не существует. Стек: фронтенд — TypeScript, React, MobX, rsbuild + Module Federation, внутренний `sdk-js`, Helm; бэкенд — см. компонент flows (FastAPI, SQLAlchemy, PostgreSQL, Kafka через FastStream, Celery, sqladmin).

Компонент отвечает за согласование (рецензирование) проектной документации: документ или комплект запускается по маршруту, состоящему из шагов с назначенными согласующими, сроками и минимальным числом согласований. Согласующий получает задачу в очередь с приоритетом и длительностью, просматривает документ, ставит пометки и замечания, заполняет чек-листы и выносит решение — согласовано, с замечаниями или отклонено, после чего документ переходит на следующий шаг либо маршрут завершается. Компонент оперирует сущностями «согласование», «маршрут», «шаг», «статус», «документ», «действие пользователя», «задача в очереди» и состоянием документа на шаге. Это ключевой этап жизненного цикла проектной документации между выпуском версии и её выдачей «в производство работ»: именно результат согласования определяет статус документа и появление штампа и QR на печатной версии. Поддерживаются массовые операции, копирование маршрутов, пересчёт сроков по рабочим дням и уведомления согласующих и администраторов, в том числе о пустых шагах.

Технически reviews-frontend — remote-модуль Module Federation со своим маршрутизатором и корневым стором, обращающийся к нескольким хостам, объявленным декларативно: flows (`/flows/api/v1`), documentations, лямбды, шлюз и Django-монолит. Основные вызовы: фильтрация и получение согласований, выборка документов по идентификаторам и статусу согласования, список задач с изменением приоритета и длительности, обновление результатов чек-листа, привязка маршрута к документам, а также API отметок и агентов с длительным таймаутом прогона. Серверная часть построена по слоям роутеры → зависимости → CRUD-менеджеры → модели, с отдельными менеджерами на каждую сущность, миксинами проверки маршрута и действий пользователя, публичным и внутренним роутерами и декларативной моделью прав. Интеграции: публикация в Kafka событий смены статуса документа и завершения согласования, кеширование типов атрибутов EAV, исходящие HTTP-вызовы к смежным сервисам, кеш количества задач пользователя в памяти с фоновым обновлением. Экспорт отчётов вынесен в отдельный сервис. Как и в паре remarks/issues, здесь один бэкенд обслуживает два фронтенд-компонента: flows-frontend — конструктор маршрутов, reviews-frontend — рабочее место согласующего.

## rfi

Репозитории: proc/rfi-backend — сервис запросов информации; proc/rfi-frontend — микрофронтенд RFI. Стек: Python, Django 5.1 + DRF, PostgreSQL, django-filter, drf-spectacular, SimpleJWT с интеграцией Zitadel, Celery + kombu, pydantic (DTO), httpx, django-colorfield, локализация; фронтенд — TypeScript, React, MobX, rsbuild + Module Federation, внутренний `sdk-js`; CI/CD — GitLab CI + Helm.

Компонент реализует процесс RFI (Request for Information) — формальные запросы информации и разъяснений между участниками проекта: подрядчик или строительный контроль задаёт вопрос проектировщику или заказчику, получает ответ и фиксирует его как официальное решение. Основная сущность — запрос с приоритетом, статусом, автором, ответственными и привязкой к ресурсу или проекту; переписка ведётся сообщениями, одно из которых может быть помечено как решение. Приоритеты и статусы не захардкожены, а конфигурируются на уровне компании и ресурса через модели наборов приоритетов и статусов со своим цветом, что позволяет каждой организации настроить собственный регламент обработки запросов. Ведётся полный журнал изменений полей запроса с человекочитаемым рендерингом «было → стало», включая изменения атрибутов. Запросы поддерживают копирование, вложения и фильтрацию, а участники получают уведомления по мере движения запроса.

Технически бэкенд разложен на Django-приложения запросов, сообщений, приоритетов, статусов, истории изменений, уведомлений и общего ядра; версионированный API собирается из отдельных роутеров каждого приложения и публикуется под `/api/v1/`. Ключевые эндпоинты: фильтрация запросов, CRUD запроса, копирование, создание и получение сообщений с фильтром по запросу, пометка сообщения решением. Все модели наследуют базовую модель с мягким удалением и таймстампами; изоляция арендаторов обеспечивается фильтром по компании и правами на уровне объектов, а аутентификация — stateless-JWT с тремя вариантами разбора токена, включая Zitadel с упакованными в base64 клеймами. Атрибуты запросов подтягиваются из внешнего сервиса EAV, оттуда же берутся имена ресурсов и пользователей — все вызовы по httpx с обработкой ошибок внешнего API. Уведомления и рассылка писем вынесены в Celery. Фронтенд — remote-модуль Module Federation с корневым стором и маршрутизатором, работающий через общий `httpService` с сервисом rfi и отдельным списком хостов других микрофронтендов; вложения адресуются через имя модели в сервисе вложений. Не подтверждено, публикует ли сервис события в Kafka.

## stamp-verification

Репозитории: pdm/stamp-verification-frontend — публичная статическая страница проверки штампа по QR-коду; бэкенд отдельного репозитория не имеет — обслуживается публичным эндпоинтом pdm/documentation-api, данные QR-меток ведутся в pdm/documentation-api-v2. Стек: фронтенд — статический сайт без сборщика и фреймворка (HTML, vanilla JS с `fetch`, moment.js, CSS), счётчик веб-аналитики; бэкенд — Go (gorilla/mux, обработчик публичной информации о документе, клиент к flows, go-pg и миграции по PostgreSQL).

Компонент решает задачу подтверждения подлинности бумажной или PDF-копии проектного документа: на выпущенный документ наносится QR-код (штамп), и любой человек — прораб на площадке, инспектор, представитель заказчика — сканирует его телефоном и попадает на публичную страницу проверки, где видит, какому документу и какой его странице соответствует код и в каком состоянии этот документ находится в системе. Это закрывает типичную проблему стройки — работу по устаревшей или неутверждённой версии чертежа. Проверка не требует авторизации в платформе, поэтому доступна и внешним подрядчикам. Метка привязана к конкретному документу, комплекту, странице и позиции на листе, что позволяет отличать оригинальный штамп от произвольно скопированного. У документа в модели данных предусмотрены признаки наличия QR, штампа, электронной подписи и публичной ссылки — то есть QR-штамп встроен в общий механизм маркировки и публикации документов.

Технически фронтенд — один HTML-файл с inline-логикой: скрипт извлекает идентификатор метки и номер страницы из URL, выбирает базовый хост в зависимости от контура и делает запрос на публичный эндпоинт `documentations/api/v1/public/qr/{public_uuid}/document_info`, после чего отрисовывает карточку документа и раскрывающийся блок истории изменений; даты форматируются moment.js с локалями. Серверная часть находится в documentation-api: маршрут зарегистрирован в публичном контуре и обслуживается отдельным пакетом разметки, который читает документ из своего хранилища и дополнительно запрашивает состояние согласования через клиент к flows — то есть статус согласования на странице проверки берётся из компонента reviews. Сами метки хранятся в таблице `document_qr`: публичный идентификатор, ссылки на документ и комплект, автор, отметка времени, признак обработки, координаты, тип позиционирования и список страниц. Рядом с этим маршрутом в коде есть пометка о постепенном проксировании части эндпоинтов в cde-api под флагом конфигурации. Генерация и нанесение QR на PDF в изученном коде не найдены — соответствующие сервисные пакеты в v2 пусты, эта часть, вероятно, выполняется отдельным заданием обработки.

## subscriptions

Репозитории: pdm/sarex-subscriptions — Django-сервис подписок и рассылки уведомлений (приложения подписок, уведомлений и получателей). Стек: Python, Django 4.1 + DRF, django-filter, Jinja2, PostgreSQL + PostGIS с TimescaleDB (гипертаблицы), python-telegram-bot, SMTP и Mailgun HTTP API, requests с ретраями, OpenTelemetry.

Компонент отвечает за то, чтобы пользователи получали уведомления о значимых изменениях в проектных данных без ручного отслеживания. Пользователь или администратор компании оформляет подписку на объект определённого типа — модель подписки хранит имя модели (например, документ), имя сервиса, компанию и расписание доставки. Поддерживаются периодичности «дважды в день» (по умолчанию 9:00 и 17:00), «ежедневно», «раз в неделю» с выбором дня и «немедленно», то есть подписчик может получать либо мгновенные оповещения, либо дайджест за период. Получатели описаны отдельной сущностью с именем, e-mail, телефоном, идентификатором чата Telegram и ссылкой на пользователя, что позволяет доставлять одно и то же событие в разные каналы. Тексты писем задаются шаблонами уведомлений, привязанными к модели, типу события (создание, редактирование, удаление, копирование, чтение) и статусу события; шаблон может быть общим для всех компаний или привязанным к арендатору. Применяется на всём жизненном цикле проекта — подписка на документ, комплект или объект и получение уведомлений о его правках и передачах.

Технически сервис не слушает брокер, а периодически опрашивает журнал системных событий: сервисный слой ходит по HTTP в компонент system-log и забирает события по фильтру, затем доразрешает пользователей и документы для подстановки в шаблон. Логика вынесена в management-команды периодических и мгновенных уведомлений, которые запускают соответствующие сценарии; в репозитории сосуществуют две версии пайплайна. Модель хранения: событие уведомления с временем регистрации как Timescale-полем, ключом маршрутизации и JSON-атрибутами; транзакция уведомления со статусами «новая / в обработке / успешно / ошибка», временем начала и завершения и текстом ошибки; сообщение с типом канала, темой, текстом и связью с получателями; отправленное уведомление с уникальным ограничением по подписке и началу окна — защита от повторной отправки одного окна. Отправка реализована взаимозаменяемыми сервисами через общий протокол: SMTP, Mailgun и Telegram. Наружу выставлен REST-API на DRF по подпискам с фильтрами по компании и сервису, получателям и уведомлениям, плюс стандартная админка Django. Конфигурация планировщика, запускающего команды, в репозитории не найдена — вероятно, это CronJob уровня кластера.

## system-log

Репозитории: platform/system-log — HTTP-API приёма и выборки событий аудита; platform/system-log-worker — фоновый обогатитель записей журнала. Стек: Go, Fiber, pgx/pgxpool + Squirrel, PostgreSQL, SQL-миграции с применением на старте, собственный пакет Kafka-коннектора на sarama с TLS и SASL/SCRAM, OpenTelemetry, OpenAPI-схема; в воркере — resty и cron.

Компонент — централизованный журнал системных событий (аудит) всей платформы: любой сервис отправляет сюда факт «кто, что и над чем сделал». Запись описывается полями актора, имени модели (документ, инспекция, задача проекта), идентификатора объекта в его домене (числового, UUID или пути), имени события (создание, редактирование, удаление, копирование, передача), подстатуса события (например, для редактирования — добавление комплекта, передача документа, переименование), произвольных метаданных в JSON и свободного текстового сообщения. Дополнительно хранятся идентификаторы цели, ресурса и компании, что позволяет строить ленты активности в разрезе компании и конкретного объекта. Журнал используется не только для прослеживаемости: компонент subscriptions вычитывает из него события, чтобы рассылать уведомления подписчикам, то есть system-log выступает источником изменений для механизма оповещений. На уровне жизненного цикла проекта это сквозной слой прослеживаемости изменений документации и задач.

Архитектура — классическая слоистая: бинарник HTTP-сервера → приложение с запуском сервера и миграций → контроллер v0 с роутером, DTO и валидацией → сценарии → сервисы → репозиторий. API версии v0: POST принимает пакет записей и пишет его в PostgreSQL батчем, валидация требует ровно один из идентификаторов экземпляра; GET отдаёт постраничную выборку с фильтрами по акторам, именам событий и моделей, идентификаторам экземпляров и ресурсов, целям, компании и диапазону времени регистрации, с сортировкой по убыванию времени и ответом со счётчиком, лимитом, смещением и ссылками на соседние страницы; запрос собирается конструктором Squirrel. В репозитории есть опция подключения Kafka-коннектора с продюсером и консьюмером, однако основной путь записи — синхронный HTTP плюс Postgres. Отдельный сервис-воркер решает задачу дообогащения: cron-джобы с интервалом 20 и 30 секунд выбирают записи без идентификатора компании по моделям документа и задачи проекта, через REST-клиенты определяют компанию (документы запрашиваются батчами по 500) и проставляют её вместе с флагом обработки в той же таблице. Используется ли Kafka-коннектор в проде и включена ли на таблице гипертаблица TimescaleDB, по коду не устанавливается.

## transmittal

Репозитории: pdm/transmittal-api — бэкенд сопроводительных писем и передач; pdm/transmittal-frontend — микрофронтенд трансмитталов. Стек: Python 3.12, FastAPI, Pydantic v2, async SQLAlchemy + Alembic, PostgreSQL (UUID, JSONB, массивы, интервалы), taskiq + RabbitMQ, boto3/S3, Jinja2 и собственный конвертер HTML → PDF, Mailgun и SMTP, httpx, PyJWT, OpenTelemetry; фронтенд — TypeScript, React, MobX, Material-UI, Webpack 5 Module Federation, внутренние `ui-kit` и `sdk-js`.

Компонент реализует формальную передачу комплектов проектной документации между участниками стройки — трансмиттал (сопроводительное письмо) с фиксацией состава, отправителя, получателей, сроков и результата. Пользователь формирует трансмиттал в рамках проекта, включает в него версии документов и комплектов, назначает получателей (по пользователям, отделам и ролям), задаёт срок и признак автоотправки. Получатели принимают или отклоняют передачу с комментарием — эти действия складываются в историю и в пошаговый маршрут. По завершении формируется акт передачи в PDF, доступный по временной ссылке. Отдельная сущность — шаблоны трансмитталов, задающие типовой состав получателей, допустимых инициаторов, интервал срока и текст; на фронтенде им отведён собственный раздел со списком, фильтрами, включением и переименованием. Трансмиттал связывается с согласованиями, то есть закрывает цикл «выдал документацию → получил замечания». Автоматическая инициация передачи после согласования настраивается на стороне flows.

Бэкенд построен по слоям контроллер → сценарий → репозиторий → сущность и DTO. Публичный API включает создание, списки и поиск (в том числе по ресурсам), справочники глобальных статусов и статусов, счётчик открытых трансмитталов пользователя, приём и отклонение, получение и удаление, выдачу ссылки на акт и проверку его готовности, привязку согласования, а также работу с шаблонами и шагами; внутренний контур отдаёт трансмитталы по идентификаторам комплектов для других сервисов. Схема БД: справочники статусов (с текстом штампа и признаком системного), шагов и действий; агрегат трансмиттала с ресурсом, компанией, автором, статусом, текущим шагом, массивом шагов, получателями в JSONB, номером, уникальным в пределах компании, признаками автоотправки и готовности акта и отметками отправки и получения; версии документов со связью с комплектом и признаком акта; действия пользователя с комментарием и массивами подразделений и ролей; шаблоны и связь с согласованиями. Интеграции — репозитории Django-монолита (пользователи, отделы, должности), документации, flows и ресурсов, сервис разметки (штампы, QR, ЭЦП), S3 для актов и почтовые сервисы. Асинхронная часть — брокер taskiq на RabbitMQ с ретраями: задачи уведомлений получателей и отправителя и генерации акта, плюс отдельные CLI-точки генерации акта, обработки просроченных трансмитталов и наполнения системных справочников.

## workspaces

Репозитории: pdm/workspaces-api — Go-бэкенд рабочих пространств, состояний и приложений; platform/workspaces-frontend — микрофронтенд v1; platform/workspace-v2-frontend — микрофронтенд v2. Стек: Go (gorilla/mux, go-pg с миграциями в коде, zap, Prometheus, Sentry, JWT на RSA), PostgreSQL; фронтенды — TypeScript, React, MobX, Material-UI, Webpack 5 Module Federation, внутренний `viewer` (3D/BIM/облака точек), Cypress со сравнением скриншотов, Jest; в v2 дополнительно кеш в IndexedDB и скрипты замера производительности на Puppeteer.

Рабочее пространство — это сцена, в которой пользователь одновременно работает с набором проектных данных: BIM-моделями, облаками точек, PDF-чертежами, панорамами и фотографиями, привязанными к объекту строительства. Пользователь добавляет в пространство документы и комплекты, настраивает их отображение (видимость, цветовые схемы, раскраска элементов по статусам и атрибутам, фильтры по свойствам BIM-элементов) и сохраняет результат как именованное состояние, к которому можно вернуться или которым можно поделиться; есть состояние по умолчанию, неудаляемые состояния и динамические состояния — сценарии с привязкой к времени или видео. Второй ключевой сценарий — приложения: в пространство можно устанавливать прикладные модули компании и создавать их экземпляры, которые подгружаются во фронтенд как отдельные федеративные модули; так в сцену встраиваются, например, замечания. Пространства и документы поддерживают архивирование и восстановление, что важно при закрытии этапов проекта. В v2 набор сценариев расширен: работа с атрибутами EAV, анализ и экспорт BIM-элементов, история статусов элемента, ресурсы элемента, отклонения облака точек с цветовыми пресетами.

Бэкенд единый для обеих версий фронтенда. Роутинг делится на публичный контур (карточка пространства, архивирование и восстановление, сброс кеша, изменение и архивирование документов, CRUD состояний и динамических состояний, добавление и удаление документов в пространстве, управление приложениями компании и их экземплярами) и два внутренних набора. Внутренний контур v1 содержит создание пространства с резолвом комплектов в документы с настраиваемым параллелизмом, внутренний контур v2 — отдельную процедуру создания пространства, батч-проверку принадлежности пространств к v2, удаление и восстановление документов. Именно эта пара внутренних наборов и миграции показывают соотношение версий: v2 — не отдельный сервис, а вторая модель данных внутри того же API (собственная таблица документов, создание без резолва комплектов), сосуществующая с v1; фронтенд v2 читает тот же эндпоинт карточки пространства, но ожидает в ответе поле документов v2. Хранилище — PostgreSQL через go-pg, внешние зависимости — клиенты документации и комплектов, есть CLI для сброса кеша. Оба фронтенда — remote-модули Module Federation с одинаковой архитектурой (декларативный реестр эндпоинтов, MobX-сторы пространств, приложений и документов), но v2 заметно шире по функциональности и дополнительно обращается к файловому сервису за геометрией и панорамами, к EAV за атрибутами и к шлюзу за динамическими состояниями. Выведен ли v1 из эксплуатации, по репозиториям не видно.
