feat(audit): correlation id on payment commands + events (Story 13.7 …#27
Merged
Conversation
…Phase B gate #4) PaymentCommand extends AuditableCommand (var correlationId + withCorrelationId; zero churn). The three consumed payment events extend AuditableEvent + carry correlation_id (PaidInEvent #10, FirstRecurringPaidInEvent #10, NextRecurringPaidEvent #14). handlePayIn / handleRecurringPayment take a correlationId param threaded from cmd.correlationId at their call sites and stamp it onto the persisted event (.copy). The checkout payIn endpoint prepends HttpCorrelation.correlationInput and stamps the PayIn command, so the originating X-Correlation-Id rides command -> PaidInEvent -> the licensing pod. Bumps genericPersistence -> 0.9-SNAPSHOT, scheduler -> 0.8-SNAPSHOT, notification -> 0.9-SNAPSHOT, version -> 0.9-SNAPSHOT. AuditableCommandSpec (chill/Kryo round-trip, 3 green); +common/+core compile (2.12+2.13) + scalafmtAll clean. Remaining origin coverage (follow-up): preAuthorize / recurring-registration / payInCallback endpoints + the akka-http PaymentService variant + schedule->ExecuteNext command threading. Core events are correlation-ready; gate #5 prefers event.correlationId else the deterministic in-pod fallback. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #27 +/- ##
==========================================
+ Coverage 40.80% 40.92% +0.12%
==========================================
Files 155 155
Lines 10549 10861 +312
Branches 1604 1810 +206
==========================================
+ Hits 4304 4445 +141
- Misses 6245 6416 +171
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
…metadata (Story 13.7 gate #4) Emit structured payment audit lines and carry a single correlation id end-to-end (HTTP origin -> command -> persisted event -> licensing pod -> notification), with a stable orderUuid fallback so no event/line is ever untraceable. Audit emission (PaymentAuditLog = AuditLog("payment")): charge_succeeded/charge_failed (PayIn), subscription_charged/subscription_charge_failed (recurring), refund/refund_failed, preauthorization_succeeded/failed/canceled, payout_succeeded/failed. Coherence: each command handler shadows the threaded cid with effectiveCorrelationId = cid.getOrElse(<businessKey: orderUuid / transaction.orderUuid / recurringPayment.externalReference>), stamped on EVERY event in the persist batch and used for the audit line, so event.correlationId (read by the licensing pod) and the audit line always agree. Stripe WRITE side: providers stamp metadata.correlation_id on object creation (PayIn/PayOut/PreAuth/Refund/Transfer/DirectDebit); RecurringPayment carries it via its metadata map, falling back to the subscription id when no explicit cid. Stripe READ side (StripeEventHandler): webhook_received audit line + resolveCorrelationId(obj,event) = metadata.correlation_id -> external_reference -> order_uuid -> backing subscription id -> event id; all webhook-driven command stamps routed through it. Protos: correlation_id on transaction/payment events + AuditableEvent; commands extend AuditableCommand. Endpoints: correlationInput wired across all payment endpoints (origin at the HTTP request). BasicPaymentService.run stamps the MDC cid on synchronous routes. Tests: AuditableCommandSpec (chill/Kryo cid round-trip), StripeWebhookCorrelationSpec (metadata resolution + subscription-id fallback + webhook_received), PaymentHandlerSpec charge_succeeded capture. scalafmt clean; cross-compiles 2.12 + 2.13. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
…Phase B gate #4)
PaymentCommand extends AuditableCommand (var correlationId + withCorrelationId; zero churn). The three consumed payment events extend AuditableEvent + carry correlation_id (PaidInEvent #10, FirstRecurringPaidInEvent #10, NextRecurringPaidEvent #14).
handlePayIn / handleRecurringPayment take a correlationId param threaded from cmd.correlationId at their call sites and stamp it onto the persisted event (.copy). The checkout payIn endpoint prepends HttpCorrelation.correlationInput and stamps the PayIn command, so the originating X-Correlation-Id rides command -> PaidInEvent -> the licensing pod.
Bumps genericPersistence -> 0.9-SNAPSHOT, scheduler -> 0.8-SNAPSHOT, notification -> 0.9-SNAPSHOT, version -> 0.9-SNAPSHOT. AuditableCommandSpec (chill/Kryo round-trip, 3 green); +common/+core compile (2.12+2.13) + scalafmtAll clean.
Remaining origin coverage (follow-up): preAuthorize / recurring-registration / payInCallback endpoints + the akka-http PaymentService variant + schedule->ExecuteNext command threading. Core events are correlation-ready; gate #5 prefers event.correlationId else the deterministic in-pod fallback.