using AVSCartonShipmentVerifier.Configuration; using AVSCartonShipmentVerifier.Data; using AVSCartonShipmentVerifier.Hosting; using AVSCartonShipmentVerifier.Repositories; using AVSCartonShipmentVerifier.ScanHistory; using AVSCartonShipmentVerifier.Services; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.FileProviders; var builder = WebApplication.CreateBuilder(args); builder.Configuration.AddJsonFile("appsettings.Local.json", optional: true, reloadOnChange: true); builder.Services .AddOptions() .Bind(builder.Configuration.GetSection(CartonVerificationOptions.SectionName)) .ValidateDataAnnotations() .ValidateOnStart(); builder.Services .AddOptions() .Bind(builder.Configuration.GetSection(ScanHistoryOptions.SectionName)) .ValidateDataAnnotations() .ValidateOnStart(); builder.Services .AddOptions() .Bind(builder.Configuration.GetSection(DesktopHostOptions.SectionName)); builder.Services.AddHostedService(); builder.Services.AddControllersWithViews(); builder.Services.AddDbContext((serviceProvider, options) => { var scanHistoryOptions = serviceProvider.GetRequiredService>().Value; var connectionString = ScanHistoryPath.EnsureDirectoryAndGetConnectionString(scanHistoryOptions); options.UseSqlite(connectionString); }); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); var app = builder.Build(); using (var scope = app.Services.CreateScope()) { var db = scope.ServiceProvider.GetRequiredService(); db.Database.EnsureCreated(); // EnsureCreated does not add new tables to an existing SQLite file; create rejected-scan storage explicitly. db.Database.ExecuteSqlRaw( """ CREATE TABLE IF NOT EXISTS rejected_scan_entries ( Id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, RawInputValue TEXT NOT NULL, ModelNumber TEXT NOT NULL, UniqueNumber TEXT NOT NULL, RejectionReason TEXT NOT NULL, ProcessedAtUtc TEXT NOT NULL ); """); db.Database.ExecuteSqlRaw( """ CREATE INDEX IF NOT EXISTS IX_rejected_scan_entries_ProcessedAtUtc ON rejected_scan_entries (ProcessedAtUtc); """); } if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Home/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthorization(); app.UseStaticFiles(new StaticFileOptions { FileProvider = new PhysicalFileProvider(Path.Combine(builder.Environment.ContentRootPath, "Resources")), RequestPath = "/resources" }); app.MapStaticAssets(); app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}") .WithStaticAssets(); app.Run();