AAYMA
RU
Войти

Граф денег

Объяснимый AML-инструмент на Go: по графу переводов от 81 seed назначает каждому из 2 248 клиентов роль, кластер и приоритет, выгружает три CSV и…

Доведённый продукт
Команда «Zzz Technology» 8💬 0 комментариевс 23 сентября 2026 г.

О проекте

Команда: Zzz Technology
Кейс HackAlem.ai: Финансы — Freedom
Стадия: Доведённый продукт

Задача кейса: «Граф денег»: восстановить структуру организованной группы по сети транзакций (AML)

Суть

Объяснимый AML-инструмент на Go: по графу переводов от 81 seed назначает каждому из 2 248 клиентов роль, кластер и приоритет, выгружает три CSV и показывает сеть в React-интерфейсе с AI-ассистентом.

Как устроено

Три parquet загружаются и сверяются (агрегированные рёбра против транзакций), строится направленный взвешенный граф. Считаются метрики: своя реализация взвешенного PageRank, HITS, betweenness, pass_through, временные признаки, возвратные циклы, дробление сумм. Шесть ролей назначаются по формальным правилам с порогами по квантилям, кластеры выделяет Louvain, priority_score считается как взвешенная сумма перцентилей, evidence пишется по шаблону. LLM (OpenAI Responses API) получает готовые факты и только пишет справки и гипотезы; ответы кэшируются в llm_cache.json, поэтому всё воспроизводится без ключа.

Ключевые решения

  • PageRank (своя реализация)
  • HITS
  • betweenness centrality
  • Louvain
  • правила ролей с квантильными порогами
  • перцентильный приоритет
  • анализ устойчивости сети (изъятие топ-N)
  • чувствительность весов (729 комбинаций)
  • LLM-ассистент с 8 инструментами
  • кэш LLM-ответов

Метрики

Пайплайн < 1 с; при сдвигах весов ±0.05 (729 комбинаций) в топ-10 остаются ≥7 узлов (в среднем 8.7), в топ-30 ≥26

Особенности

Детерминированный пайплайн: два прогона дают байт-в-байт одинаковые файлы. LLM-ответы закоммичены в кэш, так что тексты воспроизводятся без ключа. Отдельно разобраны ловушки данных: узлы 4-го колена, на которых обход обрывается, не считаются стоками, а seed штрафуются в приоритете. Устойчивость топа проверена перебором весов.

Стек

Go · Fiber · React · cytoscape.js · Docker Compose · Makefile · parquet

Модели

OpenAI Responses API


Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-bf176827-zzz-technology.

README

README.md

Граф денег

Русский · Қазақша (KZ) · English (EN)

Объяснимый анализ сети банковских переводов для AML-аналитика. Кейс «Граф денег: восстановление финансовой структуры организованной группы по транзакционной сети», хакатон HackAlem AI, команда Zzz Technology.

Инструмент отвечает на вопрос аналитика: «кого из 2 248 клиентов смотреть первым и почему». По графу переводов от 81 известного участника (seed) он назначает каждому узлу роль, кластер и приоритет, пишет обоснование с числами, показывает схему сети и позволяет проверить любой gid за десять секунд.

Все выводы системы — гипотезы для проверки, а не доказательства нарушений.


Быстрый старт для жюри

Нужен только Docker с Compose и интернет на время сборки.

git clone https://github.com/BAITC-Hacks/hack-bf176827-zzz-technology.git
cd hack-bf176827-zzz-technology
docker compose up --build

Через 1–3 минуты (сборка) откройте http://localhost:8080. При старте контейнер сам выполняет пайплайн, проверку выгрузок и поднимает интерфейс с API. Три CSV появятся на хосте в out/. Остановка: docker compose down.

Без Docker (нужен Go 1.25+): make demo — пайплайн, проверка и сервер со встроенным просмотрщиком. С React-интерфейсом дополнительно нужны Node.js 22+ и npm: make demo-full.

Пайплайн отрабатывает менее секунды, интернет и ключ LLM для воспроизведения не нужны.

[!IMPORTANT] Ключ OpenAI открывает AI-функции. Роли, приоритеты, кластеры и интерфейс работают без него. Чтобы задавать ассистенту новые вопросы и получать свежие справки по узлам, положите ключ в .env в корне репозитория до запуска: cp .env.example .env, затем OPENAI_API_KEY=sk-.... Docker и make подхватят его сами. Без ключа ассистент отвечает только на вопросы из кэша, а кнопка «Справка» показывает шаблон. Подробнее — раздел Опциональный AI-слой.

Соответствие ТЗ

ТребованиеГде проверить
Must have 1. Один запуск от parquet до трёх выгрузок, < 5 минdocker compose up --build или make demo; лог «готово за …ms»; out/nodes_roles.csv, out/clusters.csv, out/top_nodes.csv
Must have 2. 2 248 строк, роль из словаря, role_score, evidencemake check печатает распределение ролей и завершается с кодом 0
Must have 3. Критерии ролей формальны и объяснимыТаблица правил ниже и в методологии; в карточке узла метрики, сигналы и evidence с числами
Must have 4. Кластеры: размер, seed, оборот, гипотезаout/clusters.csv, вкладка «Кластеры» в интерфейсе, GET /v1/clusters
Must have 5. Топ ≥ 20 с обоснованием и экран с направлением потоковout/top_nodes.csv (30 строк), вкладка «Топ-30», поиск по gid, стрелки и подсветка входящих/исходящих
Явные ограничения данных учтеныОбрезанные обходом узлы не считаются стоками, seed не бывают транзитом и штрафуются в приоритете, см. раздел «Ловушки данных»
АртефактыРепозиторий, README (ru/kz/en), три CSV, схема решения, сценарий демо
ЗапретыНи одного захардкоженного gid в правилах; ни одного чёрного ящика; внешних атрибутов клиентов нет; облако и платные сервисы для воспроизведения не нужны
ОпциональноОбрыв обхода, временные паттерны, циклы и маршруты, дробление сумм, устойчивость сети, AI-ассистент, карточка узла, оценка полноты — см. методологию, разделы 6–9

Что реализовано

Аналитика (Go, детерминированно, < 1 с).

  • Загрузка трёх parquet и проверка: агрегированные рёбра сходятся с транзакциями по парам, числу и суммам.
  • Метрики узла: связи и суммы в обе стороны, доля транзита, PageRank (взвешенный, своя реализация), HITS, посредничество, seed напрямую и выше по цепочке, кластеры на входе, компонента, признаки по датам (быстрый транзит за 2 дня, синхронные плательщики, активные дни), возвратные циклы, устойчивые маршруты, дробление сумм.
  • Шесть ролей по правилам с порогами, role_score, кластеры Louvain, priority_score по перцентилям, evidence до 200 символов с числами.
  • Устойчивость сети: что произойдёт при изъятии топ-5/10/20.
  • Экспорт трёх CSV по схеме ТЗ и graph.json; валидатор выгрузок cmd/check.

Интерфейс (React + cytoscape.js, отдаётся Go-сервером).

  • Схема сети: направление стрелок, цвет = роль, размер = приоритет, seed ромбом, обрезанные узлы пунктиром; при выборе узла входящие красные, исходящие тёмные, поток анимирован бегущим пунктиром.
  • Поиск по полному gid или префиксу, фильтры по роли и кластеру, режимы «Топ-30» и «Вся сеть», тумблер «Исключить периферию» прямо на схеме.
  • Полоса выбранного узла: роль, получено, отправлено, удерживает, крупнейший перевод (кликабельный); наведение на «Получено» или «Отправлено» выводит это направление на передний план.
  • Карточка узла: evidence, бейджи, ближайший seed выше по цепочке, «Куда смотреть дальше» (три кандидата), сигналы по 19 метрикам относительно всей сети, входящие и исходящие с отдельной группой «Периферия».
  • Вкладки «Seed» (81 исходный участник и куда ушли деньги), «Топ-30», «Кластеры» с устойчивостью сети.
  • Маршрут просмотренных узлов с номерами на схеме, «Назад» и «Очистить», сохраняется между сессиями.
  • Уведомления, пустые состояния, скелетоны загрузки, тёмная тема по системной настройке.

AI-слой (опционально, OpenAI). Справка по узлу из четырёх блоков, гипотезы кластеров, ассистент с восемью инструментами по графу и контекстом выбранного узла и маршрута. Всё кэшируется в out/llm_cache.json (в репозитории), поэтому без ключа тексты воспроизводятся один в один.

Граф переводов и топ-30 кандидатов для проверки

Топ-30: кандидаты для проверки с ролями, приоритетами и обоснованиями.

Как работает решение

flowchart LR
    D[3 parquet] --> L[Загрузка и проверка]
    L --> M[Граф и метрики]
    M --> C[Кластеры и паттерны]
    C --> R[Роли, evidence, приоритет]
    R --> E[nodes_roles.csv · clusters.csv · top_nodes.csv · graph.json]
    R --> A[Результат в памяти]
    A --> API[Fiber API /v1]
    API --> UI[React + cytoscape]
    A --> S[Ассистент и гипотезы]
    S <--> K[llm_cache.json]
    S -. только с ключом .-> O[OpenAI Responses API]
  1. Пайплайн читает data/*.parquet, строит направленный взвешенный граф.
  2. Считает метрики, кластеры и паттерны; правила назначают роли, формула — приоритет; пишет CSV и graph.json.
  3. Веб-сервер выполняет тот же расчёт в памяти при старте и отдаёт API и интерфейс.
  4. Аналитик ищет gid или идёт по топ-листу, смотрит связи, обоснование, кандидатов и кластер.
  5. При наличии ключа получает справку и задаёт вопросы; без ключа — те же тексты из кэша.

Роли и приоритеты считает локальный алгоритм. LLM получает готовые факты и не назначает роли, кластеры или приоритеты. Два прогона пайплайна дают байт-в-байт одинаковые файлы.

Критерии ролей и пороги

Граф переводов и сигналы по метрикам выбранного узла

Метрики выбранного узла в сравнении со всей сетью помогают проверить обоснование его роли.

Для каждой роли считается скор 0–1 по правилу с порогом; роль узла — с наибольшим скором, role_score — этот скор. Если ни одно правило не набрало 0.5, узел — peripheral. Пороги выведены из распределений на данных.

РольСмыслУсловиеСкорКол-во
consolidatorсобирает от многих и удерживаетплательщиков ≥ 3min(1, in_deg/6) × (1 − min(1, pass_through)), +0.15 если платят ≥ 2 seed; у обрезанных обходом ×0.731
coordinatorсвязывает группы, кандидат в организаторывход ≥ 2, выход ≥ 2, betweenness ≥ P97, плательщики из ≥ 2 кластеров или ≥ 3 seed выше0.5 + 0.5·(0.5·btw/P99 + 0.25·кластеров/3 + 0.25·seed/5)43
distributorвеер на много получателейполучателей ≥ 5 и ≥ 2·плательщиковmin(1, out_deg/30), ×0.6 если плательщиков ≥ 316
transitпропускает деньги насквозьне seed, есть вход и выход, 0.7 ≤ pass_through ≤ 1.3`0.5 + 0.5·(1 −pass_through − 1
terminalденьги пришли и остались, подтвержденонет исходящих, узел ≤ 3-го колена (обход шёл дальше), плательщиков ≥ 2 или сумма ≥ 100 0000.5·min(1, in_kzt/500 000) + 0.5·min(1, in_deg/3)153
peripheralпризнаков роли нетиначе1 − max(остальных)1 900

Приоритет — взвешенная сумма перцентильных рангов по сети: 0.25·P(in_kzt) + 0.20·P(in_deg) + 0.15·P(seed выше) + 0.15·P(pagerank) + 0.10·P(betweenness) + 0.15·бонус роли (бонус: consolidator и coordinator 1.0, distributor 0.7, transit 0.5, terminal 0.4). Seed ×0.5 — они уже известны, цель — те, кто выше; обрезанные обходом ×0.7 — данные неполные.

Откуда взялись правила. Всё это наша разработка: стартовый код организаторов считал только степени, суммы, PageRank и pass_through, а ТЗ задавало словарь ролей и требование «формальное правило с порогом». Пороги выбраны по квантилям на данных: ≥ 3 плательщика и ≥ 5 получателей — верхние 5 % узлов, окно транзита 0.7–1.3 покрывает 72 узла с пропуском 0.8–1.2, порог посредничества — P97. Приоритет считается по перцентилям, а не по сырым значениям, чтобы одна сумма в 23 млн не задавила остальные факторы. Веса отражают порядок вопросов аналитика: куда стекаются деньги важнее, чем кто посредник. Устойчивость проверена: при любых сдвигах шести весов на ±0.05 (729 комбинаций) в топ-10 остаются не менее 7 узлов, в среднем 8.7, в топ-30 — не менее 26. Это эвристика без обучения: ground truth нет, поэтому качество проверяется объяснимостью каждого решения.

Evidence — фраза до 200 символов по шаблону роли, например: консолидация: получает от 8 плательщиков (из них seed: 2) 2.2 млн KZT, отдаёт дальше 24% (2 получ.); в возвратном цикле.

Ловушки данных и как они учтены

Особенность выгрузкиРешение
444 узла 4-го колена без исходящих — обход просто закончилсяфлаг truncated; они никогда не terminal, скор консолидатора ×0.7, приоритет ×0.7, пометка в evidence
1 091 узел 1–3 колена без исходящих — обход шёл дальше и ничего не нашёлфлаг verified_sink; только они могут быть terminal
У seed входящие занижены (граф собран от них)seed не могут быть transit; приоритет ×0.5
Порог 5 000 KZT, дробление ниже не виднопризнак structuring: ≥ 5 входящих и ≥ 60 % из них до 15 000 KZT (45 узлов)
16 компонент, 19 seed без рёберcomponent_id у всех; изолированным seed — свой cluster_id

Сценарий проверки для жюри

  1. Запустите docker compose up --build. В логе контейнера: распределение ролей и «готово за …ms», затем «http server started». make check внутри уже прошёл.
  2. Откройте http://localhost:8080. Стартовый вид — топ-30 с соседями. Слева сверху на схеме тумблер «Исключить периферию», справа легенда потоков.
  3. Введите 100000003115284100 и нажмите «Найти». Это консолидатор №1: 8 входящих (2 seed), 2 исходящих, получено 2 160 500 KZT, отправлено 517 000 KZT, удерживает 76 %. На схеме входящие стрелки красные, исходящие тёмные; в карточке — evidence, ближайший seed в 1 шаге, три кандидата «Куда смотреть дальше», сигналы по метрикам.
  4. Нажмите на контрагента в списке или на кандидата. Узел добавится в маршрут внизу схемы и получит номер на схеме. «Назад» возвращает к предыдущему.
  5. Откройте вкладку «Seed»: 81 исходный участник и куда ушли их деньги. Вкладка «Кластеры»: устойчивость (изъятие топ-20 отрезает 17 % оборота, компонент 16 → 75) и 88 кластеров с гипотезами.
  6. Сравните с out/nodes_roles.csv: gid, роль, evidence совпадают с интерфейсом. gid — 18-значные числа, в Excel открывать как текст.

Разбор пяти узлов «за минуту» и вопросы ассистенту: docs/demo.md.

Граф переводов, устойчивость сети и кластеры с гипотезами

Вкладка «Кластеры»: гипотезы групп и влияние изъятия топ-5/10/20 узлов на оборот и связность сети.

Проверка через API

curl -f http://localhost:8080/v1/health
curl -f 'http://localhost:8080/v1/top?n=3'
curl -f http://localhost:8080/v1/nodes/100000003115284100
curl -f 'http://localhost:8080/v1/nodes/100000003115284100/ego?depth=2'
curl -f http://localhost:8080/v1/seeds
curl -f http://localhost:8080/v1/robustness
curl -f http://localhost:8080/v1/assistant/status

Swagger: http://localhost:8080/swagger/index.html. Все gid в JSON — строки: значения ≈ 1e17 не помещаются в точный целочисленный диапазон JavaScript.

Автоматические проверки

make pipeline   # out/*.csv, graph.json
make check      # 2248 узлов, роли из словаря, скоры в [0,1], evidence ≤ 200, кластеры, топ ≥ 20
make test       # Go: детерминизм анализа, ограничения ролей, фильтры графа, HTTP-контракты, инструменты ассистента

Производительность

Замер на поставляемом наборе (2 248 узлов, 3 119 рёбер, 4 840 переводов), собранный бинарник, 5 прогонов подряд:

МетрикаРезультатТребование ТЗ
Полный пересчёт от parquet до трёх CSV и graph.json0,29–0,33 с< 5 минут
Пиковая память (RSS)~60 МБобычный ноутбук
Детерминизм5 прогонов дают байт-в-байт одинаковые файлывоспроизводимость

Повторить: go build -o bin/pipeline ./cmd/pipeline && /usr/bin/time -v bin/pipeline --data data --out out. Время сборки Go-бинарников и React-образа в Docker в замер не входит.

Данные и результаты

Поставляемый набор: 1–31 июля 2026, 2 248 клиентов, 3 119 рёбер, 4 840 переводов, 81 seed, оборот 365,9 млн KZT. Обход от seed по исходящим на 4 колена, только внутрибанковские переводы ≥ 5 000 KZT.

ФайлПоля
data/nodes.parquetgid, depth, is_seed
data/edges.parquetsrc, dst, sum_kzt, n_tx, depth
data/transactions.parquetsrc, dst, date, sum_kzt
РезультатСхема
out/nodes_roles.csvgid,role,role_score,cluster_id,priority_score,evidence + 20 колонок метрик
out/clusters.csvcluster_id,n_nodes,n_seed,sum_kzt_internal,top_gids,hypothesis + компонента, потоки через границу, циклы, состав ролей
out/top_nodes.csvrank,gid,role,priority_score,why — 30 строк
out/graph.jsonnodes, edges, clusters, top, robustness для интерфейса
out/llm_cache.jsonкэш ответов LLM; коммитится, чтобы результат воспроизводился без ключа

Итог на данных: 88 кластеров (8 с несколькими seed), топ-30 без единого seed, роли: 31 consolidator, 43 coordinator, 16 distributor, 105 transit, 153 terminal, 1 900 peripheral.

HTTP API

Метод и путьНазначение
GET /v1/healthдоступность сервера
GET /v1/graph?role=&cluster=&component=&top=30граф с фильтрами; top=N — топ-N и их соседи, top=0 — вся сеть
GET /v1/nodes/{gid}карточка: метрики, перцентили, контрагенты, ближайший seed, кандидаты
GET /v1/nodes/{gid}/ego?depth=1окружение в обе стороны, глубина 1–2
GET /v1/top?n=30топ приоритетов
GET /v1/clustersкластеры с гипотезами
GET /v1/seedsисходные участники и их крупнейшие получатели
GET /v1/robustnessустойчивость при изъятии топ-5/10/20
GET /v1/search?q=1000&limit=10поиск gid по префиксу
GET /v1/assistant/statusдоступен ли LLM и какая модель
GET /v1/nodes/{gid}/cardтекстовая справка по узлу (by_llm: false — шаблон)
POST /v1/assistant{"question": "...", "gid": "...", "route": ["..."]} → {answer, gids[]}; 503 без ключа
GET /graph.jsonпоследняя выгрузка, резервный источник интерфейса

Опциональный AI-слой

Ответ AI-ассистента на вопрос о выбранном узле и подсветка упомянутых узлов на графе

Ассистент отвечает на вопрос о движении денег по данным графа; упомянутые в ответе узлы подсвечиваются на схеме.

Единственная внешняя интеграция — OpenAI Responses API, модель по умолчанию gpt-5.1. Ключ задаётся переменной OPENAI_API_KEY в окружении или в файле .env в корне репозитория (шаблон — .env.example, make env создаёт его). Для Docker достаточно того же .env рядом с docker-compose.yaml: compose подставит ключ в контейнер при docker compose up. При запросах во внешний API уходят только обезличенные факты о графе и gid.

cp .env.example .env            # затем впишите OPENAI_API_KEY=sk-...
docker compose up --build       # или make demo — ключ подхватится автоматически

Без ключа работает всё, кроме новых вопросов ассистенту: роли, приоритеты, интерфейс, справки и гипотезы из кэша или по шаблону. Интерфейс сам скрывает недоступные AI-элементы по ответу 503.

go run ./cmd/pipeline --data data --out out --llm    # дозапросить гипотезы кластеров, которых нет в кэше
go run ./cmd/ask --card 100000003115284100           # справка по узлу
go run ./cmd/ask --q 'Кто собирает деньги с seed 100000000343175100 и 100000003684369100?'

LLM ничего не решает про роли: промпт требует ссылаться только на gid, формулировать гипотезы и не приписывать клиентам атрибуты, которых нет в данных.

Технологии

КомпонентРеализация
Бэкенд и CLIGo 1.25, Fiber v2, Uber FX, Viper, zap, validator
Данные и графыparquet-go, gonum (HITS, betweenness, Louvain), свой детерминированный PageRank
ФронтендReact 19, Vite 7, cytoscape.js 3.30, CSS на токенах дизайн-системы, без CDN
API-документацияswag, Swagger UI
AIOpenAI Responses API, файловый кэш
ЗапускDocker (один образ: React собирается внутри), Make
Хранениеparquet, CSV, JSON; результат анализа в памяти, без БД
КаталогНазначение
cmd/pipeline, cmd/check, cmd/web, cmd/askпайплайн, валидатор, сервер, CLI ассистента
internal/data/models, internal/data/graph, internal/repo/datasetмодели, граф и индекс, чтение parquet
internal/services/analysisметрики, роли, кластеры, приоритет, паттерны
internal/services/{pipeline,export,graph,hypotheses,assistant}оркестрация, выгрузки, доступ для API, LLM-сценарии
internal/transport/http, internal/data/dtoхендлеры и JSON-контракты
pkg/llm, pkg/httperrклиент OpenAI с кэшем, формат ошибок
frontendReact-интерфейс (frontend/src)
webвстроенный резервный просмотрщик
docsметодология, сценарий демо, схема, swagger
testsblack-box тесты анализа на реальных данных

Настройки

Несекретное — config/config.yaml, любой ключ переопределяется переменной окружения.

ПеременнаяПо умолчанию
APP_PORT8080
APP_DATA_DIR / APP_OUT_DIRdata / out
APP_DEBUGfalse; true — цветные dev-логи и стектрейсы паник
OPENAI_API_KEYпусто — LLM выключен
LLM_MODEL / LLM_BASE_URLgpt-5.1 / https://api.openai.com/v1

Если порт 8080 занят: APP_PORT=8081 make demo или замените "8080:8080" на "8081:8080" в docker-compose.yaml. Для разработки интерфейса: make web в одном терминале и cd frontend && npm ci && npm run dev в другом (http://localhost:5173, прокси к API на 8080).

Ограничения

  • Видна только выгрузка: без входящих seed извне, без переводов < 5 000 KZT, без потоков за 4-м коленом и вне банка. Отсутствие исходящих у узла 4-го колена не означает, что деньги остались.
  • Роли — правила с порогами, не разметка. Ground truth нет, поэтому качество проверяется объяснимостью, а не accuracy; role_score — уверенность правила, не вероятность вины.
  • Кластеризация на неориентированной проекции; направление учтено в ролях, а не в группировке.
  • Детекция аномалий ограничена правилом дробления сумм.
  • Тексты LLM могут ошибаться и должны проверяться по фактам; без ключа новые вопросы недоступны.
  • Авторизации нет: конфигурация для локальной демонстрации.

Каких данных не хватает и какие запросы закрывают белые пятна — методология, раздел 9.

Масштабирование до ~1 млн узлов

Что изменится в подходе (реализация не требуется ТЗ):

  • Хранение. Parquet в памяти заменяется колоночным хранилищем или графовой БД (Neo4j GDS, TigerGraph) либо Spark GraphFrames; 1 млн узлов и ~5 млн рёбер ещё помещаются в память Go, но пересчёт перестаёт быть секундами.
  • Метрики. Степени, суммы и PageRank линейны. Betweenness O(V·E) заменяется аппроксимацией по сэмплу источников (Brandes–Pich) или локальным k-hop вариантом; циклы — длиной 3–4 и только вокруг кандидатов из топа.
  • Кластеры. Louvain → Leiden, расчёт по компонентам параллельно.
  • Инкрементальность. Новые выгрузки пересчитывают только затронутые компоненты; метрики хранятся с версиями, детерминизм сохраняется фиксированным порядком обхода.
  • Интерфейс. Полный граф не рисуется: ego-подграфы и агрегаты по кластерам, серверная раскладка, индекс по gid.
  • LLM. Те же инструменты ассистента поверх БД; кэш ответов с TTL.

Материалы

Публичный адрес развёрнутой версии не предоставляется; способ демонстрации — локальный запуск.

Звёзды
⭐ 0
Форки
0
Язык
Go
Последний push
в прошлом месяце
Коммиты
36
Авторы
4
Файлы
140
Ветки
2

Авторы коммитов

NelttjeN 21Damir 13CryptoGu1 1Artemy 1

История коммитов

  • 2026-09-23 17:43Merge remote-tracking branch 'origin/main'Damir
  • 2026-09-23 17:42docs: add assistant screenshot to all README translationsDamir
  • 2026-09-23 17:28Merge remote-tracking branch 'origin/main'Damir
  • 2026-09-23 17:26Updated Readmi md with screensDamir
  • 2026-09-23 16:50docs: fix Mermaid edge labels in all READMEsDamir
  • 2026-09-23 16:45docs: update Kazakh READMEDamir
  • 2026-09-23 16:16docs: add project README in Russian, Kazakh and EnglishDamir
  • 2026-09-23 17:47Merge remote-tracking branch 'origin/main'NelttjeN
Все коммиты (36)
  • 2026-09-23 17:46remove unnecesary config logicNelttjeN
  • 2026-09-23 17:39Merge remote-tracking branch 'origin/main'NelttjeN
  • 2026-09-23 17:38back improvement + readme updateNelttjeN
  • 2026-09-23 17:21updated rulesNelttjeN
  • 2026-09-23 15:16fix(build): ignore inherited Windows GOROOT in make targetsDamir
  • 2026-09-23 17:15readme updateNelttjeN
  • 2026-09-23 15:11fix(build): detect Windows npm in WSL before installing dependenciesDamir
  • 2026-09-23 15:06build: add React compose service and document demo readinessDamir
  • 2026-09-23 15:05feat(frontend): add React graph explorer with API proxyDamir
  • 2026-09-23 15:05feat(api): serve graph analysis and offline viewerDamir
  • 2026-09-23 15:03feat(check): validate analysis CSV exportsDamir
  • 2026-09-23 17:00Merge remote-tracking branch 'origin/main'NelttjeN
  • 2026-09-23 16:59final front refinementNelttjeN
  • 2026-09-23 16:49Merge remote-tracking branch 'origin/main'NelttjeN
  • 2026-09-23 16:49graph refinementNelttjeN
  • 2026-09-23 16:39front improvements 2NelttjeN
  • 2026-09-23 16:39Merge remote-tracking branch 'origin/main'NelttjeN
  • 2026-09-23 16:38front improvementsNelttjeN
  • 2026-09-23 15:34frontend & build docker - #2CryptoGu1
  • 2026-09-23 15:30Merge remote-tracking branch 'origin/feat/web' into feat/webNelttjeN
  • 2026-09-23 15:30merge conflictsNelttjeN
  • 2026-09-23 15:14scheme v1NelttjeN
  • 2026-09-23 14:47big atrchitectore improvementsNelttjeN
  • 2026-09-23 14:18small improvements of archNelttjeN
  • 2026-09-23 14:12analysys (#1)Artemy
  • 2026-09-23 13:41foundation: без Postgres, loader parquet, граф, контракт analysis.Result, экспорт CSV/JSON, cmd/pipelineNelttjeN
  • 2026-09-23 13:33initial plansNelttjeN
  • 2026-09-23 13:20Initial commit: каркас API на базе morafest-backendNelttjeN
Структура репозитория (140 файлов)
.agent/artem.md
.agent/artem_ready.md
.agent/damir.md
.agent/damir_ready.md
.agent/plan.md
.agent/team.md
.dockerignore
.env.example
.gitignore
CLAUDE.md
Dockerfile
Makefile
README.en.md
README.kz.md
README.md
cmd/ask/main.go
cmd/check/main.go
cmd/check/main_test.go
cmd/pipeline/main.go
cmd/web/entrypoint.sh
cmd/web/main.go
config/config.yaml
data/edges.parquet
data/nodes.parquet
data/transactions.parquet
docker-compose.yaml
docs/assistent.jpg
docs/clusters.jpg
docs/demo.md
docs/docs.go
docs/main_front.png
docs/methodology.md
docs/metrics.jpg
docs/scheme.png
docs/scheme.svg
docs/swagger.json
docs/swagger.yaml
docs/top_30.jpg
frontend/README.md
frontend/index.html
frontend/package-lock.json
frontend/package.json
frontend/scripts/check-env.sh
frontend/src/App.jsx
frontend/src/api.js
frontend/src/components/Assistant.jsx
frontend/src/components/GraphCanvas.jsx
frontend/src/components/NodeTab.jsx
frontend/src/components/RouteBar.jsx
frontend/src/components/SelectedStrip.jsx
frontend/src/components/SidePanel.jsx
frontend/src/components/Toolbar.jsx
frontend/src/graph.js
frontend/src/graph.test.js
frontend/src/hooks/useRoute.js
frontend/src/lib/amlLogic.js
frontend/src/lib/graphStyle.js
frontend/src/main.jsx
frontend/src/mock.json
frontend/src/styles.css
frontend/src/styles/design-system.css
frontend/src/styles/tokens.css
frontend/vite.config.js
go.mod
go.sum
internal/app/base.go
internal/app/handlers.go
internal/app/internal.go
internal/app/server.go
internal/config/app.go
internal/config/config.go
internal/config/llm.go
internal/data/dto/assistant/requests.go
internal/data/dto/assistant/responses.go
internal/data/dto/base.go
internal/data/dto/graph/responses.go
internal/data/dto/graph/subgraph.go
internal/data/graph/graph.go
internal/data/graph/index.go
internal/data/models/analysis.go
internal/data/models/dataset.go
internal/data/models/patterns.go
internal/data/models/roles.go
internal/repo/dataset/convert.go
internal/repo/dataset/loader.go
internal/repo/dataset/validate.go
internal/services/analysis/clusters.go
internal/services/analysis/format.go
internal/services/analysis/metrics.go
internal/services/analysis/pagerank.go
internal/services/analysis/patterns.go
internal/services/analysis/priority.go
internal/services/analysis/roles.go
internal/services/analysis/service.go
internal/services/assistant/ask.go
internal/services/assistant/card.go
internal/services/assistant/errors.go
internal/services/assistant/prompts.go
internal/services/assistant/queries.go
internal/services/assistant/service.go
internal/services/assistant/tools.go
internal/services/assistant/tools_test.go
internal/services/assistant/types.go
internal/services/export/csv.go
internal/services/export/json.go
internal/services/export/service.go
internal/services/fx.go
internal/services/graph/errors.go
internal/services/graph/insights.go
internal/services/graph/service.go
internal/services/graph/service_test.go
internal/services/graph/types.go
internal/services/hypotheses/prompts.go
internal/services/hypotheses/service.go
internal/services/pipeline/service.go
internal/transport/http/middleware/logger.go
internal/transport/http/mixins/request.go
internal/transport/http/v1/assistant/core.go
internal/transport/http/v1/assistant/handlers.go
internal/transport/http/v1/graph/core.go
internal/transport/http/v1/graph/handler_test.go
internal/transport/http/v1/graph/handlers.go
internal/transport/http/v1/health/handler.go
internal/transport/http/v1/router.go
out/clusters.csv
out/graph.json
out/llm_cache.json
out/nodes_roles.csv
out/top_nodes.csv
pkg/httperr/httperr.go
pkg/llm/cache.go
pkg/llm/client.go
pkg/llm/errors.go
pkg/llm/models.go
tests/unit/analysis/analysis_test.go
web/app.js
web/embed.go
web/index.html
web/mock/graph.js
web/mock/graph.json
Ветки (2)

Обсуждение 0 комментариев

Войдите, чтобы комментировать

Пока нет комментариев — будьте первым.