sdlc-hub/ARCHITECTURE.md
Andrey Epifancev 34c57ceeab Merge remote-tracking branch 'origin/main' into feat/21-web-app
# Conflicts:
#	ARCHITECTURE.md
#	CLAUDE.md
#	src/jira_hub/api.py
#	tests/test_api.py
2026-10-15 00:07:48 +04:00

6.6 KiB
Raw Permalink Blame History

Архитектура

Хаб моста Jira: SQLite-зеркало задач AURORA/AWPCA, служебные заметки, очередь команд, HTTP API и MCP. Агент (jira-agent, виртуалка) опрашивает хаб, пишет в Jira и возвращает состояние; хаб Jira не вызывает.

Модули

Модуль Ответственность Зависит от
paths каталог данных (JIRA_HUB_HOME), пути базы и backups/, права 0700 (secure_dir) stdlib
db схема SQLite, миграции по schema_version (копия базы перед миграцией), connect backup, paths
settings настройки (setting), токены, темп, перенос из config.example.json db
mirror зеркало задач и связей, apply_state, заметки, фильтры, снимок доски board db
commands контракт типов команд, валидация, временные ключи, оценка, подтверждение по состоянию mirror
queue пакеты, выдача (claim), отчёты, отмена, повтор, автообновление commands, mirror, settings, db
backup копии файла базы, ротация paths
api HTTP-сервер, маршруты, авторизация по токенам, фоновый tick; раздача веб-приложения /app… (каталог web/app пакета, без токена) и перенаправление /, /links; снимок GET /board queue, mirror, settings, backup, relay, release
relay реле общей папки (настройка relay_dir): поток в serve, файлы req/ → свой HTTP (адрес serve, для 0.0.0.0 — 127.0.0.1) → resp/; агент с hub_url = folder:<путь> ходит через него; HTTP-обработчики о нём не знают settings
release опубликованная версия агента: release/agent.py + manifest.json в каталоге данных, publish (только вверх), current, load (с проверкой sha256), подсказка hint для agent_status paths
client HTTP-клиент хаба db, paths, settings (только для from_home)
mcp_server инструменты MCP по stdio client
importer разовый импорт CSV-пакета в заметки, сверка с зеркалом mirror, settings
cli init, serve, import, mcp, tokens, agent publish api, mcp_server, importer, release, settings, db, paths

web/ — веб-приложение хаба (React + TypeScript + Vite): вход по клиентскому токену, страницы «Доска» (/app/board) и «Задачи» (/app/issues, /app/issues/{key}). Собирается make web в src/jira_hub/web/app/; api отдаёт сборку без токена (/app/assets/* — файлы, прочие /app… — index.html, 503 без сборки), / и /links перенаправляет на /app/board. Данные — только через HTTP API с клиентским токеном; mirror.board отдаёт зеркало без преобразований, перевод в модель доски — в web/src/board/model. Логика доски — чистые модули web/src/board/{model,analysis,layout} и storage.ts (ключи localStorage прежней страницы), отрисовка — web/src/board/components.

Цепочки: api → queue → commands/mirror/settings → db; db → backup → paths, db → paths; api → relay → settings; mcp_server → client → HTTP API; importer → mirror/settings.

Потоки данных

  • Запись в Jira: клиент (mcp_server/интерфейс) → POST /batches → queue → агент claim → Jira → POST /agent/commands/{id}/result.
  • Чтение Jira: команда refresh → агент → POST /agent/state → mirror.apply_state.
  • Агент за VPN: агент → файлы в общей папке (relay_dir) → relay → HTTP хаба → ответ файлом.
  • Самообновление агента: jira-hub agent publish → release/ → claim.agent_release → агент скачивает GET /agent/release; состояние обновления агент шлёт в claim, хаб держит в памяти и отдаёт в GET /agent.
  • Токены: агентский — только /agent/*, клиентский — остальное; MCP берёт клиентский токен из базы через HubClient.from_home.

Границы

  • Зеркало пишет только mirror.apply_state по запросу агента (и заметки через PUT /issues/{key}/note); из очереди и API задач напрямую не правят.
  • Хаб не знает пароль Jira и не обращается к Jira; init не переносит auth, base_url, verify_ssl, ca_bundle.
  • queue не создаёт команд сам: повтор после failed — новый пакет. Выданная без отчёта команда довыдаётся при следующем claim (до 3 выдач, затем failed).
  • mcp_server не импортирует queue/mirror/db напрямую и ходит только через client.
  • commands, mirror, queue не знают про HTTP; HTTP живёт только в api, client и relay (реле — клиент своего же HTTP).
  • Веб-приложение (web/) ходит в хаб только через HTTP API (web/src/api/client.ts); словари kind_labels, link_types, status_labels берёт из GET /settings и своих копий не держит.

Открытые вопросы

  • Правки из UI в Jira (спринт, срок, связи, исполнитель) — change viewer-edit; страницы очереди, агента и настроек — позже.
  • Автоподстройка темпа по фактам 429 не реализована: хаб только показывает их.
  • Незакрытые SQLite-соединения и сокеты в ряде тестов (ResourceWarning при -W error::ResourceWarning).