feat(compliance): consume ledger transactions and raise aml alerts - #280
Merged
Conversation
Add the first event consumer: a Kafka listener on the ledger transaction topic deserializes posted-transaction events into a local wire view, and an idempotent handler deduplicates by envelope id, evaluates the transaction with the embedded AML engine and persists an alert when it is flagged, all in one transaction so a failed handler retries safely. Alerts now record the subject they concern. The external receive stays outside the transaction; dedup uses the shared processed-events ledger. Rolling-window aggregation and dead-letter handling are left for follow-ups. Closes #267
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
E-04 Compliance #267 - the AML event consumer (the first event consumer in the repo).
What
@KafkaListeneronfincore.transaction, groupcompliance-aml): deserializes the envelope via a JacksonTypeReferenceinto a compliance-owned wire DTO (LedgerTransactionPosted,@JsonIgnoreProperties- services don't share classes), filtersTransactionPosted(the topic also carries reversals), and delegates. Thin, no@Transactional.@Service @Transactional): deduplicates by envelope id (IdempotentEventProcessor+JdbcProcessedEventStore, F-03.5 Idempotent consumer base class / annotation #192), maps the event to anAmlTransactionView(amount = sum of DEBIT entries as BigDecimal), evaluates with the embedded AML engine (F-04.6 AML rules engine + rolling-window aggregation #266), and persists anAmlAlertwhen flagged - all in one transaction, so a thrown handler rolls back the claim and the event retries (at-least-once + idempotent). No external call inside the transaction.processed_events(default schema, matching the store's unqualified table name) +subject_referenceonaml_alerts(an alert now records its subject).fincore.eventbus.bootstrap-serversunset).Tests
Unit: handler (dedup, DEBIT-sum, flag/clear), consumer (typed deserialization + type filtering). IT:
@SpringBootTest+ Testcontainers (Redpanda + Postgres) publishing viaKafkaTemplate-> asserts an alert by subject, and a duplicate envelope raises only one alert (await + settle).Notes / deferred
Rolling-window composition (no history source yet) and a DLQ/error-handler (the #193 toolkit exists) are explicit follow-ups; documented, state-safe (poison message never commits).
Gate chain
All local gates green; the Redpanda+Postgres IT runs on CI.
Closes #267