using Server.WatchBody.Web; using Server.WatchBody.Web.Config; using Server.WatchBody.Web.Db; using Server.WatchBody.Web.Services; // Точка входа сервера (m02; режимы — requirements 2.3, З-36): // --mode serve REST API (по умолчанию) // --mode migrate применение 2-db\migrations\ по журналу src.migration // --config путь к appsettings (иначе WATCHBODY_APPSETTINGS либо // appsettings.json рядом с исполняемым файлом) // Валидация конфига — фатальна: лог + stderr, код возврата 1; // migrate: успех — 0, сбой — 1. string? mode = null, configArg = null; for (var i = 0; i < args.Length - 1; i++) { switch (args[i]) { case "--mode": mode = args[i + 1]; break; case "--config": configArg = args[i + 1]; break; } } mode ??= "serve"; var configPath = configArg ?? Environment.GetEnvironmentVariable("WATCHBODY_APPSETTINGS") ?? Path.Combine(AppContext.BaseDirectory, "appsettings.json"); ServerConfig config; try { config = ServerConfig.Load(configPath); } catch (Exception e) { Console.Error.WriteLine($"конфиг {configPath} не читается: {e.Message}"); return 1; } if (mode == "migrate") { try { var applied = new MigrationRunner( new PostgresConnectionString(config.DbConnectionString)).Apply(config.MigrationsDir); Console.WriteLine($"migrate: применено миграций — {applied}"); return 0; } catch (Exception e) { Console.Error.WriteLine($"migrate: сбой — {e.Message}"); return 1; } } if (mode != "serve") { Console.Error.WriteLine($"неизвестный режим '{mode}' (serve|migrate)"); return 1; } var errors = config.Validate(); if (errors.Count > 0) { foreach (var error in errors) Console.Error.WriteLine($"конфиг: {error}"); return 1; } var connectionString = new PostgresConnectionString(config.DbConnectionString); try { WebAppStartup.Initialize(connectionString, config); } catch (Exception e) { Console.Error.WriteLine($"инициализация не удалась: {e.Message}"); return 1; } var builder = WebApplication.CreateBuilder(args); var app = WebAppStartup.Build(builder, config, connectionString); app.Run(); return 0; public partial class Program;