// 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