The Accounting Service in the FTGO application manages customer payment accounts and handles payment authorization as part of distributed order transactions. It is the only service in the FTGO application that uses event sourcing via the Eventuate Client framework: theDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/microservices-patterns/ftgo-application/llms.txt
Use this file to discover all available pages before exploring further.
Account aggregate’s state is persisted entirely as a sequence of events rather than as a traditional relational row. This page covers the service’s responsibilities, domain model, REST API, messaging, and storage schema.
Responsibilities
- Maintain event-sourced
Accountaggregates representing the payment account for each consumer - Handle
AuthorizeCommandsaga commands to authorize payment when an order is created - Handle
ReverseAuthorizationCommandsaga commands to reverse a payment when an order is cancelled - Handle
ReviseAuthorizationsaga commands to adjust the authorized amount when an order is revised - Expose a REST endpoint to retrieve account information by ID
Domain Model
TheAccount aggregate extends ReflectiveMutableCommandProcessingAggregate<Account, AccountCommand> from the Eventuate Client library. State is derived entirely from the event stream — there is no accounts table in a traditional sense.
Commands processed
| Command | Event emitted |
|---|---|
CreateAccountCommand | AccountCreatedEvent |
AuthorizeCommandInternal | AccountAuthorizedEvent |
ReverseAuthorizationCommandInternal | (empty list — no event) |
ReviseAuthorizationCommandInternal | (empty list — no event) |
apply() methods rebuild aggregate state from events. AccountAuthorizedEvent triggers the apply(AccountAuthorizedEvent) method, which can update internal balance or authorization state. SagaReplyRequestedEvent is also applied (required by the Eventuate Tram sagas-eventsourcing integration).
Because
Account uses event sourcing, queries against account state load the full event history from the Eventuate event store and replay it. The AggregateRepository<Account, AccountCommand> handles this transparently.Account lifecycle
replyingTo option in AccountingServiceCommandHandler ensures that replies are sent back and duplicate commands are handled by the saga framework.
The
AccountDisabledException is a domain exception that causes the command handler to reply with AccountDisabledReply, which causes the CreateOrderSaga to fail and the order to be rejected.REST API
The service listens on port 8085. All endpoints are under the/accounts path.
| Method | Path | Description |
|---|---|---|
GET | /accounts/{accountId} | Retrieve account information by ID. Returns 404 if the account entity does not exist in the event store. |
Get account response body
The account ID is a
String because Eventuate Client uses string-based aggregate IDs. The AccountsController maps the consumer’s numeric ID (as a string) to the Eventuate aggregate ID.Messaging
The Accounting Service listens on theaccountingService command channel and handles saga commands sent by the Order Service:
| Command | Handler method | Reply on success | Reply on failure |
|---|---|---|---|
AuthorizeCommand | authorize() | withSuccess() | withFailure(AccountDisabledReply) |
ReverseAuthorizationCommand | reverseAuthorization() | withSuccess() | withFailure(AccountDisabledReply) |
ReviseAuthorization | reviseAuthorization() | withSuccess() | withFailure(AccountDisabledReply) |
replyingTo(cm) option with .catching(AccountDisabledException.class, ...) so that a disabled account automatically generates the appropriate failure reply.
The consumer ID from the incoming command is converted to a string to address the Eventuate AggregateRepository:
Events published
The Accounting Service emits events into the Eventuate event store (not the Eventuate Tram message bus):| Event | Trigger |
|---|---|
AccountCreatedEvent | CreateAccountCommand is processed |
AccountAuthorizedEvent | AuthorizeCommandInternal is processed |
events table) rather than the Tram outbox.
Database
The Accounting Service uses the Eventuate event store (MySQL-backed by default in the FTGO docker-compose setup) rather than a traditional domain schema.| Table | Description |
|---|---|
events | Eventuate event store — all Account aggregate events |
entities | Eventuate entity registry — tracks the latest event position per aggregate ID |
snapshots | Optional snapshots for aggregate replay optimization |