backend phase 13 & frontend phase 6

This commit is contained in:
hamid
2026-07-09 04:09:35 +03:30
parent dc64472631
commit de53f9d8a6
97 changed files with 11969 additions and 77 deletions
@@ -0,0 +1,34 @@
#nullable enable
using Baya.Application.Contracts.Configuration;
using Baya.Application.Contracts.Payments;
using Baya.Domain.Entities.Payouts;
using Microsoft.EntityFrameworkCore;
namespace Baya.Infrastructure.Persistence.Services.Payments;
/// <summary>
/// The <b>authoritative</b> b13 implementation of <see cref="INursePayoutStatus"/> — it answers "was the nurse
/// already paid for this booking?" from the real payout ledger: a booking is paid iff a
/// <c>nurse_payout_booking_links</c> row ties it to a <c>nurse_payouts</c> row in status <c>paid</c> (a
/// confirmed, irreversible transfer). This supersedes the b11 interim <c>NursePayoutStatusService</c> that
/// derived it from the dispute-window close. The refund pre-payout/clawback fork is unchanged — it just now
/// forks on the true paid-state. The <c>refund_assume_nurse_paid</c> config switch still forces the paid answer
/// for ops/testing.
/// </summary>
internal sealed class NursePayoutLinkStatusService(
ApplicationDbContext dbContext,
IPlatformConfig platformConfig) : INursePayoutStatus
{
public async ValueTask<bool> IsNursePaidForBookingAsync(long bookingId, CancellationToken cancellationToken = default)
{
if (await platformConfig.GetConfig<bool>("refund_assume_nurse_paid", cancellationToken))
return true;
return await (from l in dbContext.Set<NursePayoutBookingLink>().AsNoTracking()
where l.BookingId == bookingId
join p in dbContext.Set<NursePayout>() on l.PayoutId equals p.Id
where p.Status == PayoutStatus.Paid
select l.Id)
.AnyAsync(cancellationToken);
}
}
@@ -1,35 +0,0 @@
#nullable enable
using Baya.Application.Contracts.Common;
using Baya.Application.Contracts.Configuration;
using Baya.Application.Contracts.Payments;
using Microsoft.EntityFrameworkCore;
using BookingEntity = Baya.Domain.Entities.Booking.Booking;
namespace Baya.Infrastructure.Persistence.Services.Payments;
/// <summary>
/// The interim implementation of <see cref="INursePayoutStatus"/> until b13 ships <c>nurse_payouts</c> /
/// <c>nurse_payout_booking_links</c>. It derives "already paid?" from the booking's dispute-window close — the
/// exact gate b13 pays out on — so the pre-payout (clean reversal) path is the common one and the clawback path
/// is the fallback. A <c>refund_assume_nurse_paid</c> config switch forces the paid answer for ops/testing. b13
/// swaps this registration for the authoritative payout-link lookup.
/// </summary>
internal sealed class NursePayoutStatusService(
ApplicationDbContext dbContext,
IDateTimeProvider dateTimeProvider,
IPlatformConfig platformConfig) : INursePayoutStatus
{
public async ValueTask<bool> IsNursePaidForBookingAsync(long bookingId, CancellationToken cancellationToken = default)
{
if (await platformConfig.GetConfig<bool>("refund_assume_nurse_paid", cancellationToken))
return true;
var now = dateTimeProvider.UtcNow.UtcDateTime;
var windowEnd = await dbContext.Set<BookingEntity>().AsNoTracking()
.Where(b => b.Id == bookingId)
.Select(b => b.DisputeWindowEndsAt)
.FirstOrDefaultAsync(cancellationToken);
return windowEnd is { } endsAt && endsAt <= now;
}
}