Refactored `ExtractSwissQrCodeAsync` to `InspectSwissQrCodeAsync`, introducing `SwissQrCodeResult` to encapsulate both validation and extraction results. Removed `throwIfInvalid` parameter, ensuring validation details are always returned without exceptions. Added extension methods for file path handling to improve usability. Updated tests to reflect the new behavior, ensuring extraction is never attempted on invalid documents and validation results are always populated. Simplified API surface by removing redundant overloads and improving stream handling. Enhanced documentation and performed general code cleanup for better maintainability.
74 lines
3.0 KiB
C#
74 lines
3.0 KiB
C#
using DocumentService.Application.Common.DTOs;
|
||
using DocumentService.Client.Interfaces;
|
||
using DocumentService.Client.Models.Results;
|
||
|
||
namespace DocumentService.Client.Clients;
|
||
|
||
/// <summary>
|
||
/// Orchestrated multi-step workflows that compose multiple DocumentService clients
|
||
/// into single, higher-level operations.
|
||
/// </summary>
|
||
public class WorkflowsClient(IPdfValidationClient validation, ISwissQrCodeClient swissQrCode) : IWorkflowsClient
|
||
{
|
||
/// <inheritdoc />
|
||
public async Task<SwissQrCodeResult> InspectSwissQrCodeAsync(
|
||
byte[] pdfBytes,
|
||
bool raw = false,
|
||
CancellationToken cancellationToken = default)
|
||
{
|
||
var validationResult = await validation.ValidateAsync(pdfBytes, cancellationToken);
|
||
var qrCode = validationResult.IsValid
|
||
? await swissQrCode.ExtractAsync(pdfBytes, raw, cancellationToken)
|
||
: null;
|
||
return new SwissQrCodeResult(qrCode, validationResult);
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<SwissQrCodeResult> InspectSwissQrCodeAsync(
|
||
Stream pdfStream,
|
||
bool raw = false,
|
||
CancellationToken cancellationToken = default)
|
||
{
|
||
var validationResult = await validation.ValidateAsync(pdfStream, cancellationToken);
|
||
|
||
if (!validationResult.IsValid)
|
||
return new SwissQrCodeResult(null, validationResult);
|
||
|
||
// Stream was consumed by validation – reset if possible, otherwise re-open is caller's responsibility.
|
||
if (pdfStream.CanSeek)
|
||
pdfStream.Position = 0;
|
||
|
||
var qrCode = await swissQrCode.ExtractAsync(pdfStream, raw, cancellationToken);
|
||
return new SwissQrCodeResult(qrCode, validationResult);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Convenience extensions for <see cref="IWorkflowsClient"/> that accept a file path as input.
|
||
/// Defined alongside <see cref="WorkflowsClient"/> so they are discoverable without an additional using directive.
|
||
/// </summary>
|
||
public static class WorkflowsClientExtensions
|
||
{
|
||
/// <summary>
|
||
/// Validates the PDF at <paramref name="filePath"/> and attempts Swiss QR Code extraction
|
||
/// in a single call. Opens a <see cref="FileStream"/> and delegates to
|
||
/// <see cref="IWorkflowsClient.InspectSwissQrCodeAsync(Stream, bool, CancellationToken)"/>.
|
||
/// </summary>
|
||
/// <param name="client">The workflows client.</param>
|
||
/// <param name="filePath">Absolute or relative path to the PDF file.</param>
|
||
/// <param name="raw">
|
||
/// <c>false</c> (default) – returns a parsed Bill object.<br/>
|
||
/// <c>true</c> – returns raw QR text lines without parsing.
|
||
/// </param>
|
||
/// <param name="cancellationToken">Cancellation token.</param>
|
||
public static async Task<SwissQrCodeResult> InspectSwissQrCodeAsync(
|
||
this IWorkflowsClient client,
|
||
string filePath,
|
||
bool raw = false,
|
||
CancellationToken cancellationToken = default)
|
||
{
|
||
using var stream = File.OpenRead(filePath);
|
||
return await client.InspectSwissQrCodeAsync(stream, raw, cancellationToken);
|
||
}
|
||
}
|