using Fitness_core_BE.Models; namespace Fitness_core_BE.Interfaces { public interface ICustomerSubscriptionRepository { Task AddCustomerSubscriptionAsync( CustomerSubscription subscription, CustomerSubItem initialSubItem, SubscriptionMember primaryMember, IReadOnlyCollection installments, CancellationToken ct = default); Task GetPlanByIdAsync(Guid customerPlanId, CancellationToken ct = default); Task IsActiveCustomerAsync(Guid customerId, CancellationToken ct = default); Task> GetSubItemsAsync( Guid subscriptionId, bool activeOnly, bool newestFirst, CancellationToken ct = default); Task AddSubItemAsync(CustomerSubItem subItem, CancellationToken ct = default); Task GetLatestInvoiceAsync(Guid subscriptionId, CancellationToken ct = default); Task GetApprovedPaymentTotalAsync(Guid invoiceId, CancellationToken ct = default); Task GetCardByIdAsync(Guid cardId, CancellationToken ct = default); Task GetCustomerSubscriptionById(Guid subscriptionId); Task> GetCustomerSubscriptionsByCustomerId(Guid customerId); Task GetActiveSubscriptionByCustomerId(Guid customerId); // Whether this customer is currently an active member (primary OR secondary/group) of // ANY subscription at this gym. GetActiveSubscriptionByCustomerId only sees subscriptions // where they're the primary -- this also catches a group co-member, so "one customer, one // plan at a time" can be enforced everywhere a plan gets assigned, not just the primary // path. Task HasAnyActiveSubscriptionAsync(Guid customerId, CancellationToken ct = default); Task AddSubscriptionMemberAsync(SubscriptionMember member); Task GetActiveMemberCountAsync(Guid subscriptionId); Task GetSubscriptionMemberAsync(Guid subscriptionMemberId); Task GetActiveSubscriptionMemberByCustomerAsync(Guid subscriptionId, Guid customerId); Task> GetSubscriptionsForCustomerAsync(Guid customerId); Task> GetInstallmentsAsync(Guid subscriptionId); // Renewal-approval workflow (SubscriptionRenewalApprovalService.ApproveAsync): advances // RenewalDate only -- ExpiryDate is never touched again after creation. Task AdvanceRenewalDateAsync(Guid subscriptionId, DateTime newRenewalDate, CancellationToken ct = default); // Removes the subscription's current-cycle installment rows before a fresh schedule is // added for the newly-approved cycle. Hard delete, not soft-deactivate: a unique index on // (FKSubscriptionId, InstallmentNo) means a soft-deactivated row would still collide with // the new cycle's schedule restarting at InstallmentNo 1 on the same subscription. Task DeactivatePriorInstallmentsAsync(Guid subscriptionId, CancellationToken ct = default); Task AddInstallmentsAsync(IReadOnlyCollection installments, CancellationToken ct = default); } }