refinement phase 8

This commit is contained in:
hamid
2026-07-13 21:49:50 +03:30
parent 7edadadea1
commit ef3024ef2f
35 changed files with 2505 additions and 71 deletions
@@ -0,0 +1,38 @@
#nullable enable
using System;
using System.Threading;
using System.Threading.Tasks;
using Baya.Application.Features.Invoices.Commands.ReconcileMoadianInvoices;
using Mediator;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace Baya.Infrastructure.Persistence.Services.Scheduling.Jobs;
/// <summary>
/// Walks every <c>pending</c>/<c>submitted</c> سامانه مودیان invoice toward its registered 22-digit reference
/// (refinement-phase-8, 6.5) — the async reconciliation the mock <c>IMoadianClient</c> collapses. Runs on a fixed
/// cadence (no new seeded config key → no migration) and is idempotent: a re-submission of an already-registered
/// invoice is a no-op, and مودیان dedups on the invoice number so a re-submit doubles as the status poll. Sends
/// <see cref="ReconcileMoadianInvoicesCommand"/> under the scheduler's per-tick lock.
/// </summary>
internal sealed class MoadianReconciliationJob(ILogger<MoadianReconciliationJob> logger) : IRecurringJob
{
public string Name => "moadian_reconciliation";
// A fixed cadence keeps this off the seeded-config path (no migration); Moadian registration is not
// time-critical, so every few hours is ample.
public ValueTask<TimeSpan> GetIntervalAsync(IServiceProvider services, CancellationToken cancellationToken)
=> ValueTask.FromResult(TimeSpan.FromHours(6));
public async ValueTask RunAsync(IServiceProvider services, CancellationToken cancellationToken)
{
var sender = services.GetRequiredService<ISender>();
var result = await sender.Send(new ReconcileMoadianInvoicesCommand(), cancellationToken);
if (result.IsSuccess && result.Result is { } reconcile && reconcile.Scanned > 0)
logger.LogInformation(
"مودیان reconciliation scanned {Scanned} invoice(s); {Registered} reached registered",
reconcile.Scanned, reconcile.Registered);
}
}