first commit

This commit is contained in:
Dhananjaya99
2026-09-28 11:44:26 +05:30
parent 721743ae6b
commit bffc9b1686
424 changed files with 46474 additions and 0 deletions
@@ -0,0 +1,47 @@
using Fitness_core_BE.DTOs;
using Fitness_core_BE.DTOs.AccessDevice;
using Fitness_core_BE.Models;
namespace Fitness_core_BE.Interfaces.Services
{
public interface IAccessDeviceService
{
Task<object> AddDevice(object payload);
Task<object> RemoveDevice(object payload);
Task<object> GeneratePairingCode(object payload);
Task<bool> WhiteListMember(Guid memberId);
Task<bool> BlackListMember(Guid memberId);
// Manual/auto lock (req 7) — wraps WhiteListMember/BlackListMember and mirrors the
// result onto Customer.IsLocked/LockReason/LockedAt.
Task<bool> LockCustomer(Guid customerId, string reason);
Task<bool> UnlockCustomer(Guid customerId);
Task<Customer> UpdateDeviceProfile(Customer customer);
Task<object> AddUser(CustomerAccess cusDevice);
// Dedup + persist attendance. Reused by the agent attendance ingestion endpoint.
Task<int> SaveAttendanceRecords(Guid clientId, List<AttendanceDTO> attendanceList);
// Fingerprint-enrolled-directly-on-device reconciliation (req 3).
Task<List<UnlinkedDeviceEnrollment>> GetUnlinkedFingerprintsAsync(Guid clientId);
Task<AccessProfile> LinkFingerprintAsync(Guid clientId, Guid customerId, Guid unlinkedEnrollmentId);
Task<AccessProfile> EnsureAccessProfileAsync(
Guid clientId, Guid userId, string personType, string displayName, bool queueProvisioning = true);
Task ProvisionProfilesToDeviceAsync(AccessDevice device);
Task<object> SetUserAccessAsync(Guid clientId, Guid userId, bool enabled, string? reason);
Task<object> SetCustomerAccessAsync(Guid clientId, Guid customerId, bool enabled, string? reason);
/// <summary>
/// Queues a face photo for enrolment into the gym's Hikvision terminals. The image
/// travels in the command payload only -- it is purged once a terminal confirms.
/// </summary>
Task<object> SetCustomerFacePhotoAsync(Guid clientId, Guid customerId, string base64Jpeg);
Task<object> SetStaffAccessAsync(Guid clientId, Guid staffId, bool enabled, string? reason);
Task<AccessProfile> LinkDevicePersonAsync(
Guid clientId, Guid userId, string personType, string displayName, Guid unlinkedEnrollmentId);
Task<AccessProfile> LinkStaffFingerprintAsync(
Guid clientId, Guid staffId, Guid unlinkedEnrollmentId);
Task<AccessStatusDto?> GetAccessStatusAsync(Guid clientId, Guid userId);
}
}
@@ -0,0 +1,10 @@
using Microsoft.AspNetCore.Http;
namespace Fitness_core_BE.Interfaces.Services
{
public interface IActivityLogService
{
Task<object> LogActivity(object payload, HttpContext httpContext);
Task<object> GetActivityLogs(object payload, HttpContext httpContext);
}
}
@@ -0,0 +1,16 @@
using Fitness_core_BE.Models.IOs;
using Microsoft.AspNetCore.Http;
namespace Fitness_core_BE.Interfaces.Services
{
public interface IAdminClientDirectoryService
{
Task<PagedResult<ClientSummary>> ListAsync(ClientDirectoryQuery query);
Task<object> GetByIdAsync(Guid id);
Task<PairingCodeResult> GeneratePairingCodeAsync(Guid clientId);
Task<AdminClientDevicesResult> GetDevicesAsync(Guid clientId);
// Re-sends the "set your password" welcome email (with a fresh temp password + link)
// for a client whose account has no usable password yet.
Task ResendWelcomeEmailAsync(Guid clientId, HttpContext httpContext);
}
}
@@ -0,0 +1,11 @@
using Fitness_core_BE.Models.IOs;
namespace Fitness_core_BE.Interfaces.Services
{
public interface IAdminSuggestionService
{
Task<object> ListAsync();
Task<object> CreateWorkoutAsync(AdminWorkoutSuggestionRequest request, HttpContext httpContext);
Task<object> CreateMealAsync(AdminMealSuggestionRequest request, HttpContext httpContext);
}
}
+21
View File
@@ -0,0 +1,21 @@
using Fitness_core_BE.DTOs.Agent;
namespace Fitness_core_BE.Interfaces.Services
{
public interface IAgentService
{
// Bootstrap enrollment (no api-key auth). Returns { agentId, apiKey } once.
Task<object> EnrollAsync(EnrollRequest request);
// Agent-authenticated operations. clientId / agentId are resolved server-side
// from the authenticated agent, never from the request body.
Task<object> RegisterDeviceAsync(Guid clientId, Guid agentId, RegisterDeviceRequest request);
Task<object> ReconcileDeviceInventoryAsync(Guid clientId, Guid agentId, DeviceInventoryRequest request);
Task<object> IngestAttendanceAsync(Guid clientId, Guid agentId, AgentAttendanceRequest request);
Task<object> GetPendingCommandsAsync(Guid clientId, Guid agentId);
Task<object> SubmitCommandResultAsync(
Guid clientId, Guid agentId, Guid commandId, CommandResultRequest request);
Task<object> HeartbeatAsync(
Guid clientId, Guid agentId, AgentHeartbeatRequest request);
}
}
@@ -0,0 +1,9 @@
namespace Fitness_core_BE.Interfaces.Services
{
public interface IAttendanceService
{
Task<object> GetAllAttendanceRecords(object payload, HttpContext httpContext);
Task<object> GetAttendanceCounts(object payload, HttpContext httpContext);
Task<object> GetTodayAttendance(object payload, HttpContext httpContext);
}
}
+32
View File
@@ -0,0 +1,32 @@
using Fitness_core_BE.DTOs.Auth;
using Microsoft.AspNetCore.Http;
namespace Fitness_core_BE.Interfaces.Services
{
public interface IAuthService
{
Task<AuthResponse> SendOtp(object payload, HttpContext httpContext);
Task<AuthResponse> LoginUser(object payload, HttpContext httpContext);
Task<AuthResponse> RefreshToken(object payload, HttpContext httpContext);
Task<AuthResponse> VerifyOTP(object payload, HttpContext httpContext);
// Verifies an OTP and, on success, sets the caller's Customer channel flag
// (IsPrimaryPHVerfied / IsEmailVerfied / IsSecondaryPHVerfied).
Task<AuthResponse> VerifyOTPForCus(object payload, HttpContext httpContext);
Task<AuthResponse> IsAvailable(object payload, HttpContext httpContext);
Task<AuthResponse> GetUserDetails(object payload, HttpContext httpContext);
Task<AuthResponse> UpdateUser(object payload, HttpContext httpContext);
// Admin/service-initiated update of an arbitrary user's login credential by userId —
// unlike UpdateUser (which patches the caller's own profile from their JWT), this lets
// a client/staff edit patch the login record of the *customer* they're editing. Forwards
// to Auth's existing "adminUpdateUser" function.
Task<AuthResponse> AdminUpdateUser(object payload, HttpContext httpContext);
Task<AuthResponse> RegisterUser(object payload, HttpContext httpContext);
Task<AuthResponse> VerifyOtpForLogin(object payload, HttpContext httpContext);
Task<AuthResponse> ForgotPassword(object payload, HttpContext httpContext);
Task<AuthResponse> ResetPassword(object payload, HttpContext httpContext);
Task<AuthResponse> ResetPasswordWithToken(object payload, HttpContext httpContext);
Task<AuthResponse> VerifyPassword(object payload, HttpContext httpContext);
Task<AuthResponse> LogOut(object payload, HttpContext httpContext);
void SetAccessTokenCookie(HttpContext httpContext, string token);
}
}
+28
View File
@@ -0,0 +1,28 @@
using Microsoft.AspNetCore.Http;
namespace Fitness_core_BE.Interfaces.Services
{
public interface IBookingService
{
/// <summary>Logged-in member books a session against their own plan's allowance.</summary>
Task<object> CreateMemberBooking(object payload, HttpContext httpContext);
/// <summary>No membership at all -- pay-per-session, identity proof is the returned OTP.</summary>
Task<object> CreateGuestBooking(object payload, HttpContext httpContext);
/// <summary>Renders the public, unauthenticated confirmation page a booking's ShareUrl
/// points to -- the "copy the link and share it" receipt. Returns null if not found, so
/// the controller can render a 404 page instead of a JSON error for a browser hit.</summary>
Task<object?> GetBookingView(object payload);
/// <summary>Staff records a guest booking's payment (cash/bank/at-venue) after the fact.</summary>
Task<object> MarkGuestBookingPaid(object payload, HttpContext httpContext);
/// <summary>Staff/door check-in: verifies the OTP and marks the booking checked in.</summary>
Task<object> CheckInBooking(object payload, HttpContext httpContext);
Task<object> CancelBooking(object payload, HttpContext httpContext);
Task<object> GetMyBookings(object payload, HttpContext httpContext);
Task<object> GetSessionBookings(object payload, HttpContext httpContext);
}
}
+7
View File
@@ -0,0 +1,7 @@
namespace Fitness_core_BE.Interfaces.Services
{
public interface IBootstrapService
{
Task<object> BootstrapClub(object payload);
}
}
+12
View File
@@ -0,0 +1,12 @@
using Fitness_core_BE.Models;
namespace Fitness_core_BE.Interfaces.Services
{
public interface IChatService
{
Task<object> GetOrCreateChatAsync(object payload);
Task<object> SendMessageAsync(object payload);
Task<object> GetMessagesAsync(object payload);
Task<bool> CanUserAccessChatAsync(Guid chatId, Guid userId);
}
}
@@ -0,0 +1,14 @@
using Microsoft.AspNetCore.Http;
namespace Fitness_core_BE.Interfaces.Services
{
public interface IClientInvoiceService
{
Task<object> CreateClientInvoiceFromSubscription(object payload, HttpContext httpContext);
Task<object> GetClientInvoiceById(object payload, HttpContext httpContext);
Task<object> GetClientInvoicesByClientId(object payload, HttpContext httpContext);
Task<object> GetClientInvoicesByUserId(object payload, HttpContext httpContext);
Task<object> UpdateClientInvoiceStatus(object payload, HttpContext httpContext);
Task<object> CalculateClientInvoiceTotal(object payload, HttpContext httpContext);
}
}
@@ -0,0 +1,33 @@
using Fitness_core_BE.DTOs.PlatformBilling;
using Microsoft.AspNetCore.Http;
namespace Fitness_core_BE.Interfaces.Services
{
// The gym owner's own card(s) on file for their HexaFitness platform subscription, and
// the transaction history behind those charges — backed by Payment-Service via
// IPaymentGatewayClient, scoped to the caller's own Client (see UserRoleHelper.GetClientId).
public interface IClientPaymentMethodService
{
Task<StartCardOnboardingResult> StartCardOnboardingAsync(
HttpContext httpContext,
StartCardOnboardingRequest request,
CancellationToken ct = default);
Task<CardOnboardingStatusResult> CompleteCardOnboardingAsync(
HttpContext httpContext,
string sessionId,
CancellationToken ct = default);
Task<List<ClientCardDto>> ListCardsAsync(HttpContext httpContext, CancellationToken ct = default);
Task RemoveCardAsync(HttpContext httpContext, string cardToken, CancellationToken ct = default);
Task<ClientCardDto> SetDefaultCardAsync(HttpContext httpContext, string cardToken, CancellationToken ct = default);
Task<TransactionHistoryResult> GetTransactionHistoryAsync(
HttpContext httpContext,
int page,
int pageSize,
CancellationToken ct = default);
}
}
+54
View File
@@ -0,0 +1,54 @@
using Microsoft.AspNetCore.Http;
using Fitness_core_BE.Models.IOs;
namespace Fitness_core_BE.Interfaces.Services
{
public interface IClientService
{
Task<object> GetAllCustomers(object payload, HttpContext httpContext);
Task<object> GetClientList(object payload, HttpContext httpContext);
Task<object> GetClientById(object payload, HttpContext httpContext);
Task<object> UpdateGymProfile(
UpdateGymProfileRequest request, HttpContext httpContext);
// Gym-specific Terms & Conditions authoring (client portal).
Task<object> GetMyGymTerms(object payload, HttpContext httpContext);
Task<object> PublishGymTerms(object payload, HttpContext httpContext);
Task<object> UploadGymLogo(IFormFile logo, HttpContext httpContext);
Task<object> GetGymLogo(HttpContext httpContext);
Task<object> SendContactOtp(object payload, HttpContext httpContext);
Task<object> VerifyContactOtp(object payload, HttpContext httpContext);
Task<object> GetCustomerFullDetails(object payload, HttpContext httpContext);
Task<object> GetCustomerMedical(object payload, HttpContext httpContext);
Task<object> GetCustomerDetailsById(object payload, HttpContext httpContext);
Task<object> CreateCustomerWithPlans(object payload, HttpContext httpContext);
Task<object> UpdateCustomerByClient(object payload, HttpContext httpContext);
Task<object> GetCustomersByClientId(object payload, HttpContext httpContext);
// "Parent" path for a plan-less customer: starts a brand new subscription with them
// as primary. Mirrors CreateCustomerWithPlans' plan-assignment step, callable standalone
// for a customer who was created without a plan.
Task<object> AssignPlanToExistingCustomer(Guid customerId, object payload, HttpContext httpContext);
// Switches a customer with an existing Individual-scope subscription onto a different
// Individual-scope plan: deactivates the old subscription and starts a fresh one.
Task<object> ChangeCustomerMembershipPlan(Guid customerId, Guid newCustomerPlanId, HttpContext httpContext);
Task<object> UnassignCustomerMembership(Guid customerId, HttpContext httpContext);
Task<object> GetCustomerPlansByClientId(object payload, HttpContext httpContext);
Task<object> RegisterClient(object payload, HttpContext httpContext);
Task<object> GetPackageList(object payload, HttpContext httpContext);
Task<object> DeleteCustomerByClient(object payload, HttpContext httpContext);
Task<object> ClientLogOut(object payload, HttpContext httpContext);
Task<object> GetWorkoutPlansByClientId(object payload, HttpContext httpContext);
Task<object> GetWorkoutPlanById(object payload, HttpContext httpContext);
Task<object> GetMealPlansByClientId(object payload, HttpContext httpContext);
Task<object> GetMealPlanById(object payload, HttpContext httpContext);
Task<object> GetAllCustomerPlans(object payload, HttpContext httpContext);
Task<object> GetCustomerPlanById(object payload, HttpContext httpContext);
Task<object> GetCardDetails(object payload, HttpContext httpContext);
// Cards a specific member has saved with this gym (used to offer the auto-charge toggle).
Task<object> GetCustomerCards(object payload, HttpContext httpContext);
// Auto-lock-after-non-payment settings (req 7) — client-configurable.
Task<object> GetLockPolicy(HttpContext httpContext);
Task<object> UpdateLockPolicy(int? lockAfterDaysOverdue, HttpContext httpContext);
}
}
+17
View File
@@ -0,0 +1,17 @@
namespace Fitness_core_BE.Interfaces.Services
{
public interface IClientStatService
{
Task<object> GetTotalCustomerCount(object payload, HttpContext httpContext);
Task<object> GetMonthlyCustomerCount(object payload, HttpContext httpContext);
Task<object> GetTotalWorkoutPlanCount(object payload, HttpContext httpContext);
Task<object> GetTotalMealPlanCount(object payload, HttpContext httpContext);
Task<object> GetLastMonthCustomerCount(object payload, HttpContext httpContext);
Task<object> GetLastFiveAttendances(object payload, HttpContext httpContext);
Task<object> GetLastFivePayments(object payload, HttpContext httpContext);
Task<object> GetLastMonthRevenue(object payload, HttpContext httpContext);
Task<object> GetMonthlyRevenueVariation(object payload, HttpContext httpContext, DateTime? from = null, DateTime? to = null);
Task<object> GetTotalRevenue(object payload, HttpContext httpContext);
Task<object> GetClientStatSummary(object payload, HttpContext httpContext, DateTime? from = null, DateTime? to = null);
}
}
@@ -0,0 +1,14 @@
using Microsoft.AspNetCore.Http;
namespace Fitness_core_BE.Interfaces.Services
{
public interface ICustomerInvoiceService
{
Task<object> CreateCustomerInvoiceFromSubscription(object payload, HttpContext httpContext);
Task<object> GetCustomerInvoiceById(object payload, HttpContext httpContext);
Task<object> GetCustomerInvoicesByCustomerId(object payload, HttpContext httpContext);
Task<object> GetCustomerInvoicesByClientId(object payload, HttpContext httpContext);
Task<object> UpdateCustomerInvoiceStatus(object payload, HttpContext httpContext);
Task<object> CalculateCustomerInvoiceTotal(object payload, HttpContext httpContext);
}
}
@@ -0,0 +1,17 @@
using Microsoft.AspNetCore.Http;
namespace Fitness_core_BE.Interfaces.Services
{
public interface ICustomerPlanService
{
Task<object> GetAllCustomerPlans(object payload, HttpContext httpContext);
Task<object> GetCustomerPlanById(object payload, HttpContext httpContext);
Task<object> CreateCustomerPlan(object payload, HttpContext httpContext);
Task<object> UpdateCustomerPlan(object payload, HttpContext httpContext);
/// <summary>Activates or deactivates a plan without touching its configuration.</summary>
Task<object> SetCustomerPlanStatus(object payload, HttpContext httpContext);
Task<object> DeleteCustomerPlan(object payload, HttpContext httpContext);
}
}
+65
View File
@@ -0,0 +1,65 @@
using Microsoft.AspNetCore.Http;
namespace Fitness_core_BE.Interfaces.Services
{
public interface ICustomerService
{
Task<object> CreateCustomer(object payload, HttpContext httpContext);
Task<object> CustomerExists(object payload, HttpContext httpContext);
// True when the caller's Customer has verified at least one channel (email/phone).
Task<bool> IsCustomerVerified(HttpContext httpContext);
Task<object> AssignPlansToCustomer(Guid customerId, object payload, HttpContext httpContext);
Task<object> UpdateCustomer(object payload, HttpContext httpContext);
Task<object> DeleteCustomer(object payload, HttpContext httpContext);
Task<object> GetCustomerMealPlan(object payload, HttpContext httpContext);
Task<object> GetCustomerMealPlanById(object payload, HttpContext httpContext);
Task<object> GetFollowedMealPlans(object payload, HttpContext httpContext);
Task<object> GetMyMealPlans(object payload, HttpContext httpContext);
Task<object> GetCustomerWorkOutPlan(object payload, HttpContext httpContext);
Task<object> GetCustomerWorkoutPlanById(object payload, HttpContext httpContext);
Task<object> GetFollowedWorkoutPlans(object payload, HttpContext httpContext);
Task<object> GetMyWorkoutPlans(object payload, HttpContext httpContext);
Task<object> FollowMealPlan(object payload, HttpContext httpContext);
Task<object> FollowWorkOutPlan(object payload, HttpContext httpContext);
Task<object> SetWorkoutExerciseCompletion(Guid workoutPlanId, Guid exerciseId, bool completed, HttpContext httpContext);
Task<object> GetClientDataById(object payload, HttpContext httpContext);
Task<object> GetClientGyms(object payload, HttpContext httpContext);
// QR gym onboarding: list a gym's membership plans, then join by picking one.
Task<object> GetGymPlans(object payload, HttpContext httpContext);
Task<object> JoinGym(object payload, HttpContext httpContext);
// Gym-specific Terms & Conditions: view the gym's active terms and record acceptance.
Task<object> GetGymTerms(object payload, HttpContext httpContext);
Task<object> AcceptGymTerms(object payload, HttpContext httpContext);
Task<byte[]?> GetGymTermsPdf(Guid clientId);
Task<object> CreateCusHealthRec(object payload, HttpContext httpContext);
Task<object> CreateCusProgressRec(object payload, HttpContext httpContext);
Task<object> UpdateCusHealthRec(object payload, HttpContext httpContext);
Task<object> UpdateCusProgressRec(object payload, HttpContext httpContext);
Task<object> UpdateCustomerTargetNutritions(object payload, HttpContext httpContext);
Task<object> GetCusBasicDetails(object payload, HttpContext httpContext);
Task<object> GetCusHealthDetails(object payload, HttpContext httpContext);
Task<object> GetCusProgressDetails(object payload, HttpContext httpContext);
Task<object> GetCustomerProgress(object payload, HttpContext httpContext);
Task<object> UpdateWeeklyProgress(object payload, HttpContext httpContext);
Task<object> GetWeeklyProgressForCustomer(object payload, HttpContext httpContext);
Task<object> CreateFeed(object payload, HttpContext httpContext);
Task<object> GetCardDetails(object payload, HttpContext httpContext);
// Member self-serve auto-deduct: save a card with explicit consent, then opt a
// subscription in/out of being auto-charged against that card.
Task<object> SaveCard(object payload, HttpContext httpContext);
Task<object> SetAutoCharge(Guid subscriptionId, object payload, HttpContext httpContext);
// Lets the mobile app find the caller's active subscription id to target SetAutoCharge.
Task<object> GetMySubscription(object payload, HttpContext httpContext);
Task<object> GetMyGym(object payload, HttpContext httpContext);
Task<object> UnfollowMyGym(object payload, HttpContext httpContext);
Task<object> MyPayment(object payload, HttpContext httpContext);
// In-app Notification tab: history of assignment/feed pushes sent to this customer.
Task<object> GetMyNotifications(object payload, HttpContext httpContext);
Task<object> MarkNotificationRead(Guid notificationId, HttpContext httpContext);
// Refreshes the stored Expo push token (called at login, since a token can rotate).
Task<object> UpdatePushToken(object payload, HttpContext httpContext);
// Links an already-uploaded document (POST /customer/documents) as this customer's
// profile picture.
Task<object> UpdateProfileImage(object payload, HttpContext httpContext);
}
}
@@ -0,0 +1,22 @@
using Fitness_core_BE.DTOs.CustomerSubscription;
using Microsoft.AspNetCore.Http;
namespace Fitness_core_BE.Interfaces.Services
{
public interface ICustomerSubscriptionService
{
Task<object> CreateCustomerSubscription(object payload, HttpContext httpContext);
Task<object> GetCustomerSubscriptionById(object payload, HttpContext httpContext);
Task<object> GetCustomerSubscriptionsByCustomerId(object payload, HttpContext httpContext);
Task<object> GetActiveSubscriptionByCustomerId(object payload, HttpContext httpContext);
Task<object> GetSubscriptionSummary(object payload, HttpContext httpContext);
Task<object> AddMemberToSubscription(object payload, HttpContext httpContext);
Task<object> RemoveMemberFromSubscription(object payload, HttpContext httpContext);
Task<List<SubscriptionSummaryDto>> BuildSummariesForCustomerAsync(Guid customerId);
// Optional extra fees on a subscription (req 6 — e.g. coaching fee, once or recurring).
Task<List<CustomerSubItemDto>> GetExtraFeesAsync(Guid subscriptionId, HttpContext httpContext);
Task<object> AddExtraFeeAsync(Guid subscriptionId, AddExtraFeeRequest request, HttpContext httpContext);
}
}
+14
View File
@@ -0,0 +1,14 @@
using Fitness_core_BE.DTOs;
using Microsoft.AspNetCore.Http;
namespace Fitness_core_BE.Interfaces.Services
{
public interface IDocumentService
{
Task<object> UploadDocument(object payload, HttpContext httpContext);
Task<object> GetDocumentsByUserId(object payload, HttpContext httpContext);
Task<object> GetDocumentById(object payload, HttpContext httpContext);
Task<object> RemoveDocument(object payload, HttpContext httpContext);
Task<DocumentDownloadModel> GetFileBytesById(int documentId);
}
}
+16
View File
@@ -0,0 +1,16 @@
using Microsoft.AspNetCore.Http;
namespace Fitness_core_BE.Interfaces.Services
{
public interface IFacilityService
{
Task<object> GetAllFacilities(object payload, HttpContext httpContext);
Task<object> CreateFacility(object payload, HttpContext httpContext);
Task<object> UpdateFacility(object payload, HttpContext httpContext);
Task<object> SetFacilityStatus(object payload, HttpContext httpContext);
Task<object> CreateFacilitySession(object payload, HttpContext httpContext);
Task<object> GetSessions(object payload, HttpContext httpContext);
Task<object> CancelFacilitySession(object payload, HttpContext httpContext);
}
}
+17
View File
@@ -0,0 +1,17 @@
using Microsoft.AspNetCore.Http;
namespace Fitness_core_BE.Interfaces.Services
{
public interface IFeedService
{
Task<object> GetFeedPostById(object payload, HttpContext httpContext);
Task<object> GetFeedForCustomer(object payload, HttpContext httpContext);
Task<object> LikeAsync(object payload, HttpContext httpContext);
Task<object> IsLikedAsync(object payload, HttpContext httpContext);
Task<object> UnlikeAsync(object payload, HttpContext httpContext);
Task<object> CreateFeed(object payload, HttpContext httpContext);
Task<object> ShowFeedByClient(object payload, HttpContext httpContext);
Task<object> DeleteFeedByPostId(object payload, HttpContext httpContext);
}
}
+19
View File
@@ -0,0 +1,19 @@
using Fitness_core_BE.DTOs.Rbac;
using Microsoft.AspNetCore.Http;
namespace Fitness_core_BE.Interfaces.Services
{
// Owner-only role CRUD + staff-role assignment. Every method resolves the caller via
// UserRoleHelper.GetClientId directly and never consults IPermissionService/GymRolePermission —
// this is what makes role management immune to staff self-escalation: no nav-section
// permission can ever unlock these methods for a staff account.
public interface IGymRoleService
{
Task<List<GymRoleDto>> GetRolesAsync(HttpContext httpContext);
Task<GymRoleDto> CreateRoleAsync(CreateGymRoleRequest request, HttpContext httpContext);
Task<GymRoleDto> UpdateRoleAsync(Guid gymRoleId, UpdateGymRoleRequest request, HttpContext httpContext);
Task DeleteRoleAsync(Guid gymRoleId, HttpContext httpContext);
Task<GymRoleDto> SetRolePermissionsAsync(Guid gymRoleId, SetRolePermissionsRequest request, HttpContext httpContext);
Task AssignStaffRoleAsync(Guid staffId, AssignStaffRoleRequest request, HttpContext httpContext);
}
}
+21
View File
@@ -0,0 +1,21 @@
using Microsoft.AspNetCore.Http;
namespace Fitness_core_BE.Interfaces.Services
{
public interface IMealService
{
Task<object> GetMealCategoryList(object payload, HttpContext httpContext);
Task<object> CreateMealCategory(object payload, HttpContext httpContext);
Task<object> GetMealPlanList(object payload, HttpContext httpContext);
Task<object> GetMealPlanById(object payload, HttpContext httpContext);
Task<object> GetMealPlanByCustomerId(object payload, HttpContext httpContext);
Task<object> CreateMealPlan(object payload, HttpContext httpContext);
Task<object> CreateCustomerMealPlan(object payload, HttpContext httpContext);
Task<object> GetMealItemsByMealPlanId(object payload, HttpContext httpContext);
Task<object> CreateMealItem(object payload, HttpContext httpContext);
Task<object> UpdateMealPlan(object payload, HttpContext httpContext);
Task<object> DeleteMealPlan(object payload, HttpContext httpContext);
Task<object> AssignMealToCustomer(object payload, HttpContext httpContext);
Task<object> UnassignMealFromCustomer(object payload, HttpContext httpContext);
}
}
@@ -0,0 +1,9 @@
using Fitness_core_BE.DTOs.Rbac;
namespace Fitness_core_BE.Interfaces.Services
{
public interface INavigationService
{
Task<NavResponseDto> GetNavigationAsync(HttpContext httpContext);
}
}
@@ -0,0 +1,26 @@
using Fitness_core_BE.DTOs.PaymentGateways;
namespace Fitness_core_BE.Interfaces.Services
{
// Server-to-server client for Payment-Service's HMAC-signed, per-platform routes
// (Controllers/v1/CardsController.cs, PaymentsController.cs, RefundsController.cs there).
// Distinct from IPaymentServiceClient, which calls the X-Internal-Key admin/catalog surface.
// Every method here is scoped to one gym client and lazily provisions that client's
// Payment-Service Platform on first use (see PaymentGatewayClient.EnsureCredentialsAsync).
public interface IPaymentGatewayClient
{
Task<OnboardCardResult> OnboardCardAsync(Guid clientId, OnboardCardRequest request, CancellationToken ct = default);
Task<CardDetailsResult> GetCardDetailsAsync(Guid clientId, string cardToken, CancellationToken ct = default);
Task<IReadOnlyCollection<CardDetailsResult>> ListCardsAsync(Guid clientId, string customerId, CancellationToken ct = default);
Task DeactivateCardAsync(Guid clientId, string cardToken, CancellationToken ct = default);
Task<SetDefaultCardResult> SetDefaultCardAsync(Guid clientId, string cardToken, string customerId, CancellationToken ct = default);
/// <summary>Polls a hosted-page onboarding started earlier (CardToken is empty until
/// the gateway's webhook completes it — see Payment-Service's CardService).</summary>
Task<OnboardCardResult> GetOnboardingStatusAsync(Guid clientId, string gatewayName, string sessionId, CancellationToken ct = default);
Task<AttemptPaymentResult> AttemptPaymentAsync(Guid clientId, AttemptPaymentRequest request, CancellationToken ct = default);
Task<RefundPaymentResult> RefundPaymentAsync(Guid clientId, Guid paymentId, bool isVoid, CancellationToken ct = default);
Task<PaymentListResult> ListPaymentsAsync(Guid clientId, string? cardToken, int page, int pageSize, CancellationToken ct = default);
}
}
+24
View File
@@ -0,0 +1,24 @@
using Microsoft.AspNetCore.Http;
namespace Fitness_core_BE.Interfaces.Services
{
public interface IPaymentService
{
Task<object> CreateCustomerPayment(object payload, HttpContext httpContext);
Task<object> CreateClientPayment(object payload, HttpContext httpContext);
Task<object> GetPaymentById(object payload, HttpContext httpContext);
Task<object> GetPaymentsByCustomerInvoice(object payload, HttpContext httpContext);
Task<object> GetPaymentsByClientInvoice(object payload, HttpContext httpContext);
Task<object> ApprovePayment(object payload, HttpContext httpContext);
Task<object> RecordSubscriptionPayment(object payload, HttpContext httpContext);
Task<object> GetSubscriptionPayments(object payload, HttpContext httpContext);
// "Charge now": owner-triggered attempt against the member's consented auto-charge card.
Task<object> AttemptAutoCharge(Guid customerInvoiceId, HttpContext httpContext);
// Emails/texts the member a link to pay the invoice online themselves.
Task<object> SendPaymentLink(Guid customerInvoiceId, HttpContext httpContext);
// Public pay-by-link surface (token proves authorization; no logged-in session).
Task<object> GetInvoiceByPaymentToken(string token);
Task<object> ChargeInvoiceByPaymentToken(string token, object payload);
}
}
@@ -0,0 +1,19 @@
using Fitness_core_BE.DTOs.PaymentGateways;
namespace Fitness_core_BE.Interfaces.Services
{
// Server-to-server client for Payment-Service's internal-key-protected admin
// routes (Controllers/v1/GatewaysController.cs, PlatformsController.cs there).
public interface IPaymentServiceClient
{
Task<List<GatewayDefinitionDto>> ListGatewaysAsync(CancellationToken cancellationToken = default);
Task<GatewayDefinitionDto> UpsertGatewayAsync(UpsertGatewayDefinitionRequest request, CancellationToken cancellationToken = default);
Task<GatewayDefinitionDto> SetGatewayEnabledAsync(Guid id, bool isEnabled, CancellationToken cancellationToken = default);
Task UpsertPlatformCredentialAsync(UpsertPlatformGatewayCredentialRequest request, CancellationToken cancellationToken = default);
// Mints (or returns) the Payment-Service Platform for a client; call once at
// client activation and store the returned PlatformId on Client.FKPaymentPlatformId.
Task<(Guid PlatformId, string ApiKey, string HmacSecret)> ProvisionPlatformAsync(
Guid clientId, string displayName, CancellationToken cancellationToken = default);
}
}
@@ -0,0 +1,20 @@
using Fitness_core_BE.DTOs.PaymentsEnablement;
using Fitness_core_BE.DTOs.PaymentGateways;
using Microsoft.AspNetCore.Http;
namespace Fitness_core_BE.Interfaces.Services
{
public interface IPaymentsEnablementService
{
Task<List<PaymentTrackOption>> GetTrackOptionsAsync();
Task<PaymentTrackSelectionResult> SelectTrackAsync(HttpContext httpContext, SelectPaymentTrackRequest request);
Task<List<GatewayDefinitionDto>> GetAvailableGatewaysAsync(CancellationToken ct = default);
Task<ClientPayoutKycDto> SubmitKycAsync(
HttpContext httpContext,
SubmitGatewayOnboardingRequest request,
CancellationToken ct = default);
Task<GatewayOnboardingStatusDto> GetKycStatusAsync(HttpContext httpContext);
Task<WalletDto> GetWalletAsync(HttpContext httpContext);
Task<PayoutScheduleDto> GetPayoutScheduleAsync(HttpContext httpContext);
}
}
@@ -0,0 +1,12 @@
using Fitness_core_BE.DTOs.PaymentsEnablement;
using Microsoft.AspNetCore.Http;
namespace Fitness_core_BE.Interfaces.Services
{
public interface IPayoutKycReviewService
{
Task<List<ClientPayoutKycDto>> ListAsync(string? status);
Task<ClientPayoutKycDto> GetByClientIdAsync(Guid clientId);
Task<ClientPayoutKycDto> ReviewAsync(Guid clientId, ReviewPayoutKycRequest request, HttpContext httpContext);
}
}
+13
View File
@@ -0,0 +1,13 @@
using Microsoft.AspNetCore.Http;
namespace Fitness_core_BE.Interfaces.Services
{
public record PermissionContext(bool IsOwner, Guid? ClientId, Guid? StaffId, IReadOnlySet<string> AllowedNavKeys);
public interface IPermissionService
{
// Single shared source of truth for "what can this caller see/do" — used by both
// RequiresPermissionAttribute and NavController so they can never drift apart.
Task<PermissionContext> GetPermissionContextAsync(HttpContext httpContext);
}
}
+13
View File
@@ -0,0 +1,13 @@
using Microsoft.AspNetCore.Http;
namespace Fitness_core_BE.Interfaces.Services
{
public interface IPlaceService
{
Task<object> GetAllPlaces(object payload, HttpContext httpContext);
Task<object> CreatePlace(object payload, HttpContext httpContext);
Task<object> UpdatePlace(object payload, HttpContext httpContext);
Task<object> SetPlaceStatus(object payload, HttpContext httpContext);
Task<object> AssignDevice(object payload, HttpContext httpContext);
}
}
@@ -0,0 +1,28 @@
using Fitness_core_BE.DTOs.PlatformBilling;
using Fitness_core_BE.Models;
namespace Fitness_core_BE.Interfaces.Services
{
// Computes and generates the platform's own bill to a gym ("Client"): a per-active-member
// SaaS fee (with minimum/cap), device rental, and one-time setup fees. Distinct from
// CustomerInvoice/CustomerSubscription, which is the gym billing its own members.
public interface IPlatformBillingService
{
Task<List<PricingPlanDto>> GetPricingPlansAsync(CancellationToken ct = default);
Task<PricingPlanDto> UpsertPricingPlanAsync(UpsertPricingPlanRequest request, CancellationToken ct = default);
Task<DevicePricingDto> GetDevicePricingAsync(CancellationToken ct = default);
Task<DevicePricingDto> UpdateDevicePricingAsync(DevicePricingDto request, CancellationToken ct = default);
Task<Models.ClientInvoice> AssignPricingPlanAsync(Guid clientId, AssignPricingPlanRequest request, CancellationToken ct = default);
Task<PlatformFeeBreakdownDto> ComputeMonthlyFeeAsync(Guid clientId, CancellationToken ct = default);
Task<Models.ClientInvoice> GenerateMonthlyInvoiceAsync(Guid clientId, CancellationToken ct = default);
Task<Models.ClientInvoice> GenerateOnboardingInvoiceAsync(Guid clientId, CancellationToken ct = default);
Task<List<Models.ClientInvoice>> RunMonthlyBillingForAllClientsAsync(CancellationToken ct = default);
Task<SubscriptionChargeRunResult> RunAndChargeSubscriptionBillingAsync(CancellationToken ct = default);
Task<List<PendingPlatformInvoiceDto>> GetPendingInvoicesAsync(CancellationToken ct = default);
Task<List<PendingPlatformInvoiceDto>> GetCompletedInvoicesAsync(CancellationToken ct = default);
Task<PendingPlatformInvoiceDto> RecordClientInvoicePaymentAsync(Guid clientInvoiceId, decimal amount, CancellationToken ct = default);
Task<object> SendClientPaymentLinkAsync(Guid clientInvoiceId, CancellationToken ct = default);
}
}
+16
View File
@@ -0,0 +1,16 @@
using Fitness_core_BE.DTOs.Ledger;
using Microsoft.AspNetCore.Http;
namespace Fitness_core_BE.Interfaces.Services
{
// Basic P&L / ledger for the client portal. Derives income (approved member payments)
// and expenses (platform fees paid, staff payroll) from existing tables, and merges in
// manual ledger entries (LedgerEntry) for anything else (rent, utilities, misc income).
public interface IProfitLossService
{
Task<ProfitLossDto> GetProfitLossAsync(DateTime from, DateTime to, HttpContext httpContext);
Task<List<LedgerEntryDto>> GetManualEntriesAsync(DateTime from, DateTime to, HttpContext httpContext);
Task<LedgerEntryDto> AddManualEntryAsync(AddLedgerEntryRequest request, HttpContext httpContext);
Task DeleteManualEntryAsync(Guid id, HttpContext httpContext);
}
}
@@ -0,0 +1,25 @@
namespace Fitness_core_BE.Interfaces.Services
{
public interface IPushNotificationService
{
// Persists a CustomerNotification row (for the mobile Notification tab) and, if the
// customer has a registered Expo push token, sends a real push too. routeName/routeParams
// mirror the mobile app's PushNavigationData contract (pushNotification.ts) so tapping
// either the push or the in-app list item navigates the same way.
Task NotifyCustomerAsync(
Guid customerId,
string title,
string body,
string notificationType,
string? routeName = null,
object? routeParams = null);
Task NotifyCustomersAsync(
IEnumerable<Guid> customerIds,
string title,
string body,
string notificationType,
string? routeName = null,
object? routeParams = null);
}
}
+20
View File
@@ -0,0 +1,20 @@
using Fitness_core_BE.Models.Receipt;
namespace Fitness_core_BE.Interfaces.Services
{
public interface IReceiptService
{
/// <summary>Gathers member/plan/gym/amount data for a member invoice.
/// When <paramref name="requireClientId"/> is set, throws if the invoice isn't that gym's.</summary>
Task<ReceiptModel> BuildForInvoiceAsync(Guid customerInvoiceId, decimal? paymentAmount = null, Guid? requireClientId = null);
/// <summary>Gathers gym/amount data for a platform (HexaFitness -> gym) invoice.
/// When <paramref name="requireClientId"/> is set, throws if the invoice isn't that gym's.</summary>
Task<ReceiptModel> BuildForClientInvoiceAsync(Guid clientInvoiceId, decimal? paymentAmount = null, Guid? requireClientId = null);
byte[] GeneratePdf(ReceiptModel model);
/// <summary>Best-effort: emails the receipt PDF and texts the member. Never throws.</summary>
Task SendReceiptAsync(ReceiptModel model);
}
}
+20
View File
@@ -0,0 +1,20 @@
using Microsoft.AspNetCore.Http;
namespace Fitness_core_BE.Interfaces.Services
{
public interface IStaffService
{
Task<object> GetAllStaff(object payload, HttpContext httpContext);
Task<object> GetStaffById(object payload, HttpContext httpContext);
Task<object> GetStaffByClientId(object payload, HttpContext httpContext);
Task<object> CreateStaff(object payload, HttpContext httpContext);
Task<object> UpdateStaff(object payload, HttpContext httpContext);
Task<object> DeleteStaff(object payload, HttpContext httpContext);
// Basic HRM/payroll (req 5).
Task<object> GetPayRate(Guid staffId, HttpContext httpContext);
Task<object> UpsertPayRate(Guid staffId, string rateType, decimal amount, HttpContext httpContext);
Task<object> GetPayments(Guid staffId, HttpContext httpContext);
Task<object> RecordPayment(Guid staffId, decimal amount, string? note, HttpContext httpContext);
}
}
@@ -0,0 +1,14 @@
using Microsoft.AspNetCore.Http;
namespace Fitness_core_BE.Interfaces.Services
{
// Staff-facing approval workflow for the unapproved (IsActive=false) invoices the daily
// SubscriptionRenewalJob sweep creates. See Services/SubscriptionRenewalApprovalService.cs.
public interface ISubscriptionRenewalApprovalService
{
Task<object> GetUnapprovedInvoicesAsync(HttpContext httpContext);
Task<object> ApproveAsync(Guid customerInvoiceId, HttpContext httpContext);
Task<object> ChangePlanAsync(Guid customerInvoiceId, Guid newCustomerPlanId, HttpContext httpContext);
Task<object> RejectAsync(Guid customerInvoiceId, HttpContext httpContext);
}
}
+11
View File
@@ -0,0 +1,11 @@
using Fitness_core_BE.Models.IOs;
namespace Fitness_core_BE.Interfaces.Services
{
/// <summary>Outbound notification channels (SMS + email) — mirrors Core-Hex-Auth's ThirdPartyService.</summary>
public interface IThirdPartyService
{
Task<OtpResponse> SendSmsAsync(string mobileNumber, string? otpCode = null, string? message = null);
Task SendEmailAsync(string toEmail, string subject, string htmlBody, byte[]? attachment = null, string? attachmentName = null);
}
}
+18
View File
@@ -0,0 +1,18 @@
using Microsoft.AspNetCore.Http;
namespace Fitness_core_BE.Interfaces.Services
{
public interface ITicketService
{
Task<object> GetTicketList(object payload, HttpContext httpContext);
Task<object> GetTicketByUserId(object payload, HttpContext httpContext);
Task<object> GetTicketById(object payload, HttpContext httpContext);
Task<object> GetTicketCategoryList(object payload, HttpContext httpContext);
Task<object> CreateTicket(object payload, HttpContext httpContext);
Task<object> UpdateTicket(object payload, HttpContext httpContext);
Task<object> SendMessage(object payload, HttpContext httpContext);
Task<object> SubmitTicketFeedback(object payload, HttpContext httpContext);
Task<object> CloseTicket(object payload, HttpContext httpContext);
Task<object> DeleteTicket(object payload, HttpContext httpContext);
}
}
@@ -0,0 +1,18 @@
using Microsoft.AspNetCore.Http;
namespace Fitness_core_BE.Interfaces.Services
{
public interface ITimeBankCardService
{
/// <summary>Staff issues/sells a card -- minutes purchased, optionally linked to a member.</summary>
Task<object> IssueCard(object payload, HttpContext httpContext);
/// <summary>The tap-in/tap-out swipe action: first swipe on a card starts its session
/// (no deduction), second swipe ends it and deducts the elapsed minutes. No login
/// required (called by the reader/agent, or by staff at a manual terminal).</summary>
Task<object> Swipe(object payload);
Task<object> GetBalance(object payload);
Task<object> GetMyCards(object payload, HttpContext httpContext);
}
}
+21
View File
@@ -0,0 +1,21 @@
using Microsoft.AspNetCore.Http;
namespace Fitness_core_BE.Interfaces.Services
{
public interface IWorkoutService
{
Task<object> GetWorkoutCategoryList(object payload, HttpContext httpContext);
Task<object> CreateWorkoutCategory(object payload, HttpContext httpContext);
Task<object> GetWorkoutPlanList(object payload, HttpContext httpContext);
Task<object> GetWorkoutPlanById(object payload, HttpContext httpContext);
Task<object> GetWorkoutPlanByCustomerId(object payload, HttpContext httpContext);
Task<object> CreateWorkoutPlan(object payload, HttpContext httpContext);
Task<object> CreateCustomerWorkout(object payload, HttpContext httpContext);
Task<object> UpdateWorkoutPlan(object payload, HttpContext httpContext);
Task<object> DeleteWorkoutPlan(object payload, HttpContext httpContext);
Task<object> GetWorkoutItemsByWorkoutPlanId(object payload, HttpContext httpContext);
Task<object> CreateWorkoutItem(object payload, HttpContext httpContext);
Task<object> AssignWorkoutToCustomer(object payload, HttpContext httpContext);
Task<object> UnassignWorkoutFromCustomer(object payload, HttpContext httpContext);
}
}