Тема
10.02 Application Architecture Decisions
Статус: черновик для обсуждения
1. Назначение документа
Этот документ фиксирует application architecture decisions для MVP поверх network/runtime diagram.
Network diagram показывает infrastructure и runtime placement.
Application architecture должна объяснить:
- как назвать project/repository/services;
- какие deployable services существуют;
- где живет business logic;
- что делают gateways;
- что обрабатывается synchronously;
- что обрабатывается asynchronously;
- какие технические concepts нужно дополнительно проработать development team.
2. Naming recommendation
Не стоит называть весь project/repository Payment Service.
Причина:
- в monorepo будет не только core payment processing;
- там будут UI;
- Back Office backend;
- Forms Service;
- gateways;
- Exchange Service;
- Report Service;
- shared libraries;
- infrastructure manifests;
- CI/CD configuration.
Рекомендуемая naming model:
text
Project / Product: Payment Orchestrator / HUB v3
Repository: payment-orchestrator
Core business service: Orchestrator ServicePayment Service можно оставить как label на существующей network diagram, но для application architecture нужно использовать более точное название:
text
Orchestrator ServiceProduct decision: использовать Orchestrator Service, потому что core service отвечает не только за payment record, но и за routing, provider execution, callbacks, webhooks, fees, velocity, timeline and audit.
3. Monorepo structure
MVP должен быть в monorepo для удобства development, shared contracts, tests and deployment manifests.
Пример logical monorepo structure:
text
payment-orchestrator/
apps/
backoffice-ui/
backoffice-service/
forms-service/
merchant-gateway/
provider-gateway/
orchestrator-service/
exchange-service/
report-service/
packages/
api-contracts/
domain-shared/
provider-adapters/
ui-shared/
observability/
infra/
k8s/
manifests/
terraform/
docs/Exact folder names должны определить development team.
Product requirement:
- monorepo;
- minimal number of deployable services;
- shared API contracts;
- shared tests;
- shared provider adapter contract;
- infrastructure manifests in same project/repository.
4. Deployable services in MVP
MVP target deployable services:
- Backoffice Service / Backoffice API;
- Backoffice UI, если UI деплоится отдельно;
- Forms Service;
- Merchant Gateway;
- Provider Gateway;
- Orchestrator Service;
- Exchange Service;
- Report Service.
Exchange Service и Report Service являются отдельными services, но остаются частью одного project/monorepo.
Auth service отдельно выделять не нужно.
Auth/session/users/roles/permissions должны быть частью Backoffice/Orchestrator architecture boundary.
Причина:
- цель MVP - минимизировать количество services;
- отдельный Auth service добавит operational complexity;
- Back Office permissions tightly coupled with product domain access model.
5. Orchestrator Service
Orchestrator Service является core deployable service.
Он должен быть one deployable modular monolith with DDD modules.
Core business logic должна находиться здесь.
Внутри Orchestrator Service должны быть modules:
- Merchant / Brand;
- Payment Method / MID;
- Routing;
- MASTER MID / MASTER MID GROUP;
- SUB MID / SUB MID GROUP / SUB MID AGGREGATOR;
- Velocity;
- FX / Fees;
- Transaction Lifecycle;
- Provider Integration;
- Provider Callback Processing;
- Merchant Webhooks;
- Error Mapping;
- Audit Log;
- Timeline;
- Permissions/Visibility, если это реализуется в core domain/application layer.
Feature implementation должна идти через module boundaries, а не через создание нового microservice для каждой feature.
6. Backoffice Service
Backoffice Gateway / Backoffice Service содержит не только gateway routing logic.
В MVP Backoffice Service может содержать Back Office backend logic:
- authentication/session handling;
- user/profile operations;
- Back Office API endpoints;
- UI-specific read models;
- form data endpoints;
- permission checks for Back Office actions;
- orchestration of configuration commands;
- transaction details views.
Но critical domain decisions должны выполняться через Orchestrator Service/domain layer.
Backoffice Service не должен самостоятельно реализовывать alternative routing/fees/velocity logic.
7. Merchant Gateway
Merchant Gateway является public merchant API entry point.
Для create deposit flow Merchant Gateway должен:
- принять
POST /api/v2/deposit; - проверить authentication/signature;
- проверить basic required request fields;
- проверить duplicate merchant
transactionId, если это делается на gateway boundary; - создать payment session token;
- создать hosted payment URL;
- durably persist accepted request/session or publish it to durable queue;
- вернуть merchant response with
transactionId,merchantTransactionId,status,hostedPaymentUrl.
Важно:
- Merchant Gateway возвращает hosted payment URL immediately after accepted request/session is safely stored;
- routing/provider execution выполняется asynchronously;
- Merchant Gateway не должен выполнять full routing, velocity, FX/fee or provider execution logic;
- если request/session нельзя сохранить durably или поставить в durable queue, gateway не должен возвращать success response.
Это позволяет customer открыть hosted payment form, пока processing продолжается event-driven.
8. Provider Gateway
Provider Gateway является public provider callback entry point.
Для provider callback flow Provider Gateway должен:
- принять callback на opaque callback endpoint;
- не раскрывать real provider name в public URL;
- быстро выполнить минимальную technical validation, если она нужна для безопасного приема;
- положить callback в durable queue;
- ответить provider
OKтолько после successful durable queue publish.
Callback processing, including business validation, выполняется asynchronously.
Provider Gateway не должен синхронно выполнять:
- full signature validation, если она требует access to core data;
- transaction matching;
- amount/currency matching;
- status transition;
- duplicate callback decision;
- merchant webhook sending.
Если queue недоступна и callback невозможно надежно сохранить:
- gateway не должен silently return success;
- exact fallback behavior должна определить development team;
- предпочтительно вернуть non-2xx, чтобы provider retry mechanism мог повторить callback, если provider это поддерживает.
9. Exchange Service
Exchange Service остается отдельным service внутри project/monorepo.
Он отвечает за:
- exchange rates retrieval;
- rates storage/cache;
- conversion support;
- EUR base calculations;
- supporting FX/conversion fee logic.
Product requirement:
- all calculations must be auditable;
- rate used for transaction must be saved/snapshotted;
- Exchange Service не должен быть критическим blocker for already snapshotted transaction calculations.
10. Report Service
Report Service остается отдельным service внутри project/monorepo.
Он отвечает за:
- CSV export by current filters;
- report generation;
- storing generated files in Cloud Storage, если selected approach;
- async export jobs, если exports are heavy.
Report Service не должен быть on critical transaction creation path.
Advanced reports не входят в MVP.
11. What is Outbox / Inbox pattern
Outbox / Inbox pattern - это technical pattern для reliable event processing.
Он нужен, когда система:
- сохраняет данные в database;
- должна отправить event/message в queue;
- не хочет потерять event между database commit and queue publish.
Outbox
Outbox означает:
- Service сохраняет business change в database.
- В той же database transaction service сохраняет event в
outboxtable. - Отдельный publisher читает outbox records и публикует их в Pub/Sub.
- После successful publish outbox record отмечается как published.
Это защищает от ситуации:
text
transaction saved
service crashed before publishing event
event lostInbox
Inbox означает:
- Service получает message/event from queue.
- Service сохраняет message ID в
inboxtable. - Если такой message уже был обработан, service не выполняет side effect повторно.
- Processing становится idempotent.
Это защищает от duplicate messages.
Product view
Product owner не должен проектировать exact outbox/inbox tables.
Product requirement:
- accepted merchant requests must not be lost;
- accepted provider callbacks must not be lost;
- duplicate messages/callbacks must not create duplicate side effects;
- status/webhook/routing events must be traceable.
Development team должна решить, нужен ли classic outbox/inbox pattern или другой reliable messaging approach.
12. What are Pub/Sub topics and events
Pub/Sub topic - это named channel для событий.
Event - это сообщение, которое система публикует в topic.
Subscription - это consumer/view на topic, откуда service читает events.
Пример:
text
Topic: deposit-requests
Event: DepositRequested
Consumer: Orchestrator ServiceЗачем это описывать:
- чтобы понять, какие события существуют;
- кто их публикует;
- кто их читает;
- какие поля обязаны быть в event;
- какие retry/dead-letter rules нужны;
- какие events должны быть idempotent;
- какие events влияют на transaction timeline.
Product owner не должен определять exact Pub/Sub names.
Но нужно зафиксировать business events:
- DepositRequested;
- DepositSessionCreated;
- RoutingStarted;
- RoutingCompleted;
- ProviderRequestRequested;
- ProviderCallbackReceived;
- ProviderCallbackProcessed;
- TransactionStatusChanged;
- MerchantWebhookRequested;
- MerchantWebhookDelivered;
- MerchantWebhookFailed;
- MerchantWebhookRetryScheduled.
Development team должна превратить business events в exact Pub/Sub topics/subscriptions.
Detailed product-level async event flow описан отдельно:
text
10-technical-architecture/03-async-event-flow-and-pubsub.md13. Current decisions
На текущий момент согласовано:
- monorepo is required;
- minimal number of services;
- core business logic inside one deployable modular monolith;
- recommended core service name:
Orchestrator Service; - Exchange Service remains separate service within project;
- Report Service remains separate service within project;
- Backoffice Service may contain Back Office backend logic;
- Merchant Gateway creates payment session and hosted payment URL before returning success;
- Merchant Gateway processing after accepted request is asynchronous;
- Provider Gateway queues callback first and only then responds OK;
- Auth service is not separated in MVP;
- Pub/Sub events/topics need separate technical design;
- outbox/inbox pattern needs development team decision, but reliability requirements are mandatory.
14. Acceptance Criteria
Application Architecture Decisions считаются зафиксированными для MVP, если:
- repository/project naming separated from core service naming;
- monorepo requirement documented;
- deployable services listed;
- Orchestrator Service role documented;
- Exchange Service documented as separate service;
- Report Service documented as separate service;
- Backoffice Service responsibilities documented;
- Merchant Gateway responsibilities documented;
- Provider Gateway responsibilities documented;
- outbox/inbox explained;
- Pub/Sub topics/events explained;
- auth service not separated in MVP.
15. Open Questions
Product open questions отсутствуют.
Product decision:
- Product / Project:
Payment Orchestrator / HUB v3. - Repository:
payment-orchestrator. - Core service:
Orchestrator Service.
Technical/design follow-up:
- Development team должна предложить exact monorepo folder structure.
- Development team должна определить exact reliable messaging pattern.
- Development team должна определить exact Pub/Sub topics/subscriptions.
- Development team должна определить database boundaries and schema.
- Development team должна определить how Backoffice Service calls Orchestrator Service.