using EntitlementDAL.DTOs; namespace EntitlementBLL.Onboarding; /// /// Chains the three pieces Thread 6/§31 proved individually working (client identity /// creation, SqlWorkbench's ChangeRequest-governed database provisioning, and a /// FrameworkSL reference-data sync job) into one real onboarding flow. Routes DB creation /// through SqlWorkbench's existing Draft->Submit->Approve->Execute governance rather than /// bypassing it — a ClientProvisioning ChangeRequest is still reviewable/auditable exactly /// like any other SqlWorkbench change. /// public interface IClientOnboardingOrchestratorBLL { /// Step 1 (synchronous): create the client's identity (MCLIENT/MUSER), then /// submit (and, in AutoApprove mode, approve + execute) a ClientProvisioning /// ChangeRequest for its database. Returns once the CR is submitted — it does NOT wait /// for Executed; see ResumeAfterProvisioningExecutedAsync for the rest. Task StartOnboardingAsync(OnboardClientRequestDTO req, CancellationToken ct); /// QuickStart Step 4's real, public entrypoint — closes the "demo access for new /// registered users" gap. An anonymous visitor cannot call StartOnboardingAsync/OnboardClient /// directly (internal-staff-only, [MenuRights]-gated) and must never be able to choose their /// own ClientCode/AdminUserCode/PlanId, so this derives codes server-side, fixes PlanId to /// the configured self-serve trial plan (OnboardingOptions.DefaultTrialPlanId), and then /// delegates to StartOnboardingAsync — same identity+DB-provisioning pipeline, same /// governance, no duplicated logic. Retries a generated ClientCode a bounded number of times /// on a genuine collision. Task StartSelfServiceTrialAsync(SelfProvisionTrialRequestDTO req, CancellationToken ct); /// Anonymous-safe status poll for a self-service trial signup. Requires both /// ProvisioningJobId and the Email originally submitted — ProvisioningJobId alone is a /// sequential, guessable integer, so Email acts as a lightweight shared secret only the /// real visitor would know. Returns null if the pair doesn't match any job. Task GetTrialProvisioningStatusAsync(int provisioningJobId, string email, CancellationToken ct); /// Internal-staff status poll for ANY provisioning job (OnboardClient/SelfProvisionTrial/ /// Demo Dedicated sessions alike) — unlike GetTrialProvisioningStatusAsync above, no email /// shared-secret is needed here since the caller is already [MenuRights]-authenticated, not /// anonymous. Tracker §52.2. Task GetProvisioningJobByIdAsync(int provisioningJobId, CancellationToken ct); /// Step 2 (async, event-driven): called by ClientProvisioningExecutedSubscriber /// whenever ANY ClientProvisioning ChangeRequest reaches Executed. Re-verifies status by /// calling SqlWorkbench directly (never trusts the Dapr event payload's exact shape — /// EventLogPublish's own double-JSON-encoded envelope makes that fragile to parse /// reliably) against every job still waiting on one, then creates the subscription and /// (if configured) triggers the reference-data sync job for each one whose CR is now /// genuinely Executed. Task ResumeAfterProvisioningExecutedAsync(CancellationToken ct); /// Tracker §37 Decision 2: called by ClientProvisioningProgressSubscriber on each /// "sqlworkbench.changerequest.progress" wake-up. Re-reads real ScriptsDone/ScriptsTotal for /// every job still waiting on a ClientProvisioning ChangeRequest and pushes it over /// ProvisioningHub — a no-op if no hub is registered. Never touches MPROVISIONINGJOB itself; /// purely a best-effort real-time UI layer on top of the already-persisted job state. Task PushDdlProgressForAwaitingJobsAsync(CancellationToken ct); }