From 29d179a23a47289cc35b4e40893ebd4fffa191b7 Mon Sep 17 00:00:00 2001 From: Brian Johnson Date: Fri, 17 Jul 2026 17:10:28 +0200 Subject: [PATCH] Adjust location of classes further. --- .../ApplyFeeHandlerTests.cs | 4 +++- .../FinancialApi.Application/FeePair.cs | 5 ----- .../Handlers/ApplyFeeHandler.cs | 17 ++++++++------- .../Handlers/ReverseJournalHandler.cs | 18 +++++++--------- .../Handlers/TransferFundsHandler.cs | 21 +++++++++++-------- .../{Queries => Interfaces}/IAccountQuery.cs | 3 ++- .../Interfaces/IReversalQuery.cs | 10 +++++++++ .../Models/FeeContext.cs | 6 ++++++ .../Models/JournalReversalContext.cs | 9 ++++++++ .../Models/TransferContext.cs | 6 ++++++ .../Queries/IReversalQuery.cs | 8 ------- .../FinancialApi.Application/TransferPair.cs | 5 ----- .../{ => Aggregates}/BalancedJournal.cs | 4 +++- .../{ => Entities}/Account.cs | 2 +- .../{ => Entities}/EntryType.cs | 2 +- .../{ => Entities}/JournalEntry.cs | 2 +- .../{ => Entities}/JournalLine.cs | 2 +- .../AccountDbContext.cs | 1 + .../AccountQuery.cs | 3 ++- .../ReversalQuery.cs | 8 ++++--- .../FinancialApi/Program.cs | 2 +- 21 files changed, 82 insertions(+), 56 deletions(-) delete mode 100644 wolverine/a-frame-architecture/FinancialApi.Application/FeePair.cs rename wolverine/a-frame-architecture/FinancialApi.Application/{Queries => Interfaces}/IAccountQuery.cs (55%) create mode 100644 wolverine/a-frame-architecture/FinancialApi.Application/Interfaces/IReversalQuery.cs create mode 100644 wolverine/a-frame-architecture/FinancialApi.Application/Models/FeeContext.cs create mode 100644 wolverine/a-frame-architecture/FinancialApi.Application/Models/JournalReversalContext.cs create mode 100644 wolverine/a-frame-architecture/FinancialApi.Application/Models/TransferContext.cs delete mode 100644 wolverine/a-frame-architecture/FinancialApi.Application/Queries/IReversalQuery.cs delete mode 100644 wolverine/a-frame-architecture/FinancialApi.Application/TransferPair.cs rename wolverine/a-frame-architecture/FinancialApi.Domain/{ => Aggregates}/BalancedJournal.cs (93%) rename wolverine/a-frame-architecture/FinancialApi.Domain/{ => Entities}/Account.cs (97%) rename wolverine/a-frame-architecture/FinancialApi.Domain/{ => Entities}/EntryType.cs (54%) rename wolverine/a-frame-architecture/FinancialApi.Domain/{ => Entities}/JournalEntry.cs (92%) rename wolverine/a-frame-architecture/FinancialApi.Domain/{ => Entities}/JournalLine.cs (64%) diff --git a/wolverine/a-frame-architecture/FinancialApi.Application.UnitTests/ApplyFeeHandlerTests.cs b/wolverine/a-frame-architecture/FinancialApi.Application.UnitTests/ApplyFeeHandlerTests.cs index 3362803..15b2ec4 100644 --- a/wolverine/a-frame-architecture/FinancialApi.Application.UnitTests/ApplyFeeHandlerTests.cs +++ b/wolverine/a-frame-architecture/FinancialApi.Application.UnitTests/ApplyFeeHandlerTests.cs @@ -1,7 +1,9 @@ using System.Security.Cryptography; using FinancialApi.Application.Commands; using FinancialApi.Application.Handlers; +using FinancialApi.Application.Models; using FinancialApi.Domain; +using FinancialApi.Domain.Entities; using FluentAssertions; using FluentAssertions.Execution; @@ -16,7 +18,7 @@ public class ApplyFeeHandlerTests var command = new ApplyFeeCommand(1, 100); var account = new Account(1, 100, "Debit"); var revenueAccount = new Account(99999, 0, "Credit"); - var pair = new FeePair(account, revenueAccount, TimeProvider.System.GetUtcNow()); + var pair = new FeeContext(account, revenueAccount, TimeProvider.System.GetUtcNow()); // Act var intents = ApplyFeeHandler.Handle(command, pair); diff --git a/wolverine/a-frame-architecture/FinancialApi.Application/FeePair.cs b/wolverine/a-frame-architecture/FinancialApi.Application/FeePair.cs deleted file mode 100644 index a183e90..0000000 --- a/wolverine/a-frame-architecture/FinancialApi.Application/FeePair.cs +++ /dev/null @@ -1,5 +0,0 @@ -using FinancialApi.Domain; - -namespace FinancialApi.Application; - -public record FeePair(Account Source, Account Destination, DateTimeOffset TimeStamp); \ No newline at end of file diff --git a/wolverine/a-frame-architecture/FinancialApi.Application/Handlers/ApplyFeeHandler.cs b/wolverine/a-frame-architecture/FinancialApi.Application/Handlers/ApplyFeeHandler.cs index 96ebf8e..b7719cd 100644 --- a/wolverine/a-frame-architecture/FinancialApi.Application/Handlers/ApplyFeeHandler.cs +++ b/wolverine/a-frame-architecture/FinancialApi.Application/Handlers/ApplyFeeHandler.cs @@ -1,14 +1,17 @@ using FinancialApi.Application.Commands; using FinancialApi.Application.Events; -using FinancialApi.Application.Queries; +using FinancialApi.Application.Interfaces; +using FinancialApi.Application.Models; using FinancialApi.Domain; +using FinancialApi.Domain.Aggregates; +using FinancialApi.Domain.Entities; using Wolverine.Persistence; namespace FinancialApi.Application.Handlers; public static class ApplyFeeHandler { - public static async Task LoadAsync( + public static async Task LoadAsync( ApplyFeeCommand cmd, IAccountQuery query, TimeProvider timeProvider) { @@ -19,7 +22,7 @@ public static class ApplyFeeHandler throw new InvalidOperationException($"Cannot process transfer. Account(s) not found."); } - return new FeePair(source, dest, timeProvider.GetUtcNow()); + return new FeeContext(source, dest, timeProvider.GetUtcNow()); } public static ( @@ -30,11 +33,11 @@ public static class ApplyFeeHandler ) Handle( ApplyFeeCommand cmd, - FeePair pair + FeeContext context ) { - var updatedSource = pair.Source.ApplyPosting(cmd.Amount, EntryType.Debit); - var updatedRevenue = pair.Destination.ApplyPosting(cmd.Amount, EntryType.Credit); + var updatedSource = context.Source.ApplyPosting(cmd.Amount, EntryType.Debit); + var updatedRevenue = context.Destination.ApplyPosting(cmd.Amount, EntryType.Credit); var serviceFee = 0.5m; var lines = new List @@ -46,7 +49,7 @@ public static class ApplyFeeHandler var journalEntry = BalancedJournal.Create(Guid.NewGuid(), $"Service Fee Applied: {cmd.Amount} to Account {cmd.AccountId}", - pair.TimeStamp, lines); + context.TimeStamp, lines); var @event = new FeeAppliedEvent(cmd.AccountId, cmd.Amount); diff --git a/wolverine/a-frame-architecture/FinancialApi.Application/Handlers/ReverseJournalHandler.cs b/wolverine/a-frame-architecture/FinancialApi.Application/Handlers/ReverseJournalHandler.cs index 7f2e1b3..f481326 100644 --- a/wolverine/a-frame-architecture/FinancialApi.Application/Handlers/ReverseJournalHandler.cs +++ b/wolverine/a-frame-architecture/FinancialApi.Application/Handlers/ReverseJournalHandler.cs @@ -1,19 +1,17 @@ using FinancialApi.Application.Commands; using FinancialApi.Application.Events; -using FinancialApi.Application.Queries; +using FinancialApi.Application.Interfaces; +using FinancialApi.Application.Models; using FinancialApi.Domain; +using FinancialApi.Domain.Aggregates; +using FinancialApi.Domain.Entities; using Wolverine.Persistence; namespace FinancialApi.Application.Handlers; -public record ReversalData( - JournalEntry OriginalJournalEntry, - IReadOnlyList AffectedAccounts, - DateTimeOffset TimeStamp); - public static class ReverseJournalHandler { - public static async Task LoadAsync(ReverseJournalCommand cmd, IReversalQuery query, + public static async Task LoadAsync(ReverseJournalCommand cmd, IReversalQuery query, TimeProvider timeProvider) { var data = await query.GetReversalDataAsync(cmd.OriginalJournalId); @@ -24,11 +22,11 @@ public static class ReverseJournalHandler IStorageAction JournalWrite, UnitOfWork AccountWrites, JournalReversedEvent Event) - Handle(ReverseJournalCommand cmd, ReversalData data) + Handle(ReverseJournalCommand cmd, JournalReversalContext context) { var reversalJournal = - BalancedJournal.CreateReversal(data.OriginalJournalEntry, $"Reversal: {cmd.Reason}", data.TimeStamp); - var accountState = data.AffectedAccounts.ToDictionary(a => a.Id); + BalancedJournal.CreateReversal(context.OriginalJournalEntry, $"Reversal: {cmd.Reason}", context.TimeStamp); + var accountState = context.AffectedAccounts.ToDictionary(a => a.Id); reversalJournal.Entry.Lines.ForEach(l => { diff --git a/wolverine/a-frame-architecture/FinancialApi.Application/Handlers/TransferFundsHandler.cs b/wolverine/a-frame-architecture/FinancialApi.Application/Handlers/TransferFundsHandler.cs index 209ddf2..8f6a27e 100644 --- a/wolverine/a-frame-architecture/FinancialApi.Application/Handlers/TransferFundsHandler.cs +++ b/wolverine/a-frame-architecture/FinancialApi.Application/Handlers/TransferFundsHandler.cs @@ -1,14 +1,17 @@ using FinancialApi.Application.Commands; using FinancialApi.Application.Events; -using FinancialApi.Application.Queries; +using FinancialApi.Application.Interfaces; +using FinancialApi.Application.Models; using FinancialApi.Domain; +using FinancialApi.Domain.Aggregates; +using FinancialApi.Domain.Entities; using Wolverine.Persistence; namespace FinancialApi.Application.Handlers; public static class TransferFundsHandler { - public static async Task LoadAsync(TransferFundsCommand cmd, IAccountQuery query, + public static async Task LoadAsync(TransferFundsCommand cmd, IAccountQuery query, TimeProvider timeProvider) { var source = await query.FindByIdAsync(cmd.SourceAccountId); @@ -16,7 +19,7 @@ public static class TransferFundsHandler if (source == null || dest == null) return null; - return new TransferPair(source, dest, timeProvider.GetUtcNow()); + return new TransferContext(source, dest, timeProvider.GetUtcNow()); } public static ( @@ -24,21 +27,21 @@ public static class TransferFundsHandler IStorageAction DestWrite, IStorageAction JournalWrite, FundsTransferredEvent Event - ) Handle(TransferFundsCommand cmd, TransferPair pair) + ) Handle(TransferFundsCommand cmd, TransferContext context) { - var updatedSource = pair.Source.Debit(cmd.Amount); - var updatedDest = pair.Destination.Credit(cmd.Amount); + var updatedSource = context.Source.Debit(cmd.Amount); + var updatedDest = context.Destination.Credit(cmd.Amount); var lines = new List { - new(pair.Source.Id, cmd.Amount, EntryType.Debit), - new(pair.Destination.Id, cmd.Amount, EntryType.Credit) + new(context.Source.Id, cmd.Amount, EntryType.Debit), + new(context.Destination.Id, cmd.Amount, EntryType.Credit) }; var journalEntry = BalancedJournal.Create(Guid.NewGuid(), $"Transfer: {cmd.Amount} from {cmd.SourceAccountId} to {cmd.DestinationAccountId}", - pair.TimeStamp, lines); + context.TimeStamp, lines); var @event = new FundsTransferredEvent(cmd.SourceAccountId, cmd.DestinationAccountId, cmd.Amount); diff --git a/wolverine/a-frame-architecture/FinancialApi.Application/Queries/IAccountQuery.cs b/wolverine/a-frame-architecture/FinancialApi.Application/Interfaces/IAccountQuery.cs similarity index 55% rename from wolverine/a-frame-architecture/FinancialApi.Application/Queries/IAccountQuery.cs rename to wolverine/a-frame-architecture/FinancialApi.Application/Interfaces/IAccountQuery.cs index 887e612..b7d11a3 100644 --- a/wolverine/a-frame-architecture/FinancialApi.Application/Queries/IAccountQuery.cs +++ b/wolverine/a-frame-architecture/FinancialApi.Application/Interfaces/IAccountQuery.cs @@ -1,6 +1,7 @@ using FinancialApi.Domain; +using FinancialApi.Domain.Entities; -namespace FinancialApi.Application.Queries; +namespace FinancialApi.Application.Interfaces; public interface IAccountQuery { diff --git a/wolverine/a-frame-architecture/FinancialApi.Application/Interfaces/IReversalQuery.cs b/wolverine/a-frame-architecture/FinancialApi.Application/Interfaces/IReversalQuery.cs new file mode 100644 index 0000000..4c345f1 --- /dev/null +++ b/wolverine/a-frame-architecture/FinancialApi.Application/Interfaces/IReversalQuery.cs @@ -0,0 +1,10 @@ +using FinancialApi.Application.Commands; +using FinancialApi.Application.Handlers; +using FinancialApi.Application.Models; + +namespace FinancialApi.Application.Interfaces; + +public interface IReversalQuery +{ + Task GetReversalDataAsync(Guid journalEntryId); +} \ No newline at end of file diff --git a/wolverine/a-frame-architecture/FinancialApi.Application/Models/FeeContext.cs b/wolverine/a-frame-architecture/FinancialApi.Application/Models/FeeContext.cs new file mode 100644 index 0000000..8f15968 --- /dev/null +++ b/wolverine/a-frame-architecture/FinancialApi.Application/Models/FeeContext.cs @@ -0,0 +1,6 @@ +using FinancialApi.Domain; +using FinancialApi.Domain.Entities; + +namespace FinancialApi.Application.Models; + +public record FeeContext(Account Source, Account Destination, DateTimeOffset TimeStamp); \ No newline at end of file diff --git a/wolverine/a-frame-architecture/FinancialApi.Application/Models/JournalReversalContext.cs b/wolverine/a-frame-architecture/FinancialApi.Application/Models/JournalReversalContext.cs new file mode 100644 index 0000000..df79457 --- /dev/null +++ b/wolverine/a-frame-architecture/FinancialApi.Application/Models/JournalReversalContext.cs @@ -0,0 +1,9 @@ +using FinancialApi.Domain; +using FinancialApi.Domain.Entities; + +namespace FinancialApi.Application.Models; + +public record JournalReversalContext( + JournalEntry OriginalJournalEntry, + IReadOnlyList AffectedAccounts, + DateTimeOffset TimeStamp); \ No newline at end of file diff --git a/wolverine/a-frame-architecture/FinancialApi.Application/Models/TransferContext.cs b/wolverine/a-frame-architecture/FinancialApi.Application/Models/TransferContext.cs new file mode 100644 index 0000000..6f857a8 --- /dev/null +++ b/wolverine/a-frame-architecture/FinancialApi.Application/Models/TransferContext.cs @@ -0,0 +1,6 @@ +using FinancialApi.Domain; +using FinancialApi.Domain.Entities; + +namespace FinancialApi.Application.Models; + +public record TransferContext(Account Source, Account Destination, DateTimeOffset TimeStamp); \ No newline at end of file diff --git a/wolverine/a-frame-architecture/FinancialApi.Application/Queries/IReversalQuery.cs b/wolverine/a-frame-architecture/FinancialApi.Application/Queries/IReversalQuery.cs deleted file mode 100644 index 3925eb2..0000000 --- a/wolverine/a-frame-architecture/FinancialApi.Application/Queries/IReversalQuery.cs +++ /dev/null @@ -1,8 +0,0 @@ -using FinancialApi.Application.Handlers; - -namespace FinancialApi.Application.Queries; - -public interface IReversalQuery -{ - Task GetReversalDataAsync(Guid journalEntryId); -} \ No newline at end of file diff --git a/wolverine/a-frame-architecture/FinancialApi.Application/TransferPair.cs b/wolverine/a-frame-architecture/FinancialApi.Application/TransferPair.cs deleted file mode 100644 index 4f19502..0000000 --- a/wolverine/a-frame-architecture/FinancialApi.Application/TransferPair.cs +++ /dev/null @@ -1,5 +0,0 @@ -using FinancialApi.Domain; - -namespace FinancialApi.Application; - -public record TransferPair(Account Source, Account Destination, DateTimeOffset TimeStamp); \ No newline at end of file diff --git a/wolverine/a-frame-architecture/FinancialApi.Domain/BalancedJournal.cs b/wolverine/a-frame-architecture/FinancialApi.Domain/Aggregates/BalancedJournal.cs similarity index 93% rename from wolverine/a-frame-architecture/FinancialApi.Domain/BalancedJournal.cs rename to wolverine/a-frame-architecture/FinancialApi.Domain/Aggregates/BalancedJournal.cs index 07c9435..19b643e 100644 --- a/wolverine/a-frame-architecture/FinancialApi.Domain/BalancedJournal.cs +++ b/wolverine/a-frame-architecture/FinancialApi.Domain/Aggregates/BalancedJournal.cs @@ -1,4 +1,6 @@ -namespace FinancialApi.Domain; +using FinancialApi.Domain.Entities; + +namespace FinancialApi.Domain.Aggregates; public record BalancedJournal { diff --git a/wolverine/a-frame-architecture/FinancialApi.Domain/Account.cs b/wolverine/a-frame-architecture/FinancialApi.Domain/Entities/Account.cs similarity index 97% rename from wolverine/a-frame-architecture/FinancialApi.Domain/Account.cs rename to wolverine/a-frame-architecture/FinancialApi.Domain/Entities/Account.cs index 0d4d592..b4531de 100644 --- a/wolverine/a-frame-architecture/FinancialApi.Domain/Account.cs +++ b/wolverine/a-frame-architecture/FinancialApi.Domain/Entities/Account.cs @@ -1,4 +1,4 @@ -namespace FinancialApi.Domain; +namespace FinancialApi.Domain.Entities; public record Account(int Id, decimal Balance, string AccountType) { diff --git a/wolverine/a-frame-architecture/FinancialApi.Domain/EntryType.cs b/wolverine/a-frame-architecture/FinancialApi.Domain/Entities/EntryType.cs similarity index 54% rename from wolverine/a-frame-architecture/FinancialApi.Domain/EntryType.cs rename to wolverine/a-frame-architecture/FinancialApi.Domain/Entities/EntryType.cs index 4211801..491289e 100644 --- a/wolverine/a-frame-architecture/FinancialApi.Domain/EntryType.cs +++ b/wolverine/a-frame-architecture/FinancialApi.Domain/Entities/EntryType.cs @@ -1,4 +1,4 @@ -namespace FinancialApi.Domain; +namespace FinancialApi.Domain.Entities; public enum EntryType { diff --git a/wolverine/a-frame-architecture/FinancialApi.Domain/JournalEntry.cs b/wolverine/a-frame-architecture/FinancialApi.Domain/Entities/JournalEntry.cs similarity index 92% rename from wolverine/a-frame-architecture/FinancialApi.Domain/JournalEntry.cs rename to wolverine/a-frame-architecture/FinancialApi.Domain/Entities/JournalEntry.cs index 649fe2f..85523af 100644 --- a/wolverine/a-frame-architecture/FinancialApi.Domain/JournalEntry.cs +++ b/wolverine/a-frame-architecture/FinancialApi.Domain/Entities/JournalEntry.cs @@ -1,4 +1,4 @@ -namespace FinancialApi.Domain; +namespace FinancialApi.Domain.Entities; public record JournalEntry { diff --git a/wolverine/a-frame-architecture/FinancialApi.Domain/JournalLine.cs b/wolverine/a-frame-architecture/FinancialApi.Domain/Entities/JournalLine.cs similarity index 64% rename from wolverine/a-frame-architecture/FinancialApi.Domain/JournalLine.cs rename to wolverine/a-frame-architecture/FinancialApi.Domain/Entities/JournalLine.cs index 41802c9..03d4e3b 100644 --- a/wolverine/a-frame-architecture/FinancialApi.Domain/JournalLine.cs +++ b/wolverine/a-frame-architecture/FinancialApi.Domain/Entities/JournalLine.cs @@ -1,3 +1,3 @@ -namespace FinancialApi.Domain; +namespace FinancialApi.Domain.Entities; public record JournalLine(int AccountId, decimal Amount, EntryType Type); \ No newline at end of file diff --git a/wolverine/a-frame-architecture/FinancialApi.Infrastructure/AccountDbContext.cs b/wolverine/a-frame-architecture/FinancialApi.Infrastructure/AccountDbContext.cs index 935af0f..1ef3c3c 100644 --- a/wolverine/a-frame-architecture/FinancialApi.Infrastructure/AccountDbContext.cs +++ b/wolverine/a-frame-architecture/FinancialApi.Infrastructure/AccountDbContext.cs @@ -1,4 +1,5 @@ using FinancialApi.Domain; +using FinancialApi.Domain.Entities; using Microsoft.EntityFrameworkCore; namespace FinancialApi.Infrastructure; diff --git a/wolverine/a-frame-architecture/FinancialApi.Infrastructure/AccountQuery.cs b/wolverine/a-frame-architecture/FinancialApi.Infrastructure/AccountQuery.cs index be5aa70..8f4e774 100644 --- a/wolverine/a-frame-architecture/FinancialApi.Infrastructure/AccountQuery.cs +++ b/wolverine/a-frame-architecture/FinancialApi.Infrastructure/AccountQuery.cs @@ -1,5 +1,6 @@ -using FinancialApi.Application.Queries; +using FinancialApi.Application.Interfaces; using FinancialApi.Domain; +using FinancialApi.Domain.Entities; using Microsoft.EntityFrameworkCore; namespace FinancialApi.Infrastructure; diff --git a/wolverine/a-frame-architecture/FinancialApi.Infrastructure/ReversalQuery.cs b/wolverine/a-frame-architecture/FinancialApi.Infrastructure/ReversalQuery.cs index 44e82ae..6a12db8 100644 --- a/wolverine/a-frame-architecture/FinancialApi.Infrastructure/ReversalQuery.cs +++ b/wolverine/a-frame-architecture/FinancialApi.Infrastructure/ReversalQuery.cs @@ -1,12 +1,14 @@ +using FinancialApi.Application.Commands; using FinancialApi.Application.Handlers; -using FinancialApi.Application.Queries; +using FinancialApi.Application.Interfaces; +using FinancialApi.Application.Models; using Microsoft.EntityFrameworkCore; namespace FinancialApi.Infrastructure; public class ReversalQuery(AccountDbContext db, TimeProvider timeProvider) : IReversalQuery { - public async Task GetReversalDataAsync(Guid journalEntryId) + public async Task GetReversalDataAsync(Guid journalEntryId) { var entry = await db.JournalEntries .Include(x => x.Lines) @@ -25,6 +27,6 @@ public class ReversalQuery(AccountDbContext db, TimeProvider timeProvider) : IRe .Where(a => accountIds.Contains(a.Id)) .ToListAsync(); - return new ReversalData(entry, accounts, timeProvider.GetUtcNow()); + return new JournalReversalContext(entry, accounts, timeProvider.GetUtcNow()); } } \ No newline at end of file diff --git a/wolverine/a-frame-architecture/FinancialApi/Program.cs b/wolverine/a-frame-architecture/FinancialApi/Program.cs index f71b462..bdb87ac 100644 --- a/wolverine/a-frame-architecture/FinancialApi/Program.cs +++ b/wolverine/a-frame-architecture/FinancialApi/Program.cs @@ -2,7 +2,7 @@ using FinancialApi; using FinancialApi.Application.Commands; using FinancialApi.Application.Events; using FinancialApi.Application.Handlers; -using FinancialApi.Application.Queries; +using FinancialApi.Application.Interfaces; using FinancialApi.Infrastructure; using FinancialApi.ServiceDefaults; using JasperFx.Resources;