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