Remove FluentValidation dependency, use plain .NET validation

Replace AbstractValidator-based request validators with a small
IModelValidator<T>/ValidationResult pattern (ported from BuyEngine's
Common namespace), wired into the MVC pipeline via a
ModelValidationActionFilter so controllers and response shape are
unaffected. Also copy over the Guard precondition helper.
This commit is contained in:
2026-07-05 21:57:35 -07:00
parent 127aefc020
commit bdc85a1f3a
23 changed files with 361 additions and 130 deletions

View File

@@ -23,13 +23,7 @@ public class FeatureService(IMicCheckDbContext db, AuditService auditService, We
return await db.Features.Include(f => f.Tags).FirstOrDefaultAsync(f => f.Id == id, ct);
}
public async Task<Feature> CreateAsync(
int projectId,
string name,
FeatureType type,
string? initialValue,
string? description,
CancellationToken ct = default)
public async Task<Feature> CreateAsync(int projectId, string name, FeatureType type, string? initialValue, string? description, CancellationToken ct = default)
{
var count = await db.Features.CountAsync(f => f.ProjectId == projectId, ct);
if (count >= MaxFeaturesPerProject)
@@ -78,8 +72,7 @@ public class FeatureService(IMicCheckDbContext db, AuditService auditService, We
return feature;
}
public async Task<Feature> UpdateAsync(
int id, string name, string? description, CancellationToken ct = default)
public async Task<Feature> UpdateAsync(int id, string name, string? description, CancellationToken ct = default)
{
var feature = await db.Features.Include(f => f.Tags).FirstOrDefaultAsync(f => f.Id == id, ct)
?? throw new KeyNotFoundException($"Feature {id} not found.");
@@ -162,11 +155,7 @@ public class FeatureService(IMicCheckDbContext db, AuditService auditService, We
EventType = WebhookEventTypes.FlagDeleted,
EnvironmentId = env.Id,
OrganizationId = project.OrganizationId,
Data = new FlagDeletedData(
null,
DateTimeOffset.UtcNow,
new FeatureSummary(feature.Id, feature.Name))
});
Data = new FlagDeletedData(null, DateTimeOffset.UtcNow, new FeatureSummary(feature.Id, feature.Name)) });
}
}
}