using EntitlementBLL.Demo; using EntitlementSL.Common; using FastEndpoints; using GB5Shared.DTO.Framework.Login; using GB5Shared.DTO.Framework.ResponseStandard; using GB5Shared.FastEndPoint; using static GB5Shared.GB5Constant.Constant; namespace EntitlementSL.Endpoints.Demo; // Genuinely public/anonymous โ€” the landing-page "request a demo" form's real backend (tracker // ยง49 Decision 9). Deliberately NOT [MenuRights]-gated, same reasoning as // Onboarding/SelfProvisionTrial.cs: this is meant to be called by an unauthenticated website // visitor, not staff. Reuses that same endpoint's rate-limit policy rather than a new one โ€” both // are genuinely public actions that each create a real MCLIENT/MUSER row, so they share the // identical abuse shape (a bot spamming account creation). public class RegisterProspect : BaseEndpoint> { private readonly IDemoSessionBLL _DemoSessionBLL; public RegisterProspect(IDemoSessionBLL demoSessionBLL) => _DemoSessionBLL = demoSessionBLL; public override void Configure() { Post("/Demo/RegisterProspect"); AllowAnonymous(); Options(x => x.RequireRateLimiting(ClientAuthRateLimitPolicies.SelfProvisionTrial)); } public record Params( [property: FromHeader] string Login, [property: FromBody] RegisterDemoProspectRequest RegisterDemoProspectRequest ); /// NOT_REQUIRED โ€” a one-time creation action, never cached. protected override string? GetCacheKey(Params req, LoginDTO loginDTO) => null; protected override async Task> ExecuteAsync(Params req, LoginDTO loginDTO, CancellationToken ct) { var result = await _DemoSessionBLL.RegisterProspectAsync(req.RegisterDemoProspectRequest, ct); return await GB5Shared.ResponseStandard.Response.CreateSuccessResponse(result, CacheKeyLevel.NOT_REQUIRED, loginDTO); } }