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);
}