Reviewed Flutter implementation · 2026-10-27
ProxyHoppaRequestUseCase.cs
backend/src/NeoBanking.Application/UseCases/Hoppa/ProxyHoppaRequestUseCase.cs
Immutable source snapshot based on revision de78e63ed65c. Original line numbers are retained. This is implementation evidence; check the public API catalogue before adapting it.
The mobile /api/v1/mobile routes belong to the example backend. Company credentials stay on that backend. Some sections outside the documented product scope may be omitted.
Lines 1–71
using System.Net;using System.Text.Json;using NeoBanking.Application.Common;using NeoBanking.Application.Interfaces; namespace NeoBanking.Application.UseCases.Hoppa; public sealed class ProxyHoppaRequestUseCase : IProxyHoppaRequestUseCase{ private readonly IHoppaClient _hoppaClient; public ProxyHoppaRequestUseCase(IHoppaClient hoppaClient) { _hoppaClient = hoppaClient; } public Task<ApplicationResult<JsonElement?>> ExecuteAsync<TRequest>( ProxyHoppaRequestCommand<TRequest> command, CancellationToken cancellationToken) { var validationError = ValidatePath(command.UpstreamPath); if (validationError is not null) { return Task.FromResult(ApplicationResult<JsonElement?>.Failure(validationError)); } return _hoppaClient.SendAsync<TRequest, JsonElement?>( new HoppaRequest<TRequest> { Method = command.Method, Path = command.UpstreamPath, Query = command.Query, Body = command.Request, IdempotencyKey = command.IdempotencyKey, TrustedReferralActorId = command.TrustedReferralActorId, SuppressPayloadLogging = command.SuppressPayloadLogging, FailureCode = command.FailureCode, FailureMessage = command.FailureMessage }, cancellationToken); } private static ApplicationError? ValidatePath(string upstreamPath) { if (string.IsNullOrWhiteSpace(upstreamPath)) { return InvalidPath("Hoppa upstream path is required."); } if (!upstreamPath.StartsWith('/')) { return InvalidPath("Hoppa upstream path must be absolute relative to the configured base URL."); } if (upstreamPath.Contains("://", StringComparison.Ordinal) || upstreamPath.Contains('\\', StringComparison.Ordinal)) { return InvalidPath("Hoppa upstream path must not contain a scheme or backslashes."); } return null; } private static ApplicationError InvalidPath(string detail) { return new ApplicationError( "hoppa.path.invalid", "The Hoppa upstream path is invalid.", (int)HttpStatusCode.InternalServerError, detail); }}