02. Карта модулей src/*¶
Краткая карта всех подкаталогов src/ Payment Manager, их ответственности и зависимостей между собой. Используется как точка входа в детальные документы по каждому модулю (../modules/*.md).
Назначение¶
src/ Payment Manager состоит из 14 подкаталогов плюс двух корневых файлов
(server.ts — точка сборки Fastify; migrate.ts — CLI для миграций Drizzle).
Каждый подкаталог отвечает за один аспект платёжной обработки и имеет
ограниченный набор зависимостей: верхние слои (HTTP, оркестрация) опираются
на нижние (ledger, shared), но не наоборот.
Этот документ описывает топологию: какие модули используют какие. Все
детали (DTO, ключи Redis, формат событий) — в соответствующих
../modules/*.md.
Диаграмма зависимостей¶
flowchart TD
server[server.ts<br/>Fastify wiring]
subgraph HTTP[HTTP layer]
admin[admin/]
auth[auth/]
policies[policies/]
intent_http[intent/<br/>handler · quote · confirm · cancel]
end
subgraph Orchestration[Оркестрация]
intent_core[intent/<br/>router · step-registry · operation-registry]
channels[channels/]
optypes[operation-types/]
end
subgraph Domain[Доменные сервисы]
ledger[ledger/]
limits[limits/]
accounts[accounts/]
rule[rule-engine/]
psp[psp/]
end
subgraph Async[Асинхронная обработка]
workers[workers/]
jobs[jobs/]
end
shared[shared/<br/>db · redis · schema · errors · logger]
server --> HTTP
server --> workers
intent_http --> intent_core
intent_http --> auth
intent_core --> channels
intent_core --> optypes
channels --> ledger
channels --> psp
optypes --> ledger
optypes --> limits
optypes --> rule
optypes --> accounts
policies --> shared
admin --> shared
auth --> shared
workers --> ledger
workers --> psp
workers --> jobs
jobs --> shared
HTTP --> shared
Orchestration --> shared
Domain --> shared
Async --> shared
Стрелка A --> B читается как «A импортирует из B». Все модули в конечном
счёте упираются в shared/ (БД, Redis, схема, ошибки, конфиг, логгер).
Таблица модулей¶
| Каталог | Ответственность | Документ |
|---|---|---|
accounts/ |
Резолверы TigerBeetle-аккаунтов по имени/роли; обёртки над pm.tb_account_map. |
../modules/ledger.md |
admin/ |
HTTP-роуты для административных операций: health, debug-level, fee-rules. | ../api/admin.md |
auth/ |
HMAC-плагин Fastify (X-Service-Id / X-Timestamp / X-Signature), проверка service_key. |
TODO: ../modules/auth.md |
channels/ |
Реализации каналов исполнения: INTERNAL_P2P, IPPS_TRANSFER, MERCHANT_INVOICE, SERVICE_TRANSFER, ADMIN и т.д. Каждый канал — это объект TwoPhaseChannel со steps reserve/commit/cancel/expire. |
TODO: ../modules/channels.md |
intent/ |
Точка входа платежей. HTTP-обработчики (handler.ts, quote.ts, confirm-handler.ts, cancel-handler.ts), резолвер канала (router.ts), реестры (step-registry.ts, operation-registry.ts), запись событий, публикация статусов. |
TODO: ../modules/intent.md |
jobs/ |
Описание фоновых job-ов (типы, payload-ы, статусы) для воркеров. | ../modules/workers.md |
ledger/ |
Единственная точка доступа к TigerBeetle: createAccounts, createTransfers, lookupAccounts. HTTP-роуты /accounts/*. |
TODO: ../modules/ledger.md |
limits/ |
Расчёт и проверка лимитов (per-tx, daily, monthly). check-limits.ts, evaluate-policy.ts. |
TODO: ../modules/limits.md |
operation-types/ |
Каталог operationType (P2P_TRANSFER, IPPS_WITHDRAWAL, THAI_QR_PAY, MERCHANT_PAYMENT, INVOICE_PAYMENT, SERVICE_DEPOSIT, ADMIN_TRANSFER и т.д.). Каждый тип задаёт: какой канал использует, какие fee-rule-ы, какие limit-ы. |
TODO: ../modules/operation-types.md |
policies/ |
HTTP-роуты для step-up auth policies (см. docs/AUTH-POLICIES.md). | TODO: ../modules/policies.md |
psp/ |
Интеграция с PSP-провайдерами (IPPS-драйвер, очередь psp_tx_map). Phase 1 — in-process worker. |
TODO: ../modules/psp.md |
rule-engine/ |
Калькулятор комиссий по правилам из pm.fee_rule: fee-calculator.ts, контекст и сплиты. |
TODO: ../modules/rule-engine.md |
shared/ |
Общая инфраструктура: db.ts (Drizzle), redis.ts, schema.ts, errors.ts, logger.ts, config.ts, утилиты подписей. |
TODO: ../modules/shared.md |
workers/ |
Фоновые воркеры (OutboxWorker, expiry, psp-worker). Запускаются ролью процесса в server.ts. |
TODO: ../modules/workers.md |
Корневые файлы:
src/server.ts— собирает Fastify, регистрирует плагины (hmac, swagger, helmet, cors), монтирует роуты изadmin/,auth/,ledger/,intent/,policies/. Стартует воркеры по роли (api/worker/psp-worker).src/migrate.ts— CLI-точка дляdrizzle-kit migrate. Не часть рантайма.
Особенности именования (ловушки)¶
В кодовой базе несколько мест, где имена пересекаются с близкими, но не идентичными понятиями. Эти ловушки чаще всего ловят новых разработчиков и при review/grep-навигации.
-
src/intent/router.ts— этоresolveChannel(), а НЕ HTTP-routes. Файл экспортирует чистую функцию, которая поoperationTypeи контексту возвращает имя канала (INTERNAL_P2P,IPPS_TRANSFER, …). HTTP-роуты/intents,/intents/quote,/intents/:id/confirm,/intents/:id/cancelрегистрируются отдельными файлами:src/intent/handler.ts,src/intent/quote.ts,src/intent/confirm-handler.ts,src/intent/cancel-handler.ts. Не путать с Fastify-роутером. -
Канал
ADMIN≠ operationTypeADMIN_TRANSFER.channels/admin*.ts(если/когда появится) реализует механику административных переводов;operation-types/admin-transfer.ts— конкретный operationType, который использует этот канал, но имеет собственные лимиты и проверки. В аналитике и логах оба значения попадают в разные поля (channelvsoperation_type). -
Канал
SERVICE_TRANSFER≠ operationTypeSERVICE_DEPOSIT. КаналSERVICE_TRANSFER— это механика перевода между service- и user-аккаунтами.SERVICE_DEPOSIT— это operationType «зачисление от сервиса пользователю», который выполняется через каналSERVICE_TRANSFER. Один канал может обслуживать несколько operationType. -
Канал
IPPS_TRANSFER≠ operationTypesIPPS_WITHDRAWAL/THAI_QR_PAY.IPPS_TRANSFER— единый канал интеграции с IPPS PSP. На него маршрутизируются разные operationType: вывод средств (IPPS_WITHDRAWAL) и оплата по QR (THAI_QR_PAY). Они отличаются по комиссиям, лимитам и способу заполнения PSP-payload-а, но используют одну и ту же reserve/commit/cancel-механику в канале. -
operation-registryvsstep-registryвsrc/intent/.operation-registry.ts— реестр operationType (что разрешено, какие политики применяются).step-registry.ts— реестр каналов и проверкаisTwoPhase(). Это разные реестры с разной семантикой; легко перепутать при grep. -
accounts/vsledger/accounts.ts.src/accounts/— высокоуровневые резолверы (по userId, по роли, по merchantId).src/ledger/accounts.ts— низкоуровневые обёртки над TigerBeetle SDK (getAccountByName,getAccountByTbId). Обращайтесь кaccounts/; вledger/лазьте только если нужен прямой TB-lookup. -
shared/schema.ts— это Drizzle-схемаpm.*, НЕ Zod-схемы. Zod-схемы DTO лежат рядом с роутами (например,src/intent/operation-type.tsэкспортируетBaseIntentBody). Не путать с типами Drizzle-таблиц.
Детализация по слоям¶
HTTP-слой (точка входа всех внешних вызовов)¶
Все внешние клиенты (Auth Center, nginx-proxy для Flutter, admin panel, mini-app backends) попадают в PM через Fastify-роуты. Маршрутизация по файлам:
intent/handler.ts—POST /intents(создание платёжного intent, главный endpoint).intent/quote.ts—POST /intents/quote(расчёт комиссии без фиксации).intent/confirm-handler.ts—POST /intents/:id/confirm(commit для двухфазных каналов).intent/cancel-handler.ts—POST /intents/:id/cancel(откат reserved-intent-а).ledger/routes.ts—GET /accounts/balance,GET /accounts/historyи другие read-only-обёртки над TB.admin/health.ts—GET /health,GET /ready.admin/debug-level.ts— управление log-level на лету.admin/fee-rules.ts— CRUD надpm.fee_rule.policies/routes.ts— CRUD надpm.auth_policy.
Все эти роуты проходят через auth/hmacPlugin.ts — глобальный
preHandler, который валидирует подпись и кладёт serviceId в
request.requestContext. Исключения — health-endpoint-ы.
Оркестрация (intent → channel → operation-type)¶
При входящем POST /intents поток такой:
handler.tsпарсит DTO (BaseIntentBody+ специфичный для operationType discriminator).operation-registry.tsподтверждает, что operationType разрешён для данногоserviceId.router.ts(resolveChannel) поoperationTypeи контексту выбирает канал.step-registry.tsотдаёт реализацию канала (объектTwoPhaseChannel).- Канал из
channels/исполняетreserve()(pending TB-transfer), при необходимости публикует job вpsp/или Redis. intent-events.tsзаписывает событие вpm.intent_eventи публикует в Redis (intent.{id}).
Доменный слой (без HTTP, чистая логика)¶
ledger/— единственная обёртка над TigerBeetle SDK. Никакой другой каталог не должен импортироватьtigerbeetle-nodeнапрямую.accounts/— резолверы «по смыслу» (userId, merchantId, роль), трансляция в TB account_id черезpm.tb_account_map.limits/— реализация per-tx / daily / monthly лимитов. Читаетpm.limit_policy, считает текущее окно поpm.intent.rule-engine/— fee-калькулятор. ПринимаетRuleContext, возвращаетResolvedFeeSplit(кому сколько и куда).psp/— драйверы PSP. В Phase 1 — IPPS in-process worker черезpsp_tx_map. В Phase 2B будет вынесен в отдельный сервис через Redis Streams.
Асинхронный слой¶
workers/— long-running процессы:- OutboxWorker — публикует pending-события из
pm.outbox. - ExpiryWorker — отменяет просроченные reserved-intent-ы.
- PspWorker — Phase 1 IPPS-исполнитель (polling
psp_tx_mapчерезFOR UPDATE SKIP LOCKED). jobs/— типы job-ов (payload-схемы, статусы).workers/опирается на эти типы.
Запуск воркеров определяется переменной окружения / argv role:
server.ts стартует либо HTTP-сервер (api), либо воркеры
(worker / psp-worker).
Связь с другими документами¶
- 01. Архитектурный обзор — high-level картина сервиса.
- 03. Поток платежа (sequence) — как модули взаимодействуют во времени.
- 01. Архитектурный обзор — high-level картина сервиса (входы/выходы, ledger, sagas).
- docs/AUTH-POLICIES.md — детали step-up auth
policies, реализуемых в
policies/. - PASSPORT.md — канонический контракт PM (DTO, enum-ы каналов и operationType).