Move FeatureUsage code into MicCheck.Api.Features.Usage namespace

Groups usage-tracking (metrics, background flush, query service,
controller, entity) under its own namespace/folder, updates all
consumers and the EF migration snapshot's CLR type strings to match.
This commit is contained in:
2026-07-05 22:00:13 -07:00
parent bdc85a1f3a
commit 27497e31a9
19 changed files with 22 additions and 16 deletions

View File

@@ -1,4 +1,4 @@
using MicCheck.Api.Features; using MicCheck.Api.Features.Usage;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders; using Microsoft.EntityFrameworkCore.Metadata.Builders;

View File

@@ -2,6 +2,7 @@ using MicCheck.Api.Common.Security.ApiKeys;
using MicCheck.Api.Audit; using MicCheck.Api.Audit;
using MicCheck.Api.Common.Security.Authorization; using MicCheck.Api.Common.Security.Authorization;
using MicCheck.Api.Features; using MicCheck.Api.Features;
using MicCheck.Api.Features.Usage;
using MicCheck.Api.Identities; using MicCheck.Api.Identities;
using MicCheck.Api.Organizations; using MicCheck.Api.Organizations;
using MicCheck.Api.Projects; using MicCheck.Api.Projects;

View File

@@ -1,4 +1,5 @@
using MicCheck.Api.Data; using MicCheck.Api.Data;
using MicCheck.Api.Features.Usage;
using MicCheck.Api.Identities; using MicCheck.Api.Identities;
using MicCheck.Api.Segments; using MicCheck.Api.Segments;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;

View File

@@ -1,3 +1,3 @@
namespace MicCheck.Api.Features; namespace MicCheck.Api.Features.Usage;
public record struct FeatureUsageBucketKey(int EnvironmentId, int FeatureId, string FeatureName, DateOnly UsageDate); public record struct FeatureUsageBucketKey(int EnvironmentId, int FeatureId, string FeatureName, DateOnly UsageDate);

View File

@@ -4,7 +4,7 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.RateLimiting; using Microsoft.AspNetCore.RateLimiting;
using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Caching.Memory;
namespace MicCheck.Api.Features; namespace MicCheck.Api.Features.Usage;
[ApiController] [ApiController]
[Route("api/v1/environment/{environmentId}/usage")] [Route("api/v1/environment/{environmentId}/usage")]

View File

@@ -1,4 +1,4 @@
namespace MicCheck.Api.Features; namespace MicCheck.Api.Features.Usage;
public class FeatureUsageDaily public class FeatureUsageDaily
{ {

View File

@@ -2,7 +2,7 @@ using System.Diagnostics.CodeAnalysis;
using MicCheck.Api.Data; using MicCheck.Api.Data;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
namespace MicCheck.Api.Features; namespace MicCheck.Api.Features.Usage;
[ExcludeFromCodeCoverage(Justification = "Timer-driven BackgroundService that issues raw SQL through a DI-scoped concrete MicCheckDbContext; exercising it cleanly requires a live DB, which CLAUDE.md disallows (no WebApplicationFactory/InMemory). DrainAccumulated's bucketing logic is covered by FeatureUsageMetricsTests.")] [ExcludeFromCodeCoverage(Justification = "Timer-driven BackgroundService that issues raw SQL through a DI-scoped concrete MicCheckDbContext; exercising it cleanly requires a live DB, which CLAUDE.md disallows (no WebApplicationFactory/InMemory). DrainAccumulated's bucketing logic is covered by FeatureUsageMetricsTests.")]
public class FeatureUsageFlushBackgroundService( public class FeatureUsageFlushBackgroundService(

View File

@@ -1,7 +1,7 @@
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Diagnostics.Metrics; using System.Diagnostics.Metrics;
namespace MicCheck.Api.Features; namespace MicCheck.Api.Features.Usage;
public class FeatureUsageMetrics : IDisposable public class FeatureUsageMetrics : IDisposable
{ {

View File

@@ -1,7 +1,7 @@
using MicCheck.Api.Data; using MicCheck.Api.Data;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
namespace MicCheck.Api.Features; namespace MicCheck.Api.Features.Usage;
public class FeatureUsageQueryService(IMicCheckDbContext db) public class FeatureUsageQueryService(IMicCheckDbContext db)
{ {

View File

@@ -1,4 +1,4 @@
namespace MicCheck.Api.Features; namespace MicCheck.Api.Features.Usage;
public record TopFeatureUsage(int FeatureId, string FeatureName, long Count); public record TopFeatureUsage(int FeatureId, string FeatureName, long Count);

View File

@@ -305,7 +305,7 @@ namespace MicCheck.Api.Migrations
b.ToTable("FeatureStates"); b.ToTable("FeatureStates");
}); });
modelBuilder.Entity("MicCheck.Api.Features.FeatureUsageDaily", b => modelBuilder.Entity("MicCheck.Api.Features.Usage.FeatureUsageDaily", b =>
{ {
b.Property<int>("Id") b.Property<int>("Id")
.ValueGeneratedOnAdd() .ValueGeneratedOnAdd()

View File

@@ -302,7 +302,7 @@ namespace MicCheck.Api.Migrations
b.ToTable("FeatureStates"); b.ToTable("FeatureStates");
}); });
modelBuilder.Entity("MicCheck.Api.Features.FeatureUsageDaily", b => modelBuilder.Entity("MicCheck.Api.Features.Usage.FeatureUsageDaily", b =>
{ {
b.Property<int>("Id") b.Property<int>("Id")
.ValueGeneratedOnAdd() .ValueGeneratedOnAdd()

View File

@@ -8,6 +8,7 @@ using MicCheck.Api.Common.Validation;
using MicCheck.Api.Data; using MicCheck.Api.Data;
using MicCheck.Api.Environments; using MicCheck.Api.Environments;
using MicCheck.Api.Features; using MicCheck.Api.Features;
using MicCheck.Api.Features.Usage;
using MicCheck.Api.Identities; using MicCheck.Api.Identities;
using MicCheck.Api.Organizations; using MicCheck.Api.Organizations;
using MicCheck.Api.Projects; using MicCheck.Api.Projects;

View File

@@ -1,6 +1,7 @@
using System.Diagnostics.Metrics; using System.Diagnostics.Metrics;
using MicCheck.Api.Data; using MicCheck.Api.Data;
using MicCheck.Api.Features; using MicCheck.Api.Features;
using MicCheck.Api.Features.Usage;
using MicCheck.Api.Identities; using MicCheck.Api.Identities;
using MicCheck.Api.Segments; using MicCheck.Api.Segments;
using MicCheck.Api.Tests.Unit.TestSupport; using MicCheck.Api.Tests.Unit.TestSupport;

View File

@@ -2,6 +2,7 @@ using System.Security.Claims;
using MicCheck.Api.Data; using MicCheck.Api.Data;
using MicCheck.Api.Environments; using MicCheck.Api.Environments;
using MicCheck.Api.Features; using MicCheck.Api.Features;
using MicCheck.Api.Features.Usage;
using MicCheck.Api.Identities; using MicCheck.Api.Identities;
using MicCheck.Api.Projects; using MicCheck.Api.Projects;
using MicCheck.Api.Segments; using MicCheck.Api.Segments;

View File

@@ -1,12 +1,12 @@
using MicCheck.Api.Data; using MicCheck.Api.Data;
using MicCheck.Api.Features; using MicCheck.Api.Features.Usage;
using MicCheck.Api.Tests.Unit.TestSupport; using MicCheck.Api.Tests.Unit.TestSupport;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Caching.Memory;
using Moq; using Moq;
using NUnit.Framework; using NUnit.Framework;
namespace MicCheck.Api.Tests.Unit.Features; namespace MicCheck.Api.Tests.Unit.Features.Usage;
[TestFixture] [TestFixture]
public class FeatureUsageControllerTests public class FeatureUsageControllerTests

View File

@@ -1,9 +1,9 @@
using System.Diagnostics.Metrics; using System.Diagnostics.Metrics;
using MicCheck.Api.Features; using MicCheck.Api.Features.Usage;
using Moq; using Moq;
using NUnit.Framework; using NUnit.Framework;
namespace MicCheck.Api.Tests.Unit.Features; namespace MicCheck.Api.Tests.Unit.Features.Usage;
[TestFixture] [TestFixture]
public class FeatureUsageMetricsTests public class FeatureUsageMetricsTests

View File

@@ -1,10 +1,10 @@
using MicCheck.Api.Data; using MicCheck.Api.Data;
using MicCheck.Api.Features; using MicCheck.Api.Features.Usage;
using MicCheck.Api.Tests.Unit.TestSupport; using MicCheck.Api.Tests.Unit.TestSupport;
using Moq; using Moq;
using NUnit.Framework; using NUnit.Framework;
namespace MicCheck.Api.Tests.Unit.Features; namespace MicCheck.Api.Tests.Unit.Features.Usage;
[TestFixture] [TestFixture]
public class FeatureUsageQueryServiceTests public class FeatureUsageQueryServiceTests

View File

@@ -2,6 +2,7 @@ using System.Security.Claims;
using MicCheck.Api.Data; using MicCheck.Api.Data;
using MicCheck.Api.Environments; using MicCheck.Api.Environments;
using MicCheck.Api.Features; using MicCheck.Api.Features;
using MicCheck.Api.Features.Usage;
using MicCheck.Api.Identities; using MicCheck.Api.Identities;
using MicCheck.Api.Projects; using MicCheck.Api.Projects;
using MicCheck.Api.Segments; using MicCheck.Api.Segments;