namespace Campaign_Tracker.Server.LegacyData.Schema; /// /// Release-gate entry point (Story 1.7 AC #4). /// /// Invoked from Program.cs when the application is launched with the /// --check-legacy-schema argument. Builds the host, runs the /// compatibility check synchronously, prints a structured report, and returns /// an exit code: 0 when the schema matches the baseline, non-zero (1) /// when drift is detected. The CI/CD pipeline blocks releases on the non-zero /// exit code. /// public static class LegacySchemaReleaseGate { public const string CommandLineFlag = "--check-legacy-schema"; public const int ExitCodePass = 0; public const int ExitCodeFail = 1; public static bool ShouldRun(string[] args) => args.Any(a => string.Equals(a, CommandLineFlag, StringComparison.Ordinal)); public static async Task ExecuteAsync( ILegacySchemaCompatibilityCheck check, ILegacySchemaCheckHistory history, TextWriter output, CancellationToken cancellationToken = default) { var result = await check.RunAsync(cancellationToken).ConfigureAwait(false); history.Record(result); WriteReport(result, output); return result.Passed ? ExitCodePass : ExitCodeFail; } public static void WriteReport(LegacySchemaCheckResult result, TextWriter output) { if (result.Passed) { output.WriteLine( $"[legacy-schema-check] PASS — {result.TablesVerified} tables verified at {result.CheckedAt:O}, drift=0."); return; } output.WriteLine( $"[legacy-schema-check] FAIL — {result.TablesVerified} tables verified at {result.CheckedAt:O}, drift={result.DriftCount}."); foreach (var drift in result.Drifts) { var location = drift.ColumnName is null ? drift.TableName : $"{drift.TableName}.{drift.ColumnName}"; output.WriteLine($" - [{drift.ChangeType}] {location}: {drift.Detail}"); } } }