using Microsoft.EntityFrameworkCore; using NoticeBoard.Data; var builder = WebApplication.CreateBuilder(args); // SQLite database in app directory var dbPath = Path.Combine(builder.Environment.ContentRootPath, "noticeboard.db"); builder.Services.AddDbContext(options => options.UseSqlite($"Data Source={dbPath}")); builder.Services.AddControllersWithViews(); builder.Services.AddHttpClient(); var app = builder.Build(); // Auto-create database on startup (use Migrate() if using EF migrations) using (var scope = app.Services.CreateScope()) { var db = scope.ServiceProvider.GetRequiredService(); db.Database.EnsureCreated(); } if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/error"); app.UseHsts(); } app.UseStaticFiles(); app.UseRouting(); // Ensure uploads directory exists var uploadsPath = Path.Combine(app.Environment.WebRootPath, "uploads"); if (!Directory.Exists(uploadsPath)) Directory.CreateDirectory(uploadsPath); app.MapControllerRoute( name: "admin", pattern: "admin/{action=Index}/{id?}", defaults: new { controller = "Admin" }); app.MapControllerRoute( name: "slides", pattern: "admin/slides/{action=Index}/{id?}", defaults: new { controller = "Slides" }); app.MapControllerRoute( name: "devices", pattern: "admin/devices/{action=Index}/{id?}", defaults: new { controller = "Devices" }); app.MapControllerRoute( name: "api", pattern: "api/{action}/{id?}", defaults: new { controller = "Api" }); // Display route: /{slug} — must be last to act as catch-all app.MapControllerRoute( name: "display", pattern: "d/{slug}", defaults: new { controller = "Display", action = "Show" }); // Also support root-level slugs app.MapControllerRoute( name: "display-root", pattern: "{slug}", defaults: new { controller = "Display", action = "Show" }, constraints: new { slug = new NoticeBoard.Routing.DeviceSlugConstraint() }); // Default route goes to admin app.MapControllerRoute( name: "default", pattern: "", defaults: new { controller = "Admin", action = "Index" }); app.Run();