From d63ded45e18a285156f0531342e93f853be9d215 Mon Sep 17 00:00:00 2001 From: AJ Isaacs Date: Mon, 20 Apr 2026 18:19:31 -0400 Subject: [PATCH] refactor: abstract IWebHostEnvironment to IReceiptStorageOptions Co-Authored-By: Claude Opus 4.6 --- .../Services/IReceiptStorageOptions.cs | 6 ++++++ MoneyMap.Core/Services/ReceiptManager.cs | 13 ++++--------- MoneyMap/Program.cs | 4 ++++ MoneyMap/Services/WebReceiptStorageOptions.cs | 17 +++++++++++++++++ 4 files changed, 31 insertions(+), 9 deletions(-) create mode 100644 MoneyMap.Core/Services/IReceiptStorageOptions.cs create mode 100644 MoneyMap/Services/WebReceiptStorageOptions.cs diff --git a/MoneyMap.Core/Services/IReceiptStorageOptions.cs b/MoneyMap.Core/Services/IReceiptStorageOptions.cs new file mode 100644 index 0000000..e424648 --- /dev/null +++ b/MoneyMap.Core/Services/IReceiptStorageOptions.cs @@ -0,0 +1,6 @@ +namespace MoneyMap.Services; + +public interface IReceiptStorageOptions +{ + string ReceiptsBasePath { get; } +} diff --git a/MoneyMap.Core/Services/ReceiptManager.cs b/MoneyMap.Core/Services/ReceiptManager.cs index 78f46a3..d2f2358 100644 --- a/MoneyMap.Core/Services/ReceiptManager.cs +++ b/MoneyMap.Core/Services/ReceiptManager.cs @@ -21,8 +21,7 @@ namespace MoneyMap.Services public class ReceiptManager : IReceiptManager { private readonly MoneyMapContext _db; - private readonly IWebHostEnvironment _environment; - private readonly IConfiguration _configuration; + private readonly IReceiptStorageOptions _receiptStorage; private readonly IServiceProvider _serviceProvider; private readonly IReceiptParseQueue _parseQueue; private readonly ILogger _logger; @@ -46,15 +45,13 @@ namespace MoneyMap.Services public ReceiptManager( MoneyMapContext db, - IWebHostEnvironment environment, - IConfiguration configuration, + IReceiptStorageOptions receiptStorage, IServiceProvider serviceProvider, IReceiptParseQueue parseQueue, ILogger logger) { _db = db; - _environment = environment; - _configuration = configuration; + _receiptStorage = receiptStorage; _serviceProvider = serviceProvider; _parseQueue = parseQueue; _logger = logger; @@ -62,9 +59,7 @@ namespace MoneyMap.Services private string GetReceiptsBasePath() { - // Get from config, default to "receipts" in wwwroot - var relativePath = _configuration["Receipts:StoragePath"] ?? "receipts"; - return Path.Combine(_environment.WebRootPath, relativePath); + return _receiptStorage.ReceiptsBasePath; } public async Task UploadReceiptAsync(long transactionId, IFormFile file) diff --git a/MoneyMap/Program.cs b/MoneyMap/Program.cs index c4e721b..a30893a 100644 --- a/MoneyMap/Program.cs +++ b/MoneyMap/Program.cs @@ -3,6 +3,7 @@ using Microsoft.EntityFrameworkCore; using MoneyMap.Data; using MoneyMap.Services; using MoneyMap.Services.AITools; +using MoneyMap.WebApp.Services; // Set default culture to en-US for currency formatting ($) var culture = new CultureInfo("en-US"); @@ -57,6 +58,9 @@ builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); +// Receipt storage configuration +builder.Services.AddSingleton(); + // Receipt services builder.Services.AddScoped(); builder.Services.AddScoped(); diff --git a/MoneyMap/Services/WebReceiptStorageOptions.cs b/MoneyMap/Services/WebReceiptStorageOptions.cs new file mode 100644 index 0000000..df96d76 --- /dev/null +++ b/MoneyMap/Services/WebReceiptStorageOptions.cs @@ -0,0 +1,17 @@ +using MoneyMap.Services; + +namespace MoneyMap.WebApp.Services; + +public class WebReceiptStorageOptions : IReceiptStorageOptions +{ + public string ReceiptsBasePath { get; } + + public WebReceiptStorageOptions(IWebHostEnvironment env, IConfiguration config) + { + var relativePath = config["Receipts:StoragePath"] ?? "receipts"; + if (Path.IsPathRooted(relativePath)) + ReceiptsBasePath = relativePath; + else + ReceiptsBasePath = Path.Combine(env.WebRootPath, relativePath); + } +}