From 37d89aa602942a3e5bf3d2faecdf692be5472ad7 Mon Sep 17 00:00:00 2001 From: gamer147 Date: Tue, 9 Jun 2026 14:55:43 -0400 Subject: [PATCH] refactor(inventory): share retention cap + invariant-culture date format Introduce InventoryHistoryConfig.RetentionRowsPerViewer as the single source of truth for the 300-row audit-log cap; InventoryTransaction aliases it and ItemAcquireHistoryController.Take() references it directly so the two sites cannot drift. Also adds CultureInfo.InvariantCulture to the AcquireTime.ToString() call, matching every other WireDateFormat site in the codebase. Co-Authored-By: Claude Sonnet 4.6 --- .../Services/Inventory/InventoryHistoryConfig.cs | 15 +++++++++++++++ .../Services/Inventory/InventoryTransaction.cs | 2 +- .../Controllers/ItemAcquireHistoryController.cs | 7 ++++--- 3 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 SVSim.Database/Services/Inventory/InventoryHistoryConfig.cs diff --git a/SVSim.Database/Services/Inventory/InventoryHistoryConfig.cs b/SVSim.Database/Services/Inventory/InventoryHistoryConfig.cs new file mode 100644 index 0000000..f682d7d --- /dev/null +++ b/SVSim.Database/Services/Inventory/InventoryHistoryConfig.cs @@ -0,0 +1,15 @@ +namespace SVSim.Database.Services.Inventory; + +/// +/// Shared knobs for the viewer-acquire-history audit log. The write-side prune cap +/// (in InventoryTransaction) and the read-side page size (in +/// ItemAcquireHistoryController) both reference these constants so they cannot drift. +/// +public static class InventoryHistoryConfig +{ + /// + /// Maximum rows kept per viewer. Older rows are pruned by + /// InventoryTransaction.CommitAsync; the read endpoint pages exactly this many. + /// + public const int RetentionRowsPerViewer = 300; +} diff --git a/SVSim.Database/Services/Inventory/InventoryTransaction.cs b/SVSim.Database/Services/Inventory/InventoryTransaction.cs index 2a99f75..610042a 100644 --- a/SVSim.Database/Services/Inventory/InventoryTransaction.cs +++ b/SVSim.Database/Services/Inventory/InventoryTransaction.cs @@ -9,7 +9,7 @@ namespace SVSim.Database.Services.Inventory; internal sealed class InventoryTransaction : IInventoryTransaction { - private const int AcquireHistoryRetention = 300; + private const int AcquireHistoryRetention = InventoryHistoryConfig.RetentionRowsPerViewer; private readonly SVSimDbContext _db; private readonly IDbContextTransaction _dbTx; diff --git a/SVSim.EmulatedEntrypoint/Controllers/ItemAcquireHistoryController.cs b/SVSim.EmulatedEntrypoint/Controllers/ItemAcquireHistoryController.cs index 55728f4..ba5a35f 100644 --- a/SVSim.EmulatedEntrypoint/Controllers/ItemAcquireHistoryController.cs +++ b/SVSim.EmulatedEntrypoint/Controllers/ItemAcquireHistoryController.cs @@ -1,6 +1,8 @@ +using System.Globalization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using SVSim.Database; +using SVSim.Database.Services.Inventory; using SVSim.EmulatedEntrypoint.Models.Dtos.ItemAcquireHistory; namespace SVSim.EmulatedEntrypoint.Controllers; @@ -9,7 +11,6 @@ namespace SVSim.EmulatedEntrypoint.Controllers; public sealed class ItemAcquireHistoryController : SVSimController { private const string WireDateFormat = "yyyy-MM-dd HH:mm:ss"; - private const int PageSize = 300; private readonly SVSimDbContext _db; @@ -26,7 +27,7 @@ public sealed class ItemAcquireHistoryController : SVSimController .Where(h => h.ViewerId == viewerId) .OrderByDescending(h => h.AcquireTime) .ThenByDescending(h => h.Id) - .Take(PageSize) + .Take(InventoryHistoryConfig.RetentionRowsPerViewer) .AsNoTracking() .ToListAsync(ct); @@ -38,7 +39,7 @@ public sealed class ItemAcquireHistoryController : SVSimController RewardDetailId = h.RewardDetailId.ToString(), RewardCount = h.RewardCount.ToString(), AcquireType = h.AcquireType.ToString(), - AcquireTime = h.AcquireTime.ToString(WireDateFormat), + AcquireTime = h.AcquireTime.ToString(WireDateFormat, CultureInfo.InvariantCulture), Message = h.Message, }).ToList(), };