namespace EntitlementDAL.DTOs; /// Request to onboard a brand-new client end-to-end: identity + a submitted /// SqlWorkbench database-provisioning ChangeRequest. Internal-staff-only. public class OnboardClientRequestDTO { public string ClientCode { get; set; } = string.Empty; public string ClientName { get; set; } = string.Empty; public string ClientShortName { get; set; } = string.Empty; public string AdminUserCode { get; set; } = string.Empty; public string AdminUserName { get; set; } = string.Empty; public string AdminEmail { get; set; } = string.Empty; public string AdminMobile { get; set; } = string.Empty; public int PlanId { get; set; } public string? IdmsEngagementRef { get; set; } // Legal/Contract Agreement Consent jurisdiction resolution (tracker §51.12) — optional, no // validation. Threaded onto MCLIENT.JurisdictionCode at creation time (§ClientProvisioningBLL); // ignored entirely when ExistingClientId/ExistingUserId reuse an already-registered identity. public string? JurisdictionCode { get; set; } /// 0=NotTrial 1=WithSampleData 2=Blank — mirrors MPROVISIONINGJOB.TRIALMODE /// (ProvisioningJobDTO.TrialMode). Defaults to 0 so OnboardClient's existing /// internal-staff callers are unaffected; StartSelfServiceTrialAsync sets this to 2 /// (Blank) since no sample-data seeding exists yet (Thread 3, still unscoped). public byte TrialMode { get; set; } /// Tracker §49 Decision 9 — when both this and ExistingUserId are set (> 0), Step 1 /// skips IClientProvisioningBLL.CreateClientAsync entirely and reuses this already-registered /// identity instead of creating a fresh one. Used by Dedicated-mode demo sessions, which build /// their real physical-DB provisioning on top of the SAME central MCLIENT/MUSER account a /// lightweight prior registration call already created (DemoSessionBLL.RegisterProspectAsync) /// — never a second, duplicate identity for the same prospect. Every other existing caller /// (OnboardClient, StartSelfServiceTrialAsync) leaves this null/0, so their behavior is /// completely unchanged. public int? ExistingClientId { get; set; } public int? ExistingUserId { get; set; } // Tracker §52 — BYOC/On-Prem purchase gating. Defaults to 0/SaaS. OnboardClient.cs's own SL // endpoint enforces a SEPARATE, narrower "entdeploy" MenuRights check before letting a // caller set this to anything else — an ordinary entonbrd grant is not, on its own, enough // to commit to standing up dedicated/BYOC infrastructure for a client. This field only ever // reaches a non-zero value via that one endpoint — StartSelfServiceTrialAsync and // DemoSessionBLL's own internal construction of this DTO never set it, so Trial/Demo // structurally can never become anything but SaaS, regardless of this field's existence. public byte DeploymentType { get; set; } // Tracker §52 — internal "on behalf of a prospect" flow: the sales/CS exec fills in the // real client details themselves, but this optionally links back to the CRM TLEAD row that // prompted the purchase (Direction B, mirroring Demo's own already-built OwnerUserId/LeadId // pattern, tracker §49 Decision 8). Real FK -> TLEAD.LeadId; null = no lead. public int? LeadId { get; set; } } /// What StartOnboardingAsync can return synchronously — identity + the fact that DB /// provisioning is now in flight. The temporary password is the one and only place it's ever /// visible (see CreateClientResultDTO). Subscription creation and reference-data sync happen /// later, asynchronously, once the submitted ChangeRequest reaches Executed — check /// ProvisioningJobId's JobStatus/CurrentStep for that. public class OnboardClientResultDTO { public int ClientId { get; set; } public int UserId { get; set; } public string TemporaryPassword { get; set; } = string.Empty; public int ProvisioningJobId { get; set; } public int SwChangeRequestId { get; set; } public int SwClientDatabaseId { get; set; } public string Message { get; set; } = string.Empty; } /// Public, anonymous self-service trial signup (QuickStart Step 4's real backend — /// closes the gap step4.component.ts's own doc comment flags as an "HONEST LEAD-CAPTURE STUB"). /// Deliberately narrower than OnboardClientRequestDTO: no ClientCode/AdminUserCode/PlanId from /// the caller. Codes are derived server-side by StartSelfServiceTrialAsync (so a visitor can't /// spoof/collide with another client's code) and PlanId is fixed to the configured self-serve /// trial plan (OnboardingOptions.DefaultTrialPlanId) — an anonymous caller must never be able to /// request an arbitrary paid plan tier for free. public class SelfProvisionTrialRequestDTO { public string CompanyName { get; set; } = string.Empty; public string ContactName { get; set; } = string.Empty; public string Email { get; set; } = string.Empty; public string Mobile { get; set; } = string.Empty; // Legal/Contract Agreement Consent jurisdiction resolution (tracker §51.12) — optional. public string? JurisdictionCode { get; set; } // Legal/Contract Agreement Consent (tracker §50/§51) — the exact AgreementVersionIds the // caller was shown (via Legal/GetApplicableAgreements) and that this visitor ticked/clicked // to accept, e.g. the placeholder TOS+PrivacyPolicy bundle seeded by // 20260904_Entitlement_Agreement_PlaceholderContent_Seed. Optional/empty is tolerated (no // acceptance recorded, nothing blocked) so this stays wireable before real content exists — // once real content is Published, a real caller is expected to always supply this. public int[] AcceptedAgreementVersionIds { get; set; } = Array.Empty(); } /// What a self-service trial signup gets back — deliberately narrower than /// OnboardClientResultDTO: no SwChangeRequestId/SwClientDatabaseId (internal SqlWorkbench /// plumbing, meaningless and needlessly revealing to an anonymous caller). ProvisioningJobId + /// the Email just submitted are the pair GetTrialProvisioningStatusAsync needs to poll progress. /// TemporaryPassword is shown here once, same convention as CreateClientAdmin/OnboardClient — /// this self-service path has no staff member to relay it out-of-band, so the visitor's own /// confirmation screen is the only place it is ever surfaced. public class SelfProvisionTrialResultDTO { public int ClientId { get; set; } public int ProvisioningJobId { get; set; } public string TemporaryPassword { get; set; } = string.Empty; public string Message { get; set; } = string.Empty; } /// Anonymous-safe provisioning-status projection for a self-service trial signup — /// only what a visitor needs to render a progress screen, never LastError's raw internal text /// or any SqlWorkbench-internal ID. public class TrialProvisioningStatusDTO { public byte JobStatus { get; set; } // 0=Queued 1=Running 2=Completed 3=Failed 4=PartialFail public string CurrentStep { get; set; } = string.Empty; public bool HasError { get; set; } }