// Copyright (c) StellaOps. All rights reserved. // Licensed under BUSL-1.1. See LICENSE in the project root. // Sprint: SPRINT_20260112_004_PLATFORM_setup_wizard_backend (PLATFORM-SETUP-001) // Task: Define setup wizard contracts and step definitions using System.Collections.Generic; using System.Collections.Immutable; using System.Text.Json.Serialization; namespace StellaOps.Platform.WebService.Contracts; #region Enums /// /// Setup wizard step identifiers aligned to docs/setup/setup-wizard-ux.md. /// [JsonConverter(typeof(JsonStringEnumConverter))] public enum SetupStepId { /// Configure PostgreSQL connection. Database = 1, /// Configure Valkey/Redis caching and message queue. Valkey = 2, /// Apply database schema migrations. Migrations = 3, /// Create administrator account. Admin = 4, /// Configure signing keys and crypto profile. Crypto = 5, /// Configure secrets management (optional). Vault = 6, /// Connect source control (optional). Scm = 7, /// Configure advisory data sources (optional). Sources = 8, /// Configure alerts and notifications (optional). Notifications = 9, /// Define deployment environments (optional). Environments = 10, /// Register deployment agents (optional). Agents = 11, /// Configure container registry (optional). Registry = 12, /// Configure OpenTelemetry (optional). Telemetry = 13, /// Configure AI/LLM provider for AdvisoryAI (optional). Llm = 14, /// Configure external settings store (optional). SettingsStore = 15 } /// /// Setup step status aligned to docs/setup/setup-wizard-ux.md. /// [JsonConverter(typeof(JsonStringEnumConverter))] public enum SetupStepStatus { /// Not yet started. Pending, /// Currently active step. Current, /// Completed successfully. Passed, /// Failed validation. Failed, /// Explicitly skipped by user. Skipped, /// Blocked by failed dependency. Blocked } /// /// Overall setup session status. /// [JsonConverter(typeof(JsonStringEnumConverter))] public enum SetupSessionStatus { /// Setup not started. NotStarted, /// Setup in progress. InProgress, /// Setup completed successfully. Completed, /// Setup completed with skipped optional steps. CompletedPartial, /// Setup failed due to required step failure. Failed, /// Setup abandoned by user. Abandoned } /// /// Doctor check status for step validation. /// [JsonConverter(typeof(JsonStringEnumConverter))] public enum SetupCheckStatus { /// Check passed. Pass, /// Check failed. Fail, /// Check produced a warning. Warn, /// Check not executed. NotRun } #endregion #region Step Definitions /// /// Static definition of a setup wizard step. /// public sealed record SetupStepDefinition( SetupStepId Id, string Title, string Subtitle, int OrderIndex, bool IsRequired, ImmutableArray DependsOn, ImmutableArray DoctorChecks); /// /// Provides the canonical setup wizard step definitions. /// public static class SetupStepDefinitions { public static ImmutableArray All { get; } = ImmutableArray.Create( new SetupStepDefinition( Id: SetupStepId.Database, Title: "Database Setup", Subtitle: "Configure PostgreSQL connection", OrderIndex: 1, IsRequired: true, DependsOn: ImmutableArray.Empty, DoctorChecks: ImmutableArray.Create( "check.database.connectivity", "check.database.permissions", "check.database.version")), new SetupStepDefinition( Id: SetupStepId.Valkey, Title: "Valkey/Redis Setup", Subtitle: "Configure caching and message queue", OrderIndex: 2, IsRequired: true, DependsOn: ImmutableArray.Empty, DoctorChecks: ImmutableArray.Create( "check.services.valkey.connectivity")), new SetupStepDefinition( Id: SetupStepId.Migrations, Title: "Database Migrations", Subtitle: "Apply schema updates", OrderIndex: 3, IsRequired: true, DependsOn: ImmutableArray.Create(SetupStepId.Database), DoctorChecks: ImmutableArray.Create( "check.database.migrations.pending")), new SetupStepDefinition( Id: SetupStepId.Admin, Title: "Admin Bootstrap", Subtitle: "Create administrator account", OrderIndex: 4, IsRequired: true, DependsOn: ImmutableArray.Create(SetupStepId.Migrations), DoctorChecks: ImmutableArray.Create( "check.authority.admin.exists")), new SetupStepDefinition( Id: SetupStepId.Crypto, Title: "Crypto Profile", Subtitle: "Configure signing keys", OrderIndex: 5, IsRequired: true, DependsOn: ImmutableArray.Create(SetupStepId.Admin), DoctorChecks: ImmutableArray.Create( "check.crypto.signing.key", "check.crypto.profile")), new SetupStepDefinition( Id: SetupStepId.Vault, Title: "Vault Integration", Subtitle: "Configure secrets management", OrderIndex: 6, IsRequired: false, DependsOn: ImmutableArray.Empty, DoctorChecks: ImmutableArray.Create( "check.security.vault.connectivity")), new SetupStepDefinition( Id: SetupStepId.Scm, Title: "SCM Integration", Subtitle: "Connect source control", OrderIndex: 7, IsRequired: false, DependsOn: ImmutableArray.Empty, DoctorChecks: ImmutableArray.Create( "check.integration.scm.github.auth", "check.integration.scm.gitlab.auth", "check.integration.scm.gitea.auth")), new SetupStepDefinition( Id: SetupStepId.Sources, Title: "Advisory Sources", Subtitle: "Configure CVE/advisory data sources", OrderIndex: 8, IsRequired: false, DependsOn: ImmutableArray.Empty, DoctorChecks: ImmutableArray.Create( "check.sources.mode.configured", "check.sources.nvd.connectivity", "check.sources.ghsa.connectivity")), new SetupStepDefinition( Id: SetupStepId.Notifications, Title: "Notification Channels", Subtitle: "Configure alerts and notifications", OrderIndex: 9, IsRequired: false, DependsOn: ImmutableArray.Empty, DoctorChecks: ImmutableArray.Create( "check.notify.email", "check.notify.slack")), new SetupStepDefinition( Id: SetupStepId.Environments, Title: "Environment Definition", Subtitle: "Define deployment environments", OrderIndex: 10, IsRequired: false, DependsOn: ImmutableArray.Create(SetupStepId.Admin), DoctorChecks: ImmutableArray.Empty), new SetupStepDefinition( Id: SetupStepId.Agents, Title: "Agent Registration", Subtitle: "Register deployment agents", OrderIndex: 11, IsRequired: false, DependsOn: ImmutableArray.Create(SetupStepId.Environments), DoctorChecks: ImmutableArray.Empty), new SetupStepDefinition( Id: SetupStepId.Registry, Title: "Container Registry", Subtitle: "Configure container registry connections", OrderIndex: 12, IsRequired: false, DependsOn: ImmutableArray.Empty, DoctorChecks: ImmutableArray.Create( "check.integration.registry.connectivity", "check.integration.registry.auth")), new SetupStepDefinition( Id: SetupStepId.Telemetry, Title: "Telemetry Setup", Subtitle: "Configure OpenTelemetry for observability", OrderIndex: 13, IsRequired: false, DependsOn: ImmutableArray.Empty, DoctorChecks: ImmutableArray.Create( "check.telemetry.otlp.connectivity")), new SetupStepDefinition( Id: SetupStepId.Llm, Title: "AdvisoryAI Provider", Subtitle: "Configure AI/LLM provider for intelligent triage", OrderIndex: 14, IsRequired: false, DependsOn: ImmutableArray.Empty, DoctorChecks: ImmutableArray.Create( "check.llm.provider.connectivity", "check.llm.model.available")), new SetupStepDefinition( Id: SetupStepId.SettingsStore, Title: "Settings Store", Subtitle: "Configure external configuration store", OrderIndex: 15, IsRequired: false, DependsOn: ImmutableArray.Empty, DoctorChecks: ImmutableArray.Create( "check.settingsstore.connectivity")) ); /// /// Gets a step definition by ID. /// public static SetupStepDefinition? GetById(SetupStepId id) { foreach (var step in All) { if (step.Id == id) return step; } return null; } } #endregion #region Session State /// /// Setup wizard session state. /// public sealed record SetupSession( string SessionId, string TenantId, SetupSessionStatus Status, ImmutableArray Steps, string CreatedAtUtc, string UpdatedAtUtc, string? CreatedBy, string? UpdatedBy, string? DataAsOfUtc); /// /// State of a single setup step within a session. /// public sealed record SetupStepState( SetupStepId StepId, SetupStepStatus Status, string? CompletedAtUtc, string? SkippedAtUtc, string? SkippedReason, ImmutableArray CheckResults, string? ErrorMessage); /// /// Result of a Doctor check during step validation. /// public sealed record SetupCheckResult( string CheckId, SetupCheckStatus Status, string? Message, string? SuggestedFix); #endregion #region API Requests /// /// Request to create a new setup session. /// public sealed record CreateSetupSessionRequest( string? TenantId = null); /// /// Request to execute a setup step. /// public sealed record ExecuteSetupStepRequest( SetupStepId StepId, ImmutableDictionary? Configuration = null); /// /// Request to skip a setup step. /// public sealed record SkipSetupStepRequest( SetupStepId StepId, string? Reason = null); /// /// Request to finalize a setup session. /// public sealed record FinalizeSetupSessionRequest( bool Force = false); /// /// Request to test connectivity for a setup step. /// public sealed record SetupTestConnectionRequest( Dictionary? ConfigValues = null); #endregion #region API Responses /// /// Response for setup session operations. /// public sealed record SetupSessionResponse( SetupSession Session); /// /// Response for step execution. /// public sealed record ExecuteSetupStepResponse( SetupStepState StepState, bool Success, string? ErrorMessage, ImmutableArray SuggestedFixes); /// /// Response listing all step definitions. /// public sealed record SetupStepDefinitionsResponse( ImmutableArray Steps); /// /// A suggested fix for a failed step. /// public sealed record SetupSuggestedFix( string Title, string Description, string? Command, string? DocumentationUrl); /// /// Response for session finalization. /// public sealed record FinalizeSetupSessionResponse( SetupSessionStatus FinalStatus, ImmutableArray CompletedSteps, ImmutableArray SkippedSteps, ImmutableArray FailedSteps, string? ReportPath); #endregion