VEU.WathBody/3-app/2-cli/Server.WatchBody.Web/WebAppStartup.cs

79 lines
4.1 KiB
C#

using Kit.Helpers.SqlHelperAbstract;
using Microsoft.AspNetCore.Http.Json;
using Server.WatchBody.Core.Dal.Ref.Repository;
using Server.WatchBody.Core.Dal.Src.Repository;
using Server.WatchBody.Web.Config;
using Server.WatchBody.Web.Db;
using Server.WatchBody.Web.Middleware;
using Server.WatchBody.Web.Services;
namespace Server.WatchBody.Web;
/// <summary>
/// Сборка приложения (общая для Program и интеграционных тестов):
/// probe БД, bootstrap атлетов, DI, middleware и fluent-таблица
/// маршрутов (Kit.Helpers.Routes — Config\RouteConfig.cs).
/// </summary>
public static class WebAppStartup
{
/// <summary>Тест подключения к БД — фатален при неудаче (spec 01).</summary>
public static void ProbeDatabase(IConnectionString connectionString)
{
// через хранимую функцию: сырой SQL во fluent Kit.Helpers не передают
new MigrationRepository(connectionString).Select("000_probe");
}
public static WebApplication Build(WebApplicationBuilder builder, ServerConfig config, IConnectionString cs)
{
builder.Services.AddSingleton<IConnectionString>(cs);
builder.Services.AddSingleton<IAthleteRepository, AthleteRepository>();
builder.Services.AddSingleton<IAthleteProfileRepository, AthleteProfileRepository>();
builder.Services.AddSingleton<IExerciseRepository, ExerciseRepository>();
builder.Services.AddSingleton<IExerciseGroupRepository, ExerciseGroupRepository>();
builder.Services.AddSingleton<IProgramRepository, ProgramRepository>();
builder.Services.AddSingleton<IProgramVersionRepository, ProgramVersionRepository>();
builder.Services.AddSingleton<IWorkoutRepository, WorkoutRepository>();
builder.Services.AddSingleton<IWorkoutSetRepository, WorkoutSetRepository>();
builder.Services.AddSingleton<ICommandLogRepository, CommandLogRepository>();
builder.Services.AddSingleton<IDailyLogRepository, DailyLogRepository>();
builder.Services.AddSingleton<IWorkoutMetricsRepository, WorkoutMetricsRepository>();
builder.Services.AddSingleton<IBreakRepository, BreakRepository>();
builder.Services.AddSingleton(config.Safety);
builder.Services.AddSingleton<Core.Programs.ProgramStore>();
builder.Services.AddSingleton<Core.Metrics.MetricsEngine>();
builder.Services.AddSingleton(config.Progression);
builder.Services.AddSingleton<Core.Programs.ProgressionRules>();
builder.Services.AddSingleton<Core.Programs.BreakEngine>();
builder.Services.AddSingleton<SyncService>();
builder.Services.AddSingleton(new Services.AdminAuthService(
config.AdminLogin, config.AdminPasswordHash));
builder.Services.AddSingleton<Services.PlanSummaryService>();
builder.Services.AddControllersWithViews(o => { o.EnableEndpointRouting = false; })
// контроллеры живут в сборке Web — при хостинге из тестов входная
// сборка другая, часть нужно указать явно
.AddApplicationPart(typeof(WebAppStartup).Assembly)
.AddJsonOptions(o =>
{
o.JsonSerializerOptions.PropertyNamingPolicy = System.Text.Json.JsonNamingPolicy.CamelCase;
o.JsonSerializerOptions.DefaultIgnoreCondition =
System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull;
});
var app = builder.Build();
app.UseMiddleware<ApiKeyMiddleware>();
app.UseDefaultFiles(new DefaultFilesOptions { DefaultFileNames = { "admin/index.html" } });
app.UseStaticFiles();
app.UseRouting();
app.UseMvc(routes => RouteConfig.Configure(routes));
return app;
}
/// <summary>Инициализация: probe БД + bootstrap атлетов (до старта Kestrel).</summary>
public static void Initialize(IConnectionString cs, ServerConfig config)
{
ProbeDatabase(cs);
AthleteBootstrap.Sync(cs, config.Athletes);
}
}