using GB5Shared.DTO.Framework.Login; namespace EntitlementBLL.Onboarding; /// /// Calls SqlWorkbench's real HTTP endpoints (ClientDatabase.svc, ChangeRequest.svc) to /// provision a new client's physical database. Entitlement never references SwDAL/SwBLL /// directly — no precedent anywhere in this repo for one module's BLL reaching into another /// module's project (confirmed: PAY -> Sales/Finance is the only existing cross-module /// pattern, and it goes over a named HttpClient, not a shared assembly). /// public interface ISqlWorkbenchClient { /// POST /ClientDatabase/SaveClientDatabase — creates the MSWCLIENTDATABASE row /// a ClientProvisioning ChangeRequest will provision. Returns the new ClientDbId. Task SaveClientDatabaseAsync(SwSaveClientDatabaseRequest req, LoginDTO swLogin, CancellationToken ct); /// POST /ChangeRequest/SaveChangeRequest (Draft) — returns the new ChangeRequestId. Task SaveChangeRequestAsync(SwSaveChangeRequestRequest req, LoginDTO swLogin, CancellationToken ct); /// PUT /ChangeRequest/SubmitChangeRequest — Draft -> Submitted. Task SubmitChangeRequestAsync(int changeRequestId, LoginDTO swLogin, CancellationToken ct); /// PUT /ChangeRequest/ApproveChangeRequest — Submitted -> Approved. Only called /// in OnboardingApprovalMode.AutoApprove; HumanApprove mode never calls this. Task ApproveChangeRequestAsync(int changeRequestId, string? comment, LoginDTO swLogin, CancellationToken ct); /// POST /ChangeRequest/ExecuteChangeRequest — Approved -> Executed. Only called /// in OnboardingApprovalMode.AutoApprove, immediately after ApproveChangeRequestAsync, so /// the completion path (the "sqlworkbench.changerequest.executed" Dapr event -> /// ResumeAfterProvisioningExecutedAsync) is identical regardless of approval mode — the /// only difference is who calls Approve/Execute, not how completion is detected. Task ExecuteChangeRequestAsync(int changeRequestId, LoginDTO swLogin, CancellationToken ct); /// POST /ChangeRequest/QueueChangeRequestExecution — Approved CR is queued for /// SqlWorkbench's own background ChangeRequestExecutionWorkerJob instead of run inline on /// this HTTP request (tracker §37/§43). Returns immediately; completion is detected the same /// way as the AutoApprove/inline path — via the "sqlworkbench.changerequest.executed" Dapr /// event (fired on success AND on failure) plus GetChangeRequestStatusAsync's own live /// re-check. Used instead of ExecuteChangeRequestAsync so a large baseline-package batch is /// never tied to this request's own CancellationToken (§36.13's own proven failure mode). Task QueueChangeRequestExecutionAsync(int changeRequestId, LoginDTO swLogin, CancellationToken ct); /// POST /Provisioning/ProvisionClientDatabase — reapplies an already-Approved/ /// Released package's scripts to an already-existing client database (tracker §49, Demo /// pooled-instance reset). Idempotent (§36's own INSERT...WHERE NOT EXISTS scripts) but does /// NOT clear any occupant-written mutable-table data first. Task ReapplyUpgradePackageAsync(int clientDbId, int upgradePackageId, LoginDTO swLogin, CancellationToken ct); /// GET /ChangeRequest/GetChangeRequestById — used by /// ResumeAfterProvisioningExecutedAsync to confirm CrStatus == Executed before /// continuing, rather than trusting the Dapr event payload's exact shape. Task GetChangeRequestStatusAsync(int changeRequestId, LoginDTO swLogin, CancellationToken ct); /// POST /UpgradePackage/GetProvisioningChain — resolves the DbModel's real, /// ordered set of Released packages (Universal plus any matching the scope filter), /// collapsed to the latest version per supersession chain. Empty list (not an error) /// means no packages are registered for this DbModel yet. Task> GetProvisioningChainAsync( int dbModelId, SwPackageScopeFilterRequest? scope, LoginDTO swLogin, CancellationToken ct); /// GET /ClientDatabase/GetClientDatabaseById — a plain read, already-existing /// SqlWorkbench endpoint. Used (tracker §49 Decision 8's corrected design) to resolve a /// pooled demo instance's own DatabaseName/ServerConfigId so Entitlement can build a LoginDTO /// pointed directly at it and call the real IClientUserProvisioner.ProvisionAsync function — /// never a raw table-level INSERT via a bespoke SqlWorkbench endpoint. Task GetClientDatabaseAsync(int clientDbId, LoginDTO swLogin, CancellationToken ct); }