using ControlPlane.Core.Models; namespace ControlPlane.Core.Interfaces; /// /// Mutable context bag passed through every saga step. /// Steps read inputs and write outputs here so downstream steps can consume them. /// public class SagaContext { public ProvisioningJob Job { get; init; } = default!; // Written by DatabaseStep — connection string for the tenant's Postgres (shared or own) public string? TenantConnectionString { get; set; } public string? TenantStackName { get; set; } // Written by KeycloakStep public string? DayZeroUserSubjectId { get; set; } public string? MagicLink { get; set; } // Written by LaunchStep or PulumiStep — base URL for the provisioned tenant public string? TenantApiBaseUrl { get; set; } // Written by LaunchStep — primary app container name public string? ContainerName { get; set; } // Written by PulumiStep (DedicatedVM/Enterprise tier) — target host details for subsequent steps public string? VmIpAddress { get; set; } public string? VmSshKeyPath { get; set; } /// /// Per-component resolved endpoints for this provisioning job. /// Keyed by component name: "Keycloak", "Vault", "Postgres", "Minio". /// Built by ProvisioningWorker before the saga starts; OwnContainer host ports /// are resolved and written back by InfrastructureProvisioningStep. /// public Dictionary ResolvedTopology { get; init; } = new(StringComparer.OrdinalIgnoreCase); /// /// Absolute path to the generated docker-compose.yml for this tenant. /// Non-null only for OwnContainer tenants. /// public string? ComposeFilePath { get; set; } }