О проекте
Команда: Orbit Digital | AKO
Кейс HackAlem.ai: Финансы — Freedom
Стадия: Доведённый продукт
Задача кейса: «Граф денег»: восстановить структуру организованной группы по сети транзакций (AML)
Суть
Локальная платформа для аналитика: загрузка банковской выгрузки, построение графа переводов, роли участников с объяснением, приоритеты проверки, кластеры и симуляция исключения узлов. Результаты собираются в дело и печатное HTML-досье.
Как устроено
Пайплайн mg/ (ingest → quality → features → roles → clusters → taint/cutoff → explain → export) работает по parquet, CSV или XLSX с мастером сопоставления колонок. Роли назначаются по настраиваемым порогам (абсолютным и адаптивным), приоритет — нормируемые веса. Учитывается граница выгрузки max_depth и хронологический анализ потока (taint). Симуляция удаляет выбранные узлы или топ-N и сравнивает эффект со случайным выбором по компонентам и кластерам. FastAPI с фоновыми задачами обслуживает React/Vite/Tailwind-интерфейс с графом, мета-графом кластеров, инспектором правил и таймлайном. Опциональный ассистент на OpenAI gpt-4.1-mini, основной анализ работает офлайн.
Ключевые решения
- правила ролей с абсолютными и адаптивными порогами
- кластеризация сети
- taint/анализ хронологического потока
- симуляция удаления узлов против случайного baseline
- учёт обрыва выгрузки
- валидация схемы выгрузок
Особенности
Универсальный инструмент, а не скрипт под один датасет: мастер импорта CSV/Parquet/XLSX с проверкой качества данных. Сравнение адаптивных и абсолютных порогов, калибровка по обратной связи аналитика, сценарии «что если убрать узлы». Экспорт досье, README на трёх языках (ru/en/kk), тесты доступности и производительности.
Стек
Python · FastAPI · pandas · Parquet · React · TypeScript · Vite · Tailwind CSS · Playwright · Docker Compose
Модели
gpt-4.1-mini
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-61c5ca4c-orbit-digital-ako.
README
README.mdГраф денег — роли и приоритеты финансовой сети
Локальная платформа для исследования переводов. Загрузите банковскую выгрузку, подтвердите назначение колонок и проверьте качество данных — приложение построит граф, объяснит предполагаемые роли участников, расставит приоритеты проверки и позволит сравнить сценарии исключения узлов. Результаты можно сохранить в дело и выгрузить в печатное досье.
Текущая версия — универсальный MVP для одного аналитика на своём компьютере. Аутентификации и личных кабинетов нет. Роли и оценки потока — аналитические гипотезы, которые требуют проверки, а не выводы о вине или доказательство происхождения конкретных денег.

Содержание
- Возможности и рабочий процесс
- Быстрый запуск в Docker
- Запуск без Docker: Windows, macOS, Linux
- Настройки и переменные окружения
- Форматы импорта и качество данных
- Проверка по ТЗ и обязательные выгрузки
- Правила ролей и пороги
- Расчёт и его ограничения
- Масштабирование до миллиона узлов
- Ассистент и API
- Архитектура и структура репозитория
- Хранение, обновление и резервная копия
- Разработка и проверки
- Решение проблем
- Документация, планы и участие
Возможности и рабочий процесс
- Создать проект. «Открыть пример» копирует поставляемый набор хакатона и запускает расчёт; «Новый анализ» открывает мастер загрузки своих файлов.
- Подготовить данные. Мастер проводит через файлы, сопоставление колонок, параметры и качество. Автопредложения можно исправить; расчёт начинается после подтверждения.
- Исследовать сеть. Обзор показывает показатели, топ-10, роли, кластеры, устойчивость и ограничения данных. В расследовании доступны окружение узла на 1–3 перехода, мета-граф кластеров, инспектор правил, переводы по ребру, временная шкала и проигрывание периода.
- Проверить гипотезу. Симуляция исключает выбранные узлы или топ-N, сравнивает эффект со случайным выбором и показывает изменения компонент и кластеров. Исключение меняет расчётный сценарий, а не банковские операции.
- Сохранить результат. Дело объединяет узлы, заметки и сценарии. HTML-досье содержит снимок версии расчёта, связи, основания выводов, трассировку, запросы недостающих данных и конфигурацию. Для PDF откройте досье и выберите печать браузера → «Сохранить как PDF».
Граф поддерживает поиск, фильтры, геометрические формы ролей, пиктограммы или круги, перемещение, закрепление и скрытие узлов, мини-карту, новую раскладку, полный экран и PNG. Вывод до 3 000 узлов выполняется по явному запросу. Таблица узлов использует виртуализацию, серверный поиск, сортировку и пагинацию; доступны настройка колонок, сохранённый вид, экспорт и массовое добавление в сценарий или дело. Карточки кластеров показывают мини-подграфы до 24 узлов, состав и гипотезу. Выбранный узел и фильтры сохраняются в ссылке.
В настройках правил можно сравнить абсолютные и адаптивные пороги, просмотреть изменения ролей, изменить нормируемые веса приоритета, применить пресет и запустить полный пересчёт. Обратная связь аналитика формирует предложения калибровки; они не применяются автоматически.
Интерфейс доступен на русском, казахском и английском, со светлой и тёмной темой и учётом системного предпочтения уменьшенной анимации. Основное рабочее место — настольный браузер; мобильный вид предназначен прежде всего для обзора и карточек.
Горячие клавиши: Ctrl/⌘+K или / — поиск; E — раскрыть соседей; B — добавить узел в симуляцию; A — добавить в дело; Esc — закрыть диалог, инспектор или полный экран; ? — помощь и глоссарий. E/B/A действуют вне полей ввода. Поиск и таблица позволяют выбирать узлы без мыши; вкладки инспектора поддерживают стрелки и Home/End.
Быстрый запуск в Docker
Нужны Git и Docker с Linux-контейнерами: Docker Desktop на Windows/macOS или Docker Engine с Compose на Linux. Версия Docker Compose — 2.24.0 или новее: используется необязательный файл окружения. Python и Node.js на компьютере для этого способа не нужны.
git clone --branch main https://github.com/BAITC-Hacks/hack-61c5ca4c-orbit-digital-ako.git
cd hack-61c5ca4c-orbit-digital-ako
docker compose version
docker compose up --build -d
docker compose ps
Откройте http://127.0.0.1:8000 и нажмите «Открыть пример». API и его локальная документация доступны на /api/docs, проверка работоспособности — на /api/health.
Первая сборка скачивает базовые образы, Python-зависимости и npm-пакеты. Dockerfile собирает React-интерфейс в этапе Node.js 22, затем запускает Python 3.12 от пользователя без прав root. SDK OpenAI уже включён; ключ для обычного анализа и локальных действий ассистента не нужен. Приложение работает одним процессом API, поскольку реестр фоновых задач находится в памяти процесса.
Compose публикует порт только на 127.0.0.1 и хранит проекты в отдельном томе. Не меняйте привязку на публичный интерфейс для совместной работы: в текущем MVP нет аутентификации. После установки основной анализ работает без интернета; сеть нужна для внешних вопросов к OpenAI и обновлений.
Управление из корня репозитория:
docker compose logs --tail=100 app
docker compose stop app
docker compose start app
docker compose down удаляет контейнер и сеть, сохраняя том с данными. docker compose down -v удаляет и том с проектами — не используйте этот вариант при обычном обновлении.
Запуск без Docker: Windows, macOS, Linux
Рекомендуется Python 3.12. Готовая сборка интерфейса включена в money_graph/web/dist/, поэтому Node.js для обычного запуска не требуется. Устанавливайте зависимости в отдельное виртуальное окружение.
Windows, PowerShell
Из корня клонированного репозитория:
py -3.12 -m venv .venv
.\.venv\Scripts\python.exe -m pip install -r money_graph/requirements.txt
cd money_graph
..\.venv\Scripts\python.exe serve.py
Команды используют интерпретатор напрямую и не требуют разрешать выполнение Activate.ps1. Если Python установлен без команды py, создайте окружение через python -m venv .venv, предварительно проверив python --version.
macOS и Linux
Из корня клонированного репозитория:
python3.12 -m venv .venv
.venv/bin/python -m pip install -r money_graph/requirements.txt
cd money_graph
../.venv/bin/python serve.py
На Linux пакет для создания виртуальных окружений может устанавливаться отдельно через пакетный менеджер дистрибутива. Запускайте serve.py из папки money_graph: приложение импортируется как api.main:app. Адрес — http://127.0.0.1:8000. Остановка — Ctrl+C в терминале.
Настройки и переменные окружения
Файл money_graph/config.json задаёт исходные пороги, веса ролей и приоритета, параметры кластеризации, расчёта потока и ограничения загрузки. Новый проект получает свою копию настроек; для существующего проекта меняйте параметры через интерфейс или API. Граница выгрузки max_depth и порог сбора collection_threshold в новом пользовательском проекте остаются неизвестными до явного указания аналитиком, даже если исходный набор хакатона имеет такие значения.
Переменные сервера:
OPENAI_API_KEY— необязательный ключ для внешних вопросов. Хранится только на сервере. Без него работают анализ и локальные инструменты ассистента.OPENAI_MODEL— модель внешнего ассистента; пример настройки используетgpt-4.1-mini.MONEY_GRAPH_PROJECTS— каталог рабочих проектов. Без Docker по умолчанию используетсяmoney_graph/projects. Задавайте эту переменную в окружении процесса до запуска сервера; не полагайтесь на её загрузку из.env. В Compose она явно установлена в/data/projects.MONEYGRAPH_PORT— только для Compose: порт компьютера, по умолчанию8000. Внутри контейнера остаётся порт8000;serve.pyэту переменную не использует.
Файл money_graph/.env.example содержит пустой ключ. Для настройки OpenAI скопируйте его в необязательный money_graph/.env, только если файл ещё не существует.
PowerShell, из корня репозитория:
if (-not (Test-Path money_graph/.env)) { Copy-Item money_graph/.env.example money_graph/.env }
Bash, из корня репозитория:
test -f money_graph/.env || cp money_graph/.env.example money_graph/.env
Добавьте ключ в этот локальный файл. Не отправляйте его в чат, не вводите в браузере и не добавляйте в Git. .env исключён из Git и контекста Docker-сборки; Compose читает его при создании контейнера. Для применения изменений окружения:
docker compose up -d --force-recreate app
При запуске без Docker дополнительно установите SDK из папки money_graph и перезапустите сервер:
python -m pip install -r requirements-ai.txt
Здесь и далее python означает интерпретатор вашего виртуального окружения: активируйте его или подставляйте путь из раздела запуска. У Docker-образа SDK уже установлен.
Чтобы выбрать другой порт Compose, в PowerShell задайте $env:MONEYGRAPH_PORT="8001", затем выполните docker compose up -d. В Bash используйте MONEYGRAPH_PORT=8001 docker compose up -d. После этого адрес приложения — http://127.0.0.1:8001.
Форматы импорта и качество данных
Поддерживаются CSV, Parquet и XLSX. Для CSV распознаются UTF-8, UTF-8 BOM, Windows-1251 и разделители ,, ;, табуляция, |. Для XLSX выбирается лист; формулы и макросы не выполняются. По умолчанию можно загрузить до 20 файлов на проект, до 500 МБ каждый; размер задаётся через upload_limit_mb в конфигурации. Размер распакованного XLSX ограничен четырьмя лимитами файла.
Названия исходных колонок могут отличаться: мастер предлагает соответствия по русским и английским синонимам и типам значений, показывает уверенность, исходные строки и результат преобразования. Аналитик подтверждает сопоставление перед анализом.
Канонические таблицы:
- Транзакции:
src— отправитель,dst— получатель,amount— положительная сумма;date— необязательная дата. Для анализа нужна эта таблица или таблица агрегированных связей. - Связи:
src,dst,amount— сумма переводов между парой;n_tx— число переводов, при отсутствии принимается равным 1. Если загружены транзакции, связи пересчитываются из них. - Узлы:
id, необязательныеdepthиis_seed. Таблица необязательна: недостающие участники добавляются из связей. - Исходные участники (seed): необязательная таблица с
id. Их также можно отметить черезis_seedили ввести списком. Seed задаёт исходную точку исследования и допущение модели потока.
Минимальный пример CSV с транзакциями:
src,dst,amount,date
A001,B002,12500.00,2026-09-01
B002,C003,7000.00,2026-09-02
Идентификаторы в ядре, API и браузере — строки. Сохраняйте значимые ведущие нули в исходном файле: Excel может убрать их ещё до импорта. Суммы вида 1 234,50 поддерживаются; при запятой внутри поля используйте корректное CSV-кавычкование или другой разделитель. Для неоднозначных дат выбирается порядок дня и месяца. Валюта задаётся для проекта; конвертации валют приложение не выполняет, поэтому суммы должны быть приведены к общей единице заранее.
В параметрах указываются валюта, seed, известный порог сбора данных, известная максимальная глубина выгрузки и язык текстовых оснований выводов. Вычисленная расстоянием по графу глубина не означает границу выгрузки: без явного max_depth классификация обрезки отключена.
Проверка качества выявляет пропуски, дубли, петли, некорректные суммы и даты, расхождения связей и транзакций, изолированные seed и компоненты графа. Если более 5% строк не содержат обязательных src, dst или amount, расчёт блокируется; при меньшей доле строки исключаются с предупреждением. Отрицательные и нулевые суммы исключаются: возвраты не преобразуются автоматически в обратные переводы. Совпадающие транзакции сохраняются и требуют проверки аналитиком.
При неполных данных приложение сокращает доступный анализ:
- Без дат временные метрики выключены; транзит оценивается по соотношению сумм. Если даты есть лишь у части переводов, временные метрики используют датированные строки, а обороты — все допустимые строки.
- Без глубины, но с seed, рассчитывается направленное расстояние BFS. Без глубины и seed обрезка не оценивается.
- Без seed приоритет опирается на структуру и обороты с перенормированием весов, а симуляция измеряет общий наблюдаемый поток.
- Модель продолжения за границей выгрузки требует дат, не менее 100 обучающих узлов и обоих классов. Если условия не соблюдены,
p_onwardотсутствует, а причина доступна в ограничениях.
Доступность расчётов отражена в summary.capabilities, на обзоре и в проверке качества. Неполная выгрузка не становится полной благодаря модели или ассистенту.
Проверка по ТЗ и обязательные выгрузки
Этот раздел отвечает требованиям разделов 7, 9 и 10 предоставленного ТЗ «Граф денег» и README стартового кода. Для исходного набора используются три приложенных Parquet: 2 248 узлов, 3 119 рёбер и 4 840 транзакций. Полный расчёт от этих файлов до выгрузок запускается из корня репозитория одной командой, без ручной разметки и без ключа OpenAI:
docker compose run --build --rm --no-deps app python run.py --out /data/baseline
Результат хранится в постоянном томе. Проверка обязательных схем и исходного числа узлов:
docker compose run --rm --no-deps app python check.py --out /data/baseline
После запуска основного приложения заберите результаты на компьютер командой docker compose cp app:/data/baseline ./baseline-results. Для веб-интерфейса используйте запуск из раздела Docker и «Демо»; произвольные пользовательские проекты не обязаны содержать 2 248 узлов.
Обязательные артефакты:
nodes_roles.csv: ровно 2 248 строк исходного набора;gid— int64,role— строка,role_score— число 0–1,cluster_id— целое,priority_score— число 0–1,evidence— непустое числовое объяснение длиной до 200 символов.clusters.csv:cluster_id,n_nodes,n_seed,sum_kzt_internal,top_gids,hypothesis; одна строка на кластер, с размером, числом seed, внутренним оборотом и гипотезой. Louvain применяется к неориентированной проекции; исходные денежные потоки остаются направленными.top_nodes.csv:rank,gid,role,priority_score,why; не менее 20 строк, по умолчанию 30, по убыванию приоритета.- Экран просмотра: направление переводов, роли, кластеры, поиск по
gidи объяснение выбранного узла. Схема решения и сценарий демонстрации включены в репозиторий.
Требование ТЗ — пересчёт предоставленного набора не более чем за 5 минут. Контрольный запуск 23 сентября 2026 года в Docker на текущем компьютере занял 8,88 секунды от запуска CLI до готовых файлов, после сборки образа; check.py пройден. Скачивание зависимостей и первая сборка в этот замер не входят. Это результат одного прогона исходного набора, а не гарантия времени для любого компьютера или графа.
Правила ролей и пороги
Актуальные источники: mg/explain.py, mg/roles.py и config.json. in_deg/out_deg — количество разных плательщиков/получателей; pass_through = out_kzt / in_kzt учитывает только видимые переводы. При нулевом входящем объёме это отношение не определено. Ниже — исходный режим absolute; срабатывает первое подходящее правило:
- Изолированный узел:
in_deg = out_deg = 0→peripheral. - Граница выгрузки: известен
max_depth,depth = max_depthиout_deg = 0→ внутренняя рольtruncated. В исходном наборе это 444 узла четвёртого колена. В CSV:role=peripheral,role_detail=truncated,is_truncated=True; информация об обрыве сохраняется. coordinator:in_deg ≥ 5,out_deg ≥ 5, посредничествоbetweenness > 0и не ниже 95-го процентиля по узлам.distributor:out_deg ≥ 10иout_deg / max(in_deg, 1) ≥ 3.consolidator:in_deg ≥ 4. Порогpass_through ≤ 0,5влияет на оценку уверенности, но не является обязательным условием этой роли.transit: узел не seed,in_deg > 0,out_deg > 0и либо0,7 ≤ pass_through ≤ 1,3, либоfast_share ≥ 0,7приpass_through ≥ 0,5. Быстрая доля использует временное окно до двух дней; без дат работает только ветка отношения сумм.terminal:out_deg = 0, входящая сумма ≥ 100 000 единиц валюты проекта илиin_deg ≥ 2; при известномmax_depthдополнительно нужна известнаяdepth < max_depth. При неизвестной границе проверка глубины не применяется, поэтому вывод особенно зависит от полноты данных.peripheral: остальные узлы.
В адаптивном режиме минимальные количества связей для координатора, распределителя и консолидатора повышаются до максимума исходного порога и 99-го процентиля соответствующей степени. Инспектор показывает применённые пороги и все условия. role_score — эвристическая оценка силы признаков, а не обученная вероятность правильности роли.
Приоритет объединяет ранги положительных значений: прослеживаемые поступления — 25%, эффект блокировки — 25%, вес роли — 20%, посредничество — 10%, число источников seed — 10%, оборот — 10%. Вес роли: coordinator 1, consolidator 0,9, distributor 0,8, transit 0,6, truncated 0,4, terminal 0,3, peripheral 0. Итог делится на максимальный балл в текущем графе. Без seed соответствующие два компонента отключаются, остальные веса нормируются заново. Поэтому баллы предназначены для сравнения узлов внутри одного расчёта.
Расчёт и его ограничения
CLI и веб-проекты используют общее ядро mg.pipeline.run_pipeline: метрики направленного графа → распространение потока → эффект исключения узлов → оценка обрезки → роли и приоритет → кластеры → устойчивость. Назначение ролей и объяснение правил используют единый интерпретатор, поэтому в инспекторе можно проверить сработавшие условия.
Текущая модель потока — итеративное пропорциональное распределение, haircut. Исходным seed приписывается доля 1; остальные узлы передают долю, полученную из входящих связей. Расчёт идёт по агрегированному графу, не моделирует хронологические остатки на счетах. Даты используются в отдельных признаках и интерфейсе, но не превращают эту модель в последовательное отслеживание переводов. Сумма потока по рёбрам может учитывать одну и ту же условную денежную массу на нескольких переходах; она отличается от поступлений на наблюдаемые конечные узлы, которые показывает Sankey до и после исключения узлов.
Симуляция пересчитывает модель после удаления узлов. Её результат зависит от полноты сети, заданных seed и параметров; это оценка сценария, а не прогноз действий участников. Приоритет — относительный порядок проверки узлов внутри расчёта, не вероятность нарушения. AUC, когда модель обучена, относится к оценке продолжения за границей выгрузки, а не к точности назначения ролей.
Ограничения реализации:
- При более чем 5 000 узлов посредничество оценивается по воспроизводимой выборке источников, по умолчанию 500 (
betweenness_samples). - При более чем 20 000 узлов отдельный эффект блокировки вычисляется для ограниченного набора кандидатов, по умолчанию 1 000 (
block_top_k). Для остальных значение отсутствует (NaN), а не равно нулю. - Короткие циклы ищутся до длины 4 с лимитом по умолчанию 100 000; при достижении лимита число циклов — нижняя оценка.
- Поиск путей ограничен 12 переходами и 20 000 раскрытиями, пути ранжируются по произведению долей потока. Отдельные инструменты ассистента имеют более узкие лимиты из контракта интеграций.
- Расчёт устойчивости в ядре использует 20 случайных сравнений, а для графов свыше 20 000 узлов — 5. Размер и плотность сети влияют на время работы и память. Louvain и посредничество могут быть затратными; гарантии расчёта произвольного графа за пять минут нет.
- Роли и пороги требуют независимой проверки на размеченных данных. Текущий MVP не заявляет измеренную точность выявления нарушений.
Отчёт VALIDATION от 23 сентября 2026 года сохраняет результаты прежнего контрольного прогона и условия синтетического замера. Это исторический отчёт, а не подтверждение повторного выполнения всех проверок или измерения производительности текущей Docker-сборки.
Масштабирование до ~1 млн узлов
Это план изменения подхода, требуемый ТЗ; текущая версия не заявляет проверенную обработку миллиона узлов.
- Читать и агрегировать переводы пакетами из Parquet, отделить хранение исходных данных от вычислительного графа, сохранять контрольные точки вместо загрузки всех таблиц в память.
- Заменить объектный граф NetworkX компактным графовым движком и разреженными массивами/матрицами. Перенести итерации потока на разреженные операции; оценивать память с учётом числа рёбер и транзакций, а не только узлов.
- Оценивать посредничество по выборке источников; дорогие симуляции выполнять для ограниченного списка кандидатов. Ограничить поиск циклов и путей, явно показывать приближённые и нерассчитанные показатели.
- Разделить API и расчёты через устойчивую очередь с сохранением задач, отменой и ограничением ресурсов. Добавлять воркеры только после замены текущих внутрипроцессных блокировок и реестра задач.
- Показывать агрегированные кластеры и запрашиваемые окрестности, использовать серверные фильтры и пагинацию. Миллион узлов целиком в браузере не отображать.
- Проверить время, пиковую память и качество приближений на графах разной плотности и на независимой выборке. Ограничение пяти минут из ТЗ относится к выданному набору из 2 248 узлов; для миллиона нужен отдельный измеримый бюджет.
Ассистент и API
Ассистент связан с сохранённой версией расчёта выбранного проекта. Без ключа и без внешних запросов доступны объяснение узлов, общие получатели, направленный путь и предложение недостающих данных. Можно выбрать от 1 до 5 узлов; для направленного пути нужны ровно два, в порядке «откуда → куда». Ответы содержат ссылки на существующие узлы и связи с переходом на граф; валюта берётся из профиля проекта.
Вопросы на естественном языке используют OpenAI только после настройки сервера и явного подтверждения отправки для каждого запроса. Передаются вопрос, выбранные идентификаторы и ограниченные результаты вызванных инструментов; исходные файлы целиком не отправляются. Ассистент читает рассчитанные факты, не меняет данные, роли или правила, не запускает произвольный код и не выполняет веб-поиск. Его текст всё равно нужно сопоставлять с показанными основаниями.
Ключ не возвращается браузеру и не включается в репозиторий или образ. Использование внешней модели оплачивается по условиям вашего API-аккаунта; наличие ключа не гарантирует доступ к конкретной модели или достаточную квоту. Автоматические проверки с имитацией провайдера не заменяют отдельную проверку реального запроса.
Интеграции, контракт API и работа ассистента — настройка OpenAI, запросы и ответы, согласие на передачу и обработка ошибок. Актуальная схема всех маршрутов доступна на локальной странице OpenAPI; её JS и CSS поставляются вместе с приложением.
API охватывает проекты и импорт, сопоставление и качество, запуск и SSE-прогресс задач, обзор и метрики узлов, объяснения, граф и пути, симуляцию, правила, обратную связь, калибровку, дела и экспорты. Основные входы: /api/projects, /api/demo, /api/jobs/{id}/events, /api/assistant/status и /api/projects/{pid}/assistant. Интеграция должна обращаться к локальному серверу; текущий API не является публичным сервисом с разграничением доступа.
Архитектура и структура репозитория
flowchart LR
Files["CSV / Parquet / XLSX"] --> Import["Сопоставление и качество"]
CLI["run.py — контракт хакатона"] --> Dataset["Dataset + DatasetProfile"]
Import --> Dataset
Dataset --> Kernel["mg.pipeline.run_pipeline"]
Kernel --> Results["Метрики, роли, приоритет, кластеры, устойчивость"]
Results --> Storage["Версии проектов и экспорты"]
Storage --> API["FastAPI + очередь в процессе + SSE"]
API --> UI["React / TypeScript + Sigma.js"]
API --> Tools["Локальные инструменты ассистента"]
Tools -. "вопрос + согласие" .-> OpenAI["OpenAI API"]
Аналитическое ядро использует pandas, NumPy, NetworkX и scikit-learn. mg/dataset.py задаёт нормализованные таблицы и профиль, mg/ingest.py читает файлы, mg/quality.py проверяет данные, mg/pipeline.py выполняет расчёт без HTTP и записи файлов. mg/explain.py объединяет правила назначения ролей и их объяснения; mg/i18n/ содержит локализованные основания и гипотезы.
api/storage.py ограничивает файловые пути, атомарно записывает JSON и хранит версии результатов. api/jobs.py выполняет расчёты в последовательном ThreadPoolExecutor и сообщает прогресс через SSE. api/main.py предоставляет API и локальную статику; server.py оставлен как совместимый импорт приложения. Адаптер api/assistant.py соединяет проекты с инструментами mg/assistant.py.
Интерфейс: React / TypeScript, Sigma.js / graphology, TanStack Query / Table / Virtual, Recharts, Radix Dialog, Tailwind, Zustand и i18next. Шрифт Inter, ресурсы интерфейса и Swagger локальные; CDN и телеметрия для анализа не требуются.
README.md, README.en.md, README.kk.md Документация на трёх языках
Dockerfile, compose.yaml Сборка и локальный запуск контейнера
money_graph/docs/INTEGRATIONS.md Контракты внешних интеграций
tests/ Проверки исходного контракта и ассистента
money_graph/
serve.py Локальный сервер
run.py, check.py CLI и проверка набора хакатона
config.json Исходные параметры расчёта
mg/ Общее аналитическое ядро
api/ FastAPI, хранилище, задачи, ассистент
web/src/, web/dist/ React-исходники и готовая сборка
ui/ Ресурсы автономного CLI-viewer
data/, out/ Исходный набор и результаты CLI
projects/ Пользовательские проекты вне Git
tests/, tools/ Проверки, синтетика, замер
docs/ Методика, отчёт, демонстрация, снимки
Хранение, обновление и резервная копия
Без Docker проекты сохраняются в money_graph/projects/ либо каталоге MONEY_GRAPH_PROJECTS. В Compose логический том moneygraph_data подключён к /data, проекты лежат в /data/projects. Фактическое имя тома обычно включает имя Compose-проекта. Пересоздание контейнера сохраняет данные; смена имени Compose-проекта может подключить другой, пустой том.
projects/<id>/
project.json, mapping.json, config.json, quality.json, profile.json
raw/ Загруженные исходники
nodes.parquet, edges.parquet, transactions.parquet
current.json Ссылка на активную версию
results/<hash>/ Результаты, снимок данных и настроек
feedback.json, cases.json Обратная связь и дела
Кэш зависит от нормализованных данных, конфигурации и версии алгоритма. Дела привязаны к сохранённым результатам. Одновременно допускается одна задача на проект; данные нельзя менять во время расчёта. Общий исполнитель последовательно обрабатывает расчёты. Отмена действует между этапами: выполняющаяся операция NetworkX сначала завершится. Завершённые результаты переживают перезапуск сервера, а незавершённый расчёт нужно запустить заново. Внешней восстанавливаемой очереди задач нет.
Резервная копия
Дождитесь завершения расчётов и остановите приложение, чтобы копия включала согласованный набор файлов. Создайте в корне репозитория папку backups — она исключена из Git — и скопируйте /data в новый подкаталог:
docker compose stop app
docker compose cp app:/data ./backups/moneygraph-backup
docker compose start app
В новой папке backups/moneygraph-backup должен быть каталог projects; проверьте наличие нужных проектов и версий результатов. Если папка назначения уже существует, используйте новое имя для очередной копии. Для локального Python-запуска остановите сервер и скопируйте весь каталог проектов, а не только current.json или CSV. Полные процедуры переноса и восстановления — в руководстве по развёртыванию.
Для восстановления остановите приложение, сохраните отдельную копию текущего состояния и восстановите всю папку проектов из резервной копии. В контейнере файлы должны быть доступны пользователю UID/GID 10001:10001; при переносе между хостами проверьте права. Локальный .env храните отдельно от обычных экспортов в защищённом хранилище секретов. После восстановления откройте несколько проектов и проверьте сохранённые версии и дела.
Обновление
Сначала сделайте резервную копию и сохраните свои изменения исходников. Затем из корня репозитория:
git pull --ff-only
docker compose up --build -d
docker compose ps
При запуске без Docker обновите Python-зависимости в окружении и перезапустите сервер. Если меняли исходники React, заново соберите web/dist. Не используйте удаление тома как способ обновления.
Приватность и удаление
Проекты и .env исключены из Git. У пользовательского каталога, заданного через MONEY_GRAPH_PROJECTS, проверьте политику резервного копирования и исключение из репозиториев отдельно. Приложение проверяет Host и Origin, отклоняет внешние межсайтовые изменения, ограничивает расширения, размеры и распакованный XLSX. Имена файлов используются как подписи, а не пути: на диске загрузки получают случайные идентификаторы. CSV защищены от формул Excel; React и HTML-досье экранируют текст. Обычные HTTP access-логи с идентификаторами отключены в командах запуска.
Это не заменяет аутентификацию или шифрование: любой, кто имеет доступ к локальному API, получает доступ к его проектам. Приложение не шифрует данные на диске; используйте защищённую учётную запись ОС, шифрование диска и контролируемые резервные копии.
Удаление проекта убирает его исходники, версии результатов, обратную связь и дела, а также состояние проекта в текущем браузере. Оно не удаляет скачанные экспорты, снимки, резервные копии и состояние другого браузера. Автономный viewer.html и HTML-досье содержат встроенные данные — передавайте их как чувствительные рабочие материалы.
Разработка и проверки
Интерфейс
Нужен Node.js 20.19+ или 22.12+ совместимой ветки; Docker собирает интерфейс на Node.js 22. Из корня репозитория:
cd money_graph/web
npm ci
npm run dev
Сервер Python должен работать отдельно на порту 8000. Vite предоставляет адрес для разработки в терминале и перенаправляет /api на локальный сервер. Для сборки из той же папки:
npm run build
Команда проверяет TypeScript и создаёт web/dist. В репозитории поддерживаются исходники, lock-файл и готовая сборка; при изменении интерфейса обновляйте их согласованно.
Python и браузерные сценарии
Из папки money_graph, с Python виртуального окружения:
python -m pip install -r requirements-dev.txt
python -m pytest ../tests tests -q
Для браузерных проверок нужны готовый web/dist, синтетические примеры и браузер. Из money_graph/web, с активным Python-окружением:
npm ci
npm run build
python ../tools/make_synthetic.py --out ../.local/synthetic
npx playwright install chromium
npm run test:e2e
Playwright по умолчанию использует установленный им Chromium и запускает Python-сервер на http://127.0.0.1:8000; вне CI может использовать уже работающий сервер. Для своего Chromium/Chrome/Edge задайте PLAYWRIGHT_BROWSER абсолютным путём к исполняемому файлу. На Linux для браузера могут потребоваться системные зависимости: npx playwright install --with-deps chromium.
Чтобы проверить уже запущенный экземпляр, например Docker на другом порту, задайте PLAYWRIGHT_BASE_URL его адресом: это отключит автоматический запуск сервера. Сценарии создают тестовые проекты; удалите их через интерфейс после проверки. Снимки тестов сохраняются в каталоге результатов Playwright, а синтетические данные — в игнорируемой .local/.
CLI и исходный контракт хакатона
Из папки money_graph:
python run.py
python check.py
В out/ создаются nodes_roles.csv, clusters.csv, top_nodes.csv, requests.csv, resilience.csv, summary.json, nodes.parquet и автономный viewer.html. Параметры run.py: --data, --out, --config. Числовые идентификаторы в CLI CSV сохраняются как int64, если преобразование обратимо; в ядре и API остаются строками.
В CSV обязательное поле role содержит только шесть значений стартового кода. Для узлов на границе выгрузки экспортируется role=peripheral, role_detail=truncated, is_truncated=True; role_base совпадает с role. Это техническое отображение в словарь ТЗ, а не утверждение о поведении клиента. Все 444 пограничных узла сохранены. Граф, внутренний Parquet, оценки и расчёт приоритетов по-прежнему различают обрезку данных и конечных получателей. Правило применяется к CLI, отдельным CSV, ZIP и выбранным строкам, включая скачивание старых сохранённых результатов.
check.py проверяет исходную схему и набор из 2 248 узлов хакатона, а не произвольные пользовательские файлы. Для загружаемых проектов используется универсальная проверка качества. BASELINE_METHOD.md описывает исходный метод и предпосылки; старые команды веб-запуска в этой архивной записке заменены инструкциями этого README.
Необязательная проверка на большой синтетике, из money_graph:
python tools/make_synthetic.py --big
python tools/benchmark.py --big
Это отдельный затратный прогон; генератор и отчёт используют игнорируемую .local/. Скрипт проверяет своё условие времени на машине запуска, но его результат нельзя переносить на произвольные сети и оборудование. При публикации нового замера указывайте ревизию, конфигурацию, размеры данных и условия запуска.
Доступность: исправления и границы проверки.
Решение проблем
- Compose отвергает
required: false. Проверьтеdocker compose versionи обновите Compose до 2.24.0 или новее. Используйтеdocker compose, а не старый отдельныйdocker-compose. - Страница не открывается. Проверьте
docker compose ps, затемdocker compose logs --tail=100 app. При запуске Python прочитайте ошибку в терминале; запускайтеserve.pyизmoney_graph. В Docker открывайте адрес опубликованного порта, а не адрес контейнера. - Порт 8000 занят. Остановите другой экземпляр приложения либо задайте
MONEYGRAPH_PORTдля Compose. Для локального Python можно изmoney_graphзапуститьpython -m uvicorn api.main:app --host 127.0.0.1 --port 8001 --workers 1 --no-access-log; тесты и Vite по умолчанию ожидают 8000. - Проекты исчезли после перезапуска. Проверьте каталог
MONEY_GRAPH_PROJECTSили имя Compose-проекта и подключённый том. Пересоздание контейнера само по себе проекты не удаляет;down -vудаляет том. Не создавайте новые данные поверх предполагаемой резервной копии до проверки путей. - Нет формы внешнего вопроса. Проверьте серверную настройку ключа, наличие SDK при запуске без Docker и перезапуск после изменения окружения. Для Compose нужен
up -d --force-recreate app, посколькуrestartне перечитываетenv_file. Локальные действия работают независимо от ключа. - OpenAI вернул ошибку. Ориентируйтесь на сообщение о настройках, модели, квоте или соединении. Проверьте доступ сервера к API; не публикуйте ключ или содержимое
.envв отчёте об ошибке. Подробности — в документации интеграций. - Расчёт заблокирован на качестве. Исправьте сопоставление обязательных колонок, форматы сумм и даты, затем повторите проверку. Отсутствие временных метрик или оценки обрезки может быть ожидаемым ограничением данных.
- Отмена не мгновенная или задача потерялась после перезапуска. Отмена применяется между этапами; дождитесь текущей операции. Незавершённую задачу после перезапуска запустите снова. Не добавляйте несколько Uvicorn workers: состояние задач не разделяется между процессами.
- Playwright не находит браузер или тестовые файлы. Установите Chromium командой
npx playwright install chromiumлибо задайтеPLAYWRIGHT_BROWSER. Создайте синтетику командой из раздела проверок. Если заданPLAYWRIGHT_BASE_URL, сервер по этому адресу нужно запустить самостоятельно. - Изменения React не видны в обычном приложении. Выполните
npm run buildвmoney_graph/webлибо пересоберите Docker-образ.
Документация, планы и участие
- Развёртывание, перенос и восстановление данных.
- Контракт API, ассистент и внешние интеграции.
- Метод исходного набора хакатона.
- Исторический отчёт проверок от 23 сентября 2026 года.
- Сценарий демонстрации.
- Снимки: проекты, сопоставление, качество, обзор, расследование, узлы, кластеры, симуляция, правила, дело, ассистент, тёмная тема, мобильный обзор.
Ближайшие направления развития: независимая проверка ролей и порогов на размеченных данных, испытания на других форматах и плотностях сети, восстанавливаемая очередь расчётов с ограничением ресурсов и отменой внутри этапов, оценка качества ответов ассистента. Для нескольких пользователей требуется отдельная работа над аутентификацией, правами доступа, аудитом, хранением и защищённым сетевым развёртыванием.
В истории репозитория, в частности в ab08d0d, есть прежние личные кабинеты и другая хронологическая модель движения денег. Они не входят в текущий универсальный MVP. Ассистент адаптирован к текущим проектам; для переноса остальных возможностей нужны отдельный режим расчёта, согласование API и собственные эталонные проверки.
Изменения оформляйте через ветку и pull request: опишите воспроизводимую проблему, ожидаемое поведение и выполненные проверки. Для правок расчёта добавляйте содержательный пример с ожидаемым результатом; для UI проверяйте сборку, доступность и соответствующие браузерные сценарии. Обновляйте документацию на трёх языках. В issues, тестовых данных и коммитах не должно быть реальных выгрузок, персональных данных и API-ключей.
В корне репозитория нет файла LICENSE. Этот README не предоставляет отдельной лицензии на код; условия использования и распространения следует уточнить у правообладателей. Лицензии включённых сторонних компонентов действуют отдельно.
Авторы коммитов
История коммитов
- 2026-09-23 17:54docs: align all READMEs with hackathon acceptance requirementsOrkennn
- 2026-09-23 17:49Merge latest teammate accessibility improvementsOrkennn
- 2026-09-23 17:48Merge latest role export contract with Docker and multilingual docsOrkennn
- 2026-09-23 17:46feat: add portable Docker deployment and trilingual documentationOrkennn
- 2026-09-23 16:51feat: integrate OpenAI assistant and chronological flow analysisOrkennn
- 2026-09-23 14:49Merge origin/main: keep offline UI overhaul, fix test data path, add schema testsOrkennn
- 2026-09-23 17:46Merge latest main schema updates with accessibility fixesakezhan kh
- 2026-09-23 17:46Fix cluster overview layout and improve keyboard accessibilityakezhan kh
Все коммиты (42)
- 2026-09-23 17:39fix: enforce hackathon role schema without losing truncation evidenceYour Name
- 2026-09-23 14:24Add schema validator and role_base safety columnOrkennn
- 2026-09-23 17:24Merge universal investigation MVP into main with current implementation priorityakezhan kh
- 2026-09-23 17:20Build universal investigation MVP and document root setupakezhan kh
- 2026-09-23 13:54Merge remote-tracking branch 'origin/main'Orkennn
- 2026-09-23 13:54Add data loading, graph building and feature engineering modulesOrkennn
- 2026-09-23 16:26feat: add private analyst workspaces and evidence reportsYour Name
- 2026-09-23 15:43Delete README.mdakezhan96
- 2026-09-23 15:43Merge team transaction drill-down with responsive analyst workspaceYour Name
- 2026-09-23 15:40fix: make analyst workspace readable and responsiveYour Name
- 2026-09-23 15:36Redesign analyst workspace and connect transaction drill-downakezhan kh
- 2026-09-23 15:14Build local case analysis MVP with interactive graphakezhan kh
- 2026-09-23 14:56Merge schema validation and regenerate secured viewerakezhan kh
- 2026-09-23 14:54Remove external LLM integration and harden offline viewerakezhan kh
- 2026-09-23 14:43test: add financial input contract smoke testskorgann
- 2026-09-23 14:41Unify money graph project and improve offline analyst UIakezhan kh
- 2026-09-23 14:11Add complete money graph project artifactsakezhan kh
- 2026-09-23 13:59data: add transaction graph inputskorgann
- 2026-09-23 13:57feat: add money graph starter.pykorgann
- 2026-09-23 13:57feat: add money graph README.mdkorgann
- 2026-09-23 13:57feat: add money graph viewer.pykorgann
- 2026-09-23 13:57feat: add money graph taint.pykorgann
- 2026-09-23 13:57feat: add money graph roles.pykorgann
- 2026-09-23 13:57feat: add money graph llm.pykorgann
- 2026-09-23 13:57feat: add money graph features.pykorgann
- 2026-09-23 13:57feat: add money graph cutoff.pykorgann
- 2026-09-23 13:57feat: add money graph clusters.pykorgann
- 2026-09-23 13:57feat: add money graph __init__.pykorgann
- 2026-09-23 13:57feat: add money graph run.pykorgann
- 2026-09-23 13:57feat: add money graph requirements.txtkorgann
- 2026-09-23 13:57feat: add money graph config.jsonkorgann
- 2026-09-23 13:54docs: add demo scriptkorgann
- 2026-09-23 13:53docs: add project noteskorgann
- 2026-09-23 13:49Add project READMEakezhan kh
Структура репозитория (134 файлов)
.dockerignore .gitignore Dockerfile README.en.md README.kk.md README.md compose.yaml money_graph/.env.example money_graph/DEMO_SCRIPT.md money_graph/PROJECT_NOTES.md money_graph/README.md money_graph/api/__init__.py money_graph/api/assistant.py money_graph/api/jobs.py money_graph/api/main.py money_graph/api/schemas.py money_graph/api/storage.py money_graph/check.py money_graph/config.json money_graph/data/README.md money_graph/data/edges.parquet money_graph/data/nodes.parquet money_graph/data/transactions.parquet money_graph/docs/ACCESSIBILITY.md money_graph/docs/BASELINE_METHOD.md money_graph/docs/DEMO_SCRIPT.md money_graph/docs/DEPLOYMENT.md money_graph/docs/INTEGRATIONS.md money_graph/docs/VALIDATION.md money_graph/docs/screens/assistant.png money_graph/docs/screens/cases.png money_graph/docs/screens/cluster-overview.png money_graph/docs/screens/clusters.png money_graph/docs/screens/dark.png money_graph/docs/screens/investigate.png money_graph/docs/screens/mapping.png money_graph/docs/screens/mobile.png money_graph/docs/screens/nodes.png money_graph/docs/screens/overview.png money_graph/docs/screens/projects.png money_graph/docs/screens/quality.png money_graph/docs/screens/settings.png money_graph/docs/screens/simulation.png money_graph/docs/ui-overview.png money_graph/mg/__init__.py money_graph/mg/assistant.py money_graph/mg/clusters.py money_graph/mg/cutoff.py money_graph/mg/dataset.py money_graph/mg/explain.py money_graph/mg/export.py money_graph/mg/features.py money_graph/mg/i18n/en.json money_graph/mg/i18n/kk.json money_graph/mg/i18n/ru.json money_graph/mg/ingest.py money_graph/mg/paths.py money_graph/mg/pipeline.py money_graph/mg/provider_errors.py money_graph/mg/quality.py money_graph/mg/report.py money_graph/mg/roles.py money_graph/mg/taint.py money_graph/mg/validation.py money_graph/mg/viewer.py money_graph/out/clusters.csv money_graph/out/nodes.parquet money_graph/out/nodes_roles.csv money_graph/out/requests.csv money_graph/out/resilience.csv money_graph/out/summary.json money_graph/out/top_nodes.csv money_graph/out/viewer.html money_graph/requirements-ai.txt money_graph/requirements-dev.txt money_graph/requirements.txt money_graph/run.py money_graph/serve.py money_graph/server.py money_graph/starter/README.md money_graph/starter/requirements.txt money_graph/starter/starter.py money_graph/tests/test_api_workflow.py money_graph/tests/test_container_runtime.py money_graph/tests/test_universal.py money_graph/tools/benchmark.py money_graph/tools/make_synthetic.py money_graph/ui/app.js money_graph/ui/index.html money_graph/ui/styles.css money_graph/web/e2e/accessibility.spec.ts money_graph/web/e2e/assistant.spec.ts money_graph/web/e2e/performance.spec.ts money_graph/web/e2e/workspace.spec.ts money_graph/web/favicon.svg money_graph/web/index.html money_graph/web/package-lock.json money_graph/web/package.json money_graph/web/playwright.config.ts money_graph/web/postcss.config.js money_graph/web/public/fonts/OFL.txt money_graph/web/public/fonts/inter-cyrillic-400-normal.woff2 money_graph/web/public/fonts/inter-cyrillic-600-normal.woff2 money_graph/web/public/fonts/inter-cyrillic-ext-400-normal.woff2 money_graph/web/public/fonts/inter-cyrillic-ext-600-normal.woff2 money_graph/web/public/fonts/inter-latin-400-normal.woff2 money_graph/web/public/fonts/inter-latin-600-normal.woff2 money_graph/web/src/AnalysisTools.tsx money_graph/web/src/App.tsx money_graph/web/src/Assistant.tsx money_graph/web/src/Dashboard.tsx money_graph/web/src/GraphCanvas.tsx money_graph/web/src/Inspector.tsx money_graph/web/src/Investigation.tsx money_graph/web/src/NodeTable.tsx money_graph/web/src/Projects.tsx money_graph/web/src/api.ts money_graph/web/src/components.tsx money_graph/web/src/i18n.ts money_graph/web/src/main.tsx money_graph/web/src/overviewLayout.ts money_graph/web/src/store.ts money_graph/web/src/styles.css money_graph/web/src/types.ts money_graph/web/tailwind.config.js money_graph/web/tsconfig.json money_graph/web/vite.config.ts tests/test_assistant.py tests/test_data_contract.py tests/test_mvp_contract.py tests/test_output_schema.py tests/test_provider_errors.py tests/test_role_exports.py tests/test_strict_role_contract.py
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.