CUB-30: Implement PUT /filaments/{id} update endpoint

- Add FluentValidation validators for CreateFilamentRequest and UpdateFilamentRequest
  with comprehensive validation rules (required fields, string lengths, hex color format,
  weight constraints including WeightRemainingGrams <= WeightTotalGrams, purchase price range)
- Add FluentValidationFilter action filter that auto-runs FluentValidation validators
  for all API controller actions before execution, returning 400 with structured error details
- Register FluentValidationFilter in DI and add it to MVC controller filters in Program.cs
- PUT endpoint was already implemented in FilamentsController with proper validation,
  404 handling, FK existence checks, serial uniqueness check, and weight constraint check
- This change ensures FluentValidation rules are enforced consistently via the pipeline
This commit is contained in:
cubecraft-agents[bot]
2026-04-26 13:26:26 +00:00
parent 230c3b295d
commit 9cd27e213b
3 changed files with 186 additions and 1 deletions

View File

@@ -1,4 +1,5 @@
using System.Reflection;
using Extrudex.API.Filters;
using Extrudex.API.Hubs;
using Extrudex.Domain.Interfaces;
using Extrudex.Infrastructure.Data;
@@ -23,7 +24,10 @@ builder.Services.AddDbContext<ExtrudexDbContext>(options =>
options.UseNpgsql(connectionString));
// ── API Services ───────────────────────────────────────────
builder.Services.AddControllers();
builder.Services.AddControllers(options =>
{
options.Filters.AddService<FluentValidationFilter>();
});
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c =>
{
@@ -50,6 +54,10 @@ builder.Services.AddSingleton<IQrCodeService, QrCodeService>();
// Registers all validators from the API assembly into DI.
builder.Services.AddValidatorsFromAssembly(Assembly.GetExecutingAssembly());
// Register the FluentValidation action filter so validators run automatically
// on all API controller actions before the action executes.
builder.Services.AddScoped<FluentValidationFilter>();
// ── CORS (kiosk + remote browser) ─────────────────────────
// AllowAnyOrigin disallows credentials by spec; this is fine for
// REST API calls. SignalR WebSockets negotiate without credentials