using FastEndpoints; using GB5Shared.DTO.Framework.Login; using GB5Shared.DTO.Framework.ResponseStandard; using GB5Shared.FastEndPoint; using RecruitmentBLL.Career; using RecruitmentDAL.DTO.Career; using static GB5Shared.GB5Constant.Constant; namespace RecruitmentSL.EndPoints.Career { // Public career-site apply flow. This is the one write in the Career surface reachable by // a fully anonymous visitor with no session/menu-rights gate of any kind, so it is rate // limited via FastEndpoints' built-in Throttle() — no other AllowAnonymous endpoint in this // repo currently uses Throttle() (searched repo-wide; no precedent found), so the limit // below is a conservative default rather than a match to an existing convention: 5 // submissions per rolling hour per client (FastEndpoints keys this by the 'X-Forwarded-For' // header if present, else HttpContext.Connection.RemoteIpAddress) — enough for a genuine // applicant (who may legitimately retry once or twice after a validation error) while // making a scripted flood of fake applications impractical. public class SubmitApplication : BaseEndpoint> { private readonly ICareerBLL _CareerBLL; public SubmitApplication(ICareerBLL careerBLL) { _CareerBLL = careerBLL; } public override void Configure() { Post("/Career/SubmitApplication"); AllowAnonymous(); Throttle(hitLimit: 5, durationSeconds: 3600); } public record SubmitApplicationParameters( [property: FastEndpoints.FromHeader] string Login, [property: FastEndpoints.FromBody] CareerApplicationSubmissionDTO Submission ); // Mutation — never cached. protected override string? GetCacheKey(SubmitApplicationParameters req, LoginDTO login) => null; protected override async Task> ExecuteAsync( SubmitApplicationParameters req, LoginDTO LoginDTO, CancellationToken ct) { try { var result = await _CareerBLL .SubmitApplication(req.Submission, LoginDTO!, ct); return await GB5Shared.ResponseStandard.Response .CreateSuccessResponse( result, CacheKeyLevel.NOT_REQUIRED, LoginDTO); } catch (Exception ex) { return await GB5Shared.ResponseStandard.Response .CreateExceptionError( ex, CacheKeyLevel.NOT_REQUIRED, LoginDTO, ex.Message, 500); } } } }