@gymspace/sdk 1.9.0 → 1.9.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -55,6 +55,9 @@ var NetworkError = class extends GymSpaceError {
55
55
  var ApiClient = class {
56
56
  constructor(config) {
57
57
  this.refreshToken = null;
58
+ this.rememberMe = null;
59
+ this.isRefreshing = false;
60
+ this.failedRequestsQueue = [];
58
61
  this.config = config;
59
62
  this.axiosInstance = axios__default.default.create({
60
63
  baseURL: config.baseURL,
@@ -119,6 +122,74 @@ var ApiClient = class {
119
122
  return response;
120
123
  },
121
124
  async (error) => {
125
+ if (error.response?.status === 401) {
126
+ const originalRequest = error.config;
127
+ if (originalRequest?.skipAuth) {
128
+ throw this.handleError(error);
129
+ }
130
+ if (this.isRefreshing && this.refreshToken) {
131
+ return new Promise((resolve, reject) => {
132
+ this.failedRequestsQueue.push({
133
+ resolve: (token) => {
134
+ if (originalRequest) {
135
+ originalRequest.headers["Authorization"] = `Bearer ${token}`;
136
+ this.axiosInstance.request(originalRequest).then(resolve).catch(reject);
137
+ } else {
138
+ reject(error);
139
+ }
140
+ },
141
+ reject: (err) => {
142
+ reject(err);
143
+ }
144
+ });
145
+ });
146
+ }
147
+ if (this.refreshToken) {
148
+ this.isRefreshing = true;
149
+ try {
150
+ console.log("Access token expired, attempting refresh...");
151
+ const response = await axios__default.default.post(
152
+ `${this.config.baseURL}/auth/members/refresh`,
153
+ { refresh_token: this.refreshToken },
154
+ { headers: { "Content-Type": "application/json" } }
155
+ );
156
+ const { accessToken: newAccessToken, refreshToken: newRefreshToken } = response.data;
157
+ console.log("Token refresh successful");
158
+ this.setAuthToken(newAccessToken);
159
+ if (newRefreshToken) {
160
+ this.setRefreshToken(newRefreshToken);
161
+ }
162
+ if (this.onTokenRefreshed) {
163
+ this.onTokenRefreshed(newAccessToken, newRefreshToken);
164
+ }
165
+ this.failedRequestsQueue.forEach((request) => {
166
+ request.resolve(newAccessToken);
167
+ });
168
+ this.failedRequestsQueue = [];
169
+ if (originalRequest) {
170
+ originalRequest.headers["Authorization"] = `Bearer ${newAccessToken}`;
171
+ return this.axiosInstance.request(originalRequest);
172
+ }
173
+ throw error;
174
+ } catch (refreshError) {
175
+ console.error("Token refresh failed:", refreshError.message);
176
+ this.failedRequestsQueue.forEach((request) => {
177
+ request.reject(refreshError);
178
+ });
179
+ this.failedRequestsQueue = [];
180
+ this.clearAuth();
181
+ const authError = new AuthenticationError(
182
+ refreshError.response?.data?.message || "Token refresh failed"
183
+ );
184
+ if (this.onAuthFailure) {
185
+ this.onAuthFailure(authError);
186
+ }
187
+ throw authError;
188
+ } finally {
189
+ this.isRefreshing = false;
190
+ }
191
+ }
192
+ }
122
193
  throw this.handleError(error);
123
194
  }
124
195
  );
@@ -169,6 +240,9 @@ var ApiClient = class {
169
240
  if (options?.gymId) {
170
241
  headers["X-Gym-Id"] = options.gymId;
171
242
  }
243
+ if (options?.gymContextMode) {
244
+ headers["X-Gym-Context-Mode"] = options.gymContextMode;
245
+ }
172
246
  return { headers };
173
247
  }
174
248
  async request(method, path, data, options) {
@@ -213,6 +287,18 @@ var ApiClient = class {
213
287
  getRefreshToken() {
214
288
  return this.refreshToken;
215
289
  }
290
+ /**
291
+ * Set rememberMe preference from login response
292
+ */
293
+ setRememberMe(value) {
294
+ this.rememberMe = value;
295
+ }
296
+ /**
297
+ * Get rememberMe preference
298
+ */
299
+ getRememberMe() {
300
+ return this.rememberMe;
301
+ }
216
302
  /**
217
303
  * Set callback for when tokens are refreshed by backend
218
304
  */
@@ -225,18 +311,53 @@ var ApiClient = class {
225
311
  getOnTokenRefreshed() {
226
312
  return this.onTokenRefreshed;
227
313
  }
314
+ /**
315
+ * Set callback for when authentication fails irrecoverably
316
+ */
317
+ setOnAuthFailure(callback) {
318
+ this.onAuthFailure = callback;
319
+ }
228
320
  setGymId(gymId) {
229
321
  this.axiosInstance.defaults.headers.common["X-Gym-Id"] = gymId;
230
322
  }
231
323
  clearAuth() {
232
324
  delete this.config.apiKey;
233
325
  this.refreshToken = null;
326
+ this.rememberMe = null;
234
327
  delete this.axiosInstance.defaults.headers.common["Authorization"];
235
328
  delete this.axiosInstance.defaults.headers.common["X-Gym-Id"];
236
329
  }
237
330
  getBaseUrl() {
238
331
  return this.config.baseURL;
239
332
  }
333
+ /**
334
+ * Get config for creating scoped SDK instances
335
+ * Exposes minimal config needed without exposing internal structure
336
+ */
337
+ getConfigForScoped() {
338
+ return {
339
+ baseURL: this.config.baseURL,
340
+ apiKey: this.config.apiKey,
341
+ refreshToken: this.refreshToken,
342
+ headers: this.config.headers
343
+ };
344
+ }
345
+ /**
346
+ * Get axios instance defaults for scoped SDK
347
+ */
348
+ getAxiosDefaults() {
349
+ return { ...this.axiosInstance.defaults.headers.common };
350
+ }
351
+ /**
352
+ * Set common headers on axios instance (for scoped SDK setup)
353
+ */
354
+ setCommonHeaders(headers) {
355
+ Object.entries(headers).forEach(([key, value]) => {
356
+ if (value !== void 0) {
357
+ this.axiosInstance.defaults.headers.common[key] = value;
358
+ }
359
+ });
360
+ }
240
361
  };
241
362
 
242
363
  // src/utils/agent-fetch.ts
@@ -304,8 +425,12 @@ var AuthResource = class extends BaseResource {
304
425
  async registerOwner(data, options) {
305
426
  return this.client.post(`${this.basePath}/register/owner`, data, options);
306
427
  }
307
- async login(data, options) {
308
- return this.client.post(`${this.basePath}/login`, data, options);
428
+ async login(data, options, rememberMe) {
429
+ return this.client.post(
430
+ `${this.basePath}/login`,
431
+ { ...data, rememberMe },
432
+ options
433
+ );
309
434
  }
310
435
  async refreshToken(refreshToken, options) {
311
436
  return this.client.post(
@@ -372,6 +497,39 @@ var AuthResource = class extends BaseResource {
372
497
  options
373
498
  );
374
499
  }
500
+ /**
501
+ * Member login with PIN
502
+ * POST /auth/members/pin/login
503
+ */
504
+ async memberPinLogin(data, options) {
505
+ return this.client.post(
506
+ `${this.basePath}/members/pin/login`,
507
+ data,
508
+ options
509
+ );
510
+ }
511
+ /**
512
+ * Consume member invite and set initial PIN
513
+ * POST /auth/members/invite/consume
514
+ */
515
+ async consumeMemberInvite(data, options) {
516
+ return this.client.post(
517
+ `${this.basePath}/members/invite/consume`,
518
+ data,
519
+ options
520
+ );
521
+ }
522
+ /**
523
+ * Refresh member access token
524
+ * POST /auth/members/refresh
525
+ */
526
+ async refreshMemberToken(refreshToken, options) {
527
+ return this.client.post(
528
+ `${this.basePath}/members/refresh`,
529
+ { refresh_token: refreshToken },
530
+ options
531
+ );
532
+ }
375
533
  };
376
534
 
377
535
  // src/resources/organizations.ts
@@ -599,6 +757,16 @@ var ClientsResource = class extends BaseResource {
599
757
  async searchClientsForCheckIn(params, options) {
600
758
  return this.client.get(`${this.basePath}/search/check-in`, params, options);
601
759
  }
760
+ async searchGlobal(params, options) {
761
+ return this.client.post(`${this.basePath}/search-global`, params, options);
762
+ }
763
+ async importFromGym(params, options) {
764
+ return this.client.post(
765
+ `${this.basePath}/import-from-gym`,
766
+ params,
767
+ options
768
+ );
769
+ }
602
770
  };
603
771
 
604
772
  // src/resources/membership-plans.ts
@@ -646,9 +814,40 @@ var ContractsResource = class extends BaseResource {
646
814
  async getContract(id, options) {
647
815
  return this.client.get(`${this.basePath}/${id}`, void 0, options);
648
816
  }
817
+ async getContractInstallments(id, options) {
818
+ return this.client.get(
819
+ `${this.basePath}/${id}/installments`,
820
+ void 0,
821
+ options
822
+ );
823
+ }
824
+ async getContractPayments(id, options) {
825
+ return this.client.get(
826
+ `${this.basePath}/${id}/payments`,
827
+ void 0,
828
+ options
829
+ );
830
+ }
831
+ async registerContractPayment(id, data, options) {
832
+ return this.client.post(
833
+ `${this.basePath}/${id}/payments`,
834
+ data,
835
+ options
836
+ );
837
+ }
838
+ async sendInstallmentReminder(id, installmentId, options) {
839
+ return this.client.post(
840
+ `${this.basePath}/${id}/installments/${installmentId}/send-reminder`,
841
+ {},
842
+ options
843
+ );
844
+ }
649
845
  async getClientContracts(clientId, options) {
650
846
  return this.client.get(`${this.basePath}/client/${clientId}`, void 0, options);
651
847
  }
848
+ async getMyContracts(options) {
849
+ return this.client.get("auth/members/me/contracts", void 0, options);
850
+ }
652
851
  async renewContract(id, data, options) {
653
852
  return this.client.post(`${this.basePath}/${id}/renew`, data, options);
654
853
  }
@@ -723,6 +922,14 @@ var DashboardResource = class extends BaseResource {
723
922
  async getDebts(params) {
724
923
  return this.client.get("/dashboard/debts", params);
725
924
  }
925
+ /**
926
+ * Get total collections within date range
927
+ * @param params Optional date range parameters
928
+ * @returns Collections data for the specified period
929
+ */
930
+ async getCollections(params) {
931
+ return this.client.get("/dashboard/collections", params);
932
+ }
726
933
  /**
727
934
  * Get check-ins count within date range
728
935
  * @param params Optional date range parameters
@@ -828,6 +1035,21 @@ var CheckInsResource = class extends BaseResource {
828
1035
  options
829
1036
  );
830
1037
  }
1038
+ /**
1039
+ * Creates a check-in for an external client (from another gym in the same organization).
1040
+ *
1041
+ * **Permissions Required:**
1042
+ * - Gym owners with full gym access
1043
+ * - Active collaborators with CHECKINS_CREATE permission
1044
+ *
1045
+ * @param data - The external check-in data including document value
1046
+ * @param options - Optional request configuration
1047
+ * @returns The created check-in record with external client details
1048
+ * @throws {ValidationError} When client is not found or contract doesn't allow access
1049
+ */
1050
+ async createExternal(data, options) {
1051
+ return this.client.post(`${this.basePath}/external`, data, options);
1052
+ }
831
1053
  };
832
1054
 
833
1055
  // src/resources/invitations.ts
@@ -2379,8 +2601,68 @@ var PromoCodesResource = class extends BaseResource {
2379
2601
  }
2380
2602
  };
2381
2603
 
2604
+ // src/resources/members.ts
2605
+ var MembersResource = class extends BaseResource {
2606
+ /**
2607
+ * Create and send member invite
2608
+ * POST /admin/members/clients/:id/invites
2609
+ */
2610
+ async createInvite(clientId, data, options) {
2611
+ return this.client.post(
2612
+ `admin/members/clients/${clientId}/invites`,
2613
+ data,
2614
+ options
2615
+ );
2616
+ }
2617
+ /**
2618
+ * Validate member invite token
2619
+ * GET /members/invites/validate/:token
2620
+ */
2621
+ async validateInvite(token, options) {
2622
+ return this.client.get(
2623
+ `members/invites/validate/${token}`,
2624
+ void 0,
2625
+ options
2626
+ );
2627
+ }
2628
+ /**
2629
+ * Generate QR token for member check-ins
2630
+ * GET /admin/members/check-in-qr
2631
+ */
2632
+ async generateQrToken(options) {
2633
+ return this.client.get("admin/members/check-in-qr", void 0, options);
2634
+ }
2635
+ /**
2636
+ * Self check-in with QR token
2637
+ * POST /members/checkins
2638
+ */
2639
+ async checkIn(data, options) {
2640
+ return this.client.post("members/checkins", data, options);
2641
+ }
2642
+ };
2643
+
2644
+ // src/resources/receivables.ts
2645
+ var ReceivablesResource = class extends BaseResource {
2646
+ /**
2647
+ * Get paginated list of pending contract installments with filtering, sorting, and organization scope support.
2648
+ * @param params Optional query parameters for filtering, pagination, and sorting
2649
+ * @returns Paginated list of installment receivables with summary
2650
+ */
2651
+ async getInstallmentReceivables(params) {
2652
+ return this.client.get("/receivables/installments", params);
2653
+ }
2654
+ /**
2655
+ * Get paginated list of unpaid sales with filtering, sorting, and organization scope support.
2656
+ * @param params Optional query parameters for filtering, pagination, and sorting
2657
+ * @returns Paginated list of sale receivables with summary
2658
+ */
2659
+ async getSaleReceivables(params) {
2660
+ return this.client.get("/receivables/sales", params);
2661
+ }
2662
+ };
2663
+
2382
2664
  // src/sdk.ts
2383
- var GymSpaceSdk = class {
2665
+ var GymSpaceSdk = class _GymSpaceSdk {
2384
2666
  constructor(config) {
2385
2667
  this.client = new ApiClient(config);
2386
2668
  this.auth = new AuthResource(this.client);
@@ -2422,6 +2704,8 @@ var GymSpaceSdk = class {
2422
2704
  this.credits = new CreditsResource(this.client);
2423
2705
  this.pricingPackages = new PricingPackagesResource(this.client);
2424
2706
  this.promoCodes = new PromoCodesResource(this.client);
2707
+ this.members = new MembersResource(this.client);
2708
+ this.receivables = new ReceivablesResource(this.client);
2425
2709
  }
2426
2710
  /**
2427
2711
  * Set the authentication token
@@ -2480,7 +2764,44 @@ var GymSpaceSdk = class {
2480
2764
  getClient() {
2481
2765
  return this.client;
2482
2766
  }
2767
+ /**
2768
+ * Create a scoped SDK instance that sends X-Gym-Id and X-Gym-Context-Mode: scoped
2769
+ * for all requests WITHOUT modifying the global gym context.
2770
+ *
2771
+ * Usage:
2772
+ * const scopedSdk = sdk.withGymId('gym-123');
2773
+ * const sales = await scopedSdk.sales.searchSales({ ... });
2774
+ */
2775
+ withGymId(gymId) {
2776
+ const config = this.client.getConfigForScoped();
2777
+ const defaults = this.client.getAxiosDefaults();
2778
+ const scopedSdk = new _GymSpaceSdk({
2779
+ baseURL: config.baseURL,
2780
+ apiKey: config.apiKey,
2781
+ refreshToken: config.refreshToken
2782
+ });
2783
+ if (defaults && typeof defaults === "object") {
2784
+ const headers = {};
2785
+ Object.entries(defaults).forEach(([key, value]) => {
2786
+ if (typeof value === "string") {
2787
+ headers[key] = value;
2788
+ }
2789
+ });
2790
+ scopedSdk.client.setCommonHeaders(headers);
2791
+ }
2792
+ const originalRequest = scopedSdk.client.request.bind(scopedSdk.client);
2793
+ scopedSdk.client.request = (method, path, data, options) => {
2794
+ return originalRequest(method, path, data, {
2795
+ ...options,
2796
+ gymId,
2797
+ gymContextMode: "scoped"
2798
+ });
2799
+ };
2800
+ return scopedSdk;
2801
+ }
2483
2802
  };
2803
+
2804
+ // ../shared/src/types/whatsapp-templates.types.ts
2484
2805
  var TemplateCode = {
2485
2806
  WELCOME: "WELCOME",
2486
2807
  MEMBERSHIP_PURCHASE: "MEMBERSHIP_PURCHASE",
@@ -2490,12 +2811,16 @@ var TemplateCode = {
2490
2811
  BIRTHDAY: "BIRTHDAY",
2491
2812
  PAYMENT_RECEIPT: "PAYMENT_RECEIPT",
2492
2813
  SHARE_CATALOG: "SHARE_CATALOG",
2493
- SALE_PAYMENT_REMINDER: "SALE_PAYMENT_REMINDER"
2814
+ SALE_PAYMENT_REMINDER: "SALE_PAYMENT_REMINDER",
2815
+ MEMBER_INVITE: "MEMBER_INVITE",
2816
+ CONTRACT_INSTALLMENT_REMINDER: "CONTRACT_INSTALLMENT_REMINDER"
2494
2817
  };
2495
2818
  var TemplateType = {
2496
2819
  STATIC: "STATIC",
2497
2820
  PROMPT: "PROMPT"
2498
2821
  };
2822
+
2823
+ // ../shared/src/constants/template-codes.constants.ts
2499
2824
  var TEMPLATE_CODES = {
2500
2825
  WELCOME: TemplateCode.WELCOME,
2501
2826
  MEMBERSHIP_PURCHASE: TemplateCode.MEMBERSHIP_PURCHASE,
@@ -2505,7 +2830,9 @@ var TEMPLATE_CODES = {
2505
2830
  BIRTHDAY: TemplateCode.BIRTHDAY,
2506
2831
  PAYMENT_RECEIPT: TemplateCode.PAYMENT_RECEIPT,
2507
2832
  SHARE_CATALOG: TemplateCode.SHARE_CATALOG,
2508
- SALE_PAYMENT_REMINDER: TemplateCode.SALE_PAYMENT_REMINDER
2833
+ SALE_PAYMENT_REMINDER: TemplateCode.SALE_PAYMENT_REMINDER,
2834
+ MEMBER_INVITE: TemplateCode.MEMBER_INVITE,
2835
+ CONTRACT_INSTALLMENT_REMINDER: TemplateCode.CONTRACT_INSTALLMENT_REMINDER
2509
2836
  };
2510
2837
  var WHATSAPP_TEMPLATE_EVENTS = {
2511
2838
  SEND_TEMPLATE: "whatsapp/template.send",
@@ -2662,8 +2989,48 @@ var TEMPLATE_METADATA = {
2662
2989
  ],
2663
2990
  currency: "S/ "
2664
2991
  }
2992
+ },
2993
+ [TemplateCode.MEMBER_INVITE]: {
2994
+ code: TemplateCode.MEMBER_INVITE,
2995
+ title: "Invitaci\xF3n Portal de Miembros",
2996
+ description: "Invitaci\xF3n para que el socio se registre en el portal",
2997
+ icon: "UserPlus",
2998
+ variables: ["clientName", "gymName", "inviteCode", "inviteUrl", "expiryDate"],
2999
+ exampleValues: {
3000
+ clientName: "Juan P\xE9rez",
3001
+ gymName: "GymSpace",
3002
+ inviteCode: "123456",
3003
+ inviteUrl: "https://gymspace.app/members/invite/abc-123",
3004
+ expiryDate: "20/02/2024"
3005
+ }
3006
+ },
3007
+ [TemplateCode.CONTRACT_INSTALLMENT_REMINDER]: {
3008
+ code: TemplateCode.CONTRACT_INSTALLMENT_REMINDER,
3009
+ title: "Recordatorio de Cuota de Contrato",
3010
+ description: "Recordatorio de pago para cuotas de membres\xEDa",
3011
+ icon: "DollarSign",
3012
+ variables: [
3013
+ "clientName",
3014
+ "planName",
3015
+ "contractNumber",
3016
+ "installmentNumber",
3017
+ "dueDate",
3018
+ "amount",
3019
+ "outstandingAmount"
3020
+ ],
3021
+ exampleValues: {
3022
+ clientName: "Mar\xEDa L\xF3pez",
3023
+ planName: "Premium",
3024
+ contractNumber: "#202512340001",
3025
+ installmentNumber: "2",
3026
+ dueDate: "25/02/2024",
3027
+ amount: "S/ 150.00",
3028
+ outstandingAmount: "S/ 300.00"
3029
+ }
2665
3030
  }
2666
3031
  };
3032
+
3033
+ // ../shared/src/constants/bulk-message-variables.ts
2667
3034
  var BULK_MESSAGE_VARIABLES = [
2668
3035
  // Variables de Cliente
2669
3036
  {
@@ -2693,6 +3060,33 @@ var BULK_MESSAGE_VARIABLES = [
2693
3060
  required: false,
2694
3061
  formatter: "text"
2695
3062
  },
3063
+ {
3064
+ name: "registrationDate",
3065
+ placeholder: "{{registrationDate}}",
3066
+ description: "Fecha de registro del cliente",
3067
+ example: "15/10/2024",
3068
+ category: "client",
3069
+ required: false,
3070
+ formatter: "date"
3071
+ },
3072
+ {
3073
+ name: "birthDate",
3074
+ placeholder: "{{birthDate}}",
3075
+ description: "Fecha de nacimiento del cliente",
3076
+ example: "15/10/1990",
3077
+ category: "client",
3078
+ required: false,
3079
+ formatter: "date"
3080
+ },
3081
+ {
3082
+ name: "age",
3083
+ placeholder: "{{age}}",
3084
+ description: "Edad del cliente",
3085
+ example: "34",
3086
+ category: "client",
3087
+ required: false,
3088
+ formatter: "number"
3089
+ },
2696
3090
  // Variables de Gimnasio
2697
3091
  {
2698
3092
  name: "gymName",
@@ -2767,6 +3161,60 @@ var BULK_MESSAGE_VARIABLES = [
2767
3161
  required: false,
2768
3162
  formatter: "currency"
2769
3163
  },
3164
+ {
3165
+ name: "startDate",
3166
+ placeholder: "{{startDate}}",
3167
+ description: "Fecha de inicio de membres\xEDa",
3168
+ example: "15/10/2024",
3169
+ category: "membership",
3170
+ required: false,
3171
+ formatter: "date"
3172
+ },
3173
+ {
3174
+ name: "endDate",
3175
+ placeholder: "{{endDate}}",
3176
+ description: "Fecha de fin de membres\xEDa",
3177
+ example: "15/11/2024",
3178
+ category: "membership",
3179
+ required: false,
3180
+ formatter: "date"
3181
+ },
3182
+ {
3183
+ name: "newEndDate",
3184
+ placeholder: "{{newEndDate}}",
3185
+ description: "Nueva fecha de vencimiento por renovaci\xF3n",
3186
+ example: "15/12/2024",
3187
+ category: "membership",
3188
+ required: false,
3189
+ formatter: "date"
3190
+ },
3191
+ {
3192
+ name: "paymentFrequency",
3193
+ placeholder: "{{paymentFrequency}}",
3194
+ description: "Frecuencia de pago",
3195
+ example: "Mensual",
3196
+ category: "membership",
3197
+ required: false,
3198
+ formatter: "text"
3199
+ },
3200
+ {
3201
+ name: "daysRemaining",
3202
+ placeholder: "{{daysRemaining}}",
3203
+ description: "D\xEDas restantes",
3204
+ example: "15",
3205
+ category: "membership",
3206
+ required: false,
3207
+ formatter: "number"
3208
+ },
3209
+ {
3210
+ name: "dueDate",
3211
+ placeholder: "{{dueDate}}",
3212
+ description: "Fecha de vencimiento de pago",
3213
+ example: "15/10/2024",
3214
+ category: "membership",
3215
+ required: false,
3216
+ formatter: "date"
3217
+ },
2770
3218
  // Variables de Fecha/Hora
2771
3219
  {
2772
3220
  name: "date",
@@ -2921,6 +3369,8 @@ var BULK_MESSAGE_VARIABLE_CATEGORIES = {
2921
3369
  activity: "Actividad",
2922
3370
  datetime: "Fecha/Hora"
2923
3371
  };
3372
+
3373
+ // ../shared/src/constants.ts
2924
3374
  var PERMISSIONS = {
2925
3375
  // Organizations
2926
3376
  ORGANIZATIONS_CREATE: "ORGANIZATIONS_CREATE",
@@ -2946,8 +3396,14 @@ var PERMISSIONS = {
2946
3396
  CONTRACTS_CREATE: "CONTRACTS_CREATE",
2947
3397
  CONTRACTS_READ: "CONTRACTS_READ",
2948
3398
  CONTRACTS_UPDATE: "CONTRACTS_UPDATE",
3399
+ CONTRACTS_DELETE: "CONTRACTS_DELETE",
2949
3400
  CONTRACTS_APPROVE: "CONTRACTS_APPROVE",
2950
3401
  CONTRACTS_CANCEL: "CONTRACTS_CANCEL",
3402
+ // Membership Plans
3403
+ MEMBERSHIP_PLANS_CREATE: "MEMBERSHIP_PLANS_CREATE",
3404
+ MEMBERSHIP_PLANS_READ: "MEMBERSHIP_PLANS_READ",
3405
+ MEMBERSHIP_PLANS_UPDATE: "MEMBERSHIP_PLANS_UPDATE",
3406
+ MEMBERSHIP_PLANS_DELETE: "MEMBERSHIP_PLANS_DELETE",
2951
3407
  // Check-ins
2952
3408
  CHECKINS_CREATE: "CHECKINS_CREATE",
2953
3409
  CHECKINS_READ: "CHECKINS_READ",
@@ -3025,6 +3481,12 @@ var PERMISSIONS = {
3025
3481
  CATALOG_READ: "CATALOG_READ",
3026
3482
  CATALOG_UPDATE: "CATALOG_UPDATE",
3027
3483
  CATALOG_MANAGE: "CATALOG_MANAGE",
3484
+ // Credits
3485
+ CREDITS_READ: "CREDITS_READ",
3486
+ CREDITS_MANAGE: "CREDITS_MANAGE",
3487
+ CREDITS_ADJUST: "CREDITS_ADJUST",
3488
+ // Members
3489
+ MEMBERS_PORTAL_ACCESS: "MEMBERS_PORTAL_ACCESS",
3028
3490
  // Special permissions
3029
3491
  SUPER_ADMIN: "SUPER_ADMIN",
3030
3492
  OWNER: "OWNER",
@@ -3112,6 +3574,8 @@ var HEADERS = {
3112
3574
  GYM_ID: "X-Gym-Id",
3113
3575
  REQUEST_ID: "X-Request-Id"
3114
3576
  };
3577
+
3578
+ // ../shared/src/enums.ts
3115
3579
  var UserType = /* @__PURE__ */ ((UserType2) => {
3116
3580
  UserType2["OWNER"] = "owner";
3117
3581
  UserType2["COLLABORATOR"] = "collaborator";
@@ -3190,6 +3654,14 @@ var PaymentFrequency = /* @__PURE__ */ ((PaymentFrequency2) => {
3190
3654
  PaymentFrequency2["ANNUAL"] = "annual";
3191
3655
  return PaymentFrequency2;
3192
3656
  })(PaymentFrequency || {});
3657
+ var ContractInstallmentStatus = /* @__PURE__ */ ((ContractInstallmentStatus2) => {
3658
+ ContractInstallmentStatus2["PENDING"] = "pending";
3659
+ ContractInstallmentStatus2["PARTIALLY_PAID"] = "partially_paid";
3660
+ ContractInstallmentStatus2["PAID"] = "paid";
3661
+ ContractInstallmentStatus2["OVERDUE"] = "overdue";
3662
+ ContractInstallmentStatus2["CANCELLED"] = "cancelled";
3663
+ return ContractInstallmentStatus2;
3664
+ })(ContractInstallmentStatus || {});
3193
3665
  var AssetStatus = /* @__PURE__ */ ((AssetStatus2) => {
3194
3666
  AssetStatus2["ACTIVE"] = "active";
3195
3667
  AssetStatus2["DELETED"] = "deleted";
@@ -3220,15 +3692,26 @@ var MessageStatus = /* @__PURE__ */ ((MessageStatus2) => {
3220
3692
  MessageStatus2["CANCELLED"] = "cancelled";
3221
3693
  return MessageStatus2;
3222
3694
  })(MessageStatus || {});
3695
+ var FeatureType = /* @__PURE__ */ ((FeatureType2) => {
3696
+ FeatureType2["AI_GENERATION"] = "ai_generation";
3697
+ FeatureType2["BULK_WHATSAPP"] = "bulk_whatsapp";
3698
+ return FeatureType2;
3699
+ })(FeatureType || {});
3700
+
3701
+ // ../shared/src/events/whatsapp.events.ts
3223
3702
  var WHATSAPP_EVENTS = {
3224
3703
  MESSAGE_SEND: "whatsapp/message.send",
3225
3704
  MESSAGE_RETRY: "whatsapp/message.retry",
3226
3705
  MESSAGE_RECEIVED: "whatsapp/message.received",
3227
3706
  CONNECTION_UPDATE: "whatsapp/connection.update"
3228
3707
  };
3708
+
3709
+ // ../shared/src/events/bulk-messaging.events.ts
3229
3710
  var BULK_MESSAGING_EVENTS = {
3230
3711
  SEND_BULK_MESSAGES: "whatsapp/bulk-messages.send"
3231
3712
  };
3713
+
3714
+ // ../shared/src/events/activity.events.ts
3232
3715
  var ACTIVITY_EVENTS = {
3233
3716
  SEND_ACTIVITY_NOTIFICATION: "activity/notification.send"
3234
3717
  };
@@ -3272,6 +3755,8 @@ var activityNotificationGenerationRequestSchema = zod.z.object({
3272
3755
  var activityNotificationSchema = zod.z.object({
3273
3756
  message: zod.z.string().describe("Generated notification message with activity variables")
3274
3757
  });
3758
+
3759
+ // ../shared/src/utils/roleHelpers.ts
3275
3760
  var RoleNames = /* @__PURE__ */ ((RoleNames2) => {
3276
3761
  RoleNames2["ADMIN"] = "Admin";
3277
3762
  RoleNames2["ENCARGADO"] = "Encargado";
@@ -3280,24 +3765,24 @@ var RoleNames = /* @__PURE__ */ ((RoleNames2) => {
3280
3765
  })(RoleNames || {});
3281
3766
  var ROLE_NAMES = RoleNames;
3282
3767
  function isAdminRole(roleName) {
3283
- return roleName === "Admin";
3768
+ return roleName === "Admin" /* ADMIN */;
3284
3769
  }
3285
3770
  function isEncargadoRole(roleName) {
3286
- return roleName === "Encargado";
3771
+ return roleName === "Encargado" /* ENCARGADO */;
3287
3772
  }
3288
3773
  function canAccessFeature(userRole, allowedRoles) {
3289
3774
  if (!userRole) return false;
3290
- if (userRole === "OWNER") return true;
3775
+ if (userRole === "OWNER" /* OWNER */) return true;
3291
3776
  return allowedRoles.includes(userRole);
3292
3777
  }
3293
3778
  function getRoleDisplayName(roleName) {
3294
3779
  if (!roleName) return "";
3295
3780
  switch (roleName) {
3296
- case "Admin":
3781
+ case "Admin" /* ADMIN */:
3297
3782
  return "Administrador";
3298
- case "Encargado":
3783
+ case "Encargado" /* ENCARGADO */:
3299
3784
  return "Encargado";
3300
- case "OWNER":
3785
+ case "OWNER" /* OWNER */:
3301
3786
  return "Propietario";
3302
3787
  default:
3303
3788
  return roleName;
@@ -3306,11 +3791,11 @@ function getRoleDisplayName(roleName) {
3306
3791
  function getRoleDescription(roleName) {
3307
3792
  if (!roleName) return "";
3308
3793
  switch (roleName) {
3309
- case "Admin":
3794
+ case "Admin" /* ADMIN */:
3310
3795
  return "Acceso completo a todas las funcionalidades del gimnasio, gesti\xF3n de colaboradores y configuraci\xF3n";
3311
- case "Encargado":
3796
+ case "Encargado" /* ENCARGADO */:
3312
3797
  return "Gesti\xF3n diaria del gimnasio: clientes, contratos, check-ins y reportes";
3313
- case "OWNER":
3798
+ case "OWNER" /* OWNER */:
3314
3799
  return "Acceso completo a todas las funcionalidades, organizaci\xF3n y suscripci\xF3n";
3315
3800
  default:
3316
3801
  return "";
@@ -3319,7 +3804,7 @@ function getRoleDescription(roleName) {
3319
3804
  function getRoleCapabilities(roleName) {
3320
3805
  if (!roleName) return [];
3321
3806
  switch (roleName) {
3322
- case "OWNER":
3807
+ case "OWNER" /* OWNER */:
3323
3808
  return [
3324
3809
  "Acceso completo a todas las funcionalidades",
3325
3810
  "Gesti\xF3n de organizaci\xF3n",
@@ -3335,7 +3820,7 @@ function getRoleCapabilities(roleName) {
3335
3820
  "Gesti\xF3n de inventario",
3336
3821
  "Check-ins"
3337
3822
  ];
3338
- case "Admin":
3823
+ case "Admin" /* ADMIN */:
3339
3824
  return [
3340
3825
  "Gesti\xF3n completa de clientes",
3341
3826
  "Gesti\xF3n completa de contratos",
@@ -3348,7 +3833,7 @@ function getRoleCapabilities(roleName) {
3348
3833
  "Gesti\xF3n de inventario",
3349
3834
  "Check-ins"
3350
3835
  ];
3351
- case "Encargado":
3836
+ case "Encargado" /* ENCARGADO */:
3352
3837
  return [
3353
3838
  "Gesti\xF3n de clientes (ver, crear, editar)",
3354
3839
  "Creaci\xF3n y renovaci\xF3n de contratos",
@@ -3361,6 +3846,16 @@ function getRoleCapabilities(roleName) {
3361
3846
  return [];
3362
3847
  }
3363
3848
  }
3849
+
3850
+ // ../shared/src/types/bulk-message.types.ts
3851
+ var MAX_MESSAGES_PER_CAMPAIGN = 10;
3852
+ var MAX_IMAGES_PER_CAMPAIGN = 5;
3853
+ var MAX_CAPTION_LENGTH = 1024;
3854
+ var INTER_MESSAGE_DELAY_MS = 500;
3855
+ var SUPPORTED_MESSAGE_TYPES = ["text", "image"];
3856
+ var ALLOWED_IMAGE_MIMES = ["image/jpeg", "image/jpg", "image/png", "image/webp"];
3857
+
3858
+ // ../shared/src/utils/phone.utils.ts
3364
3859
  function normalizePhoneForEvolution(phoneNumber) {
3365
3860
  if (!phoneNumber) {
3366
3861
  throw new Error("Phone number is required");
@@ -3426,13 +3921,6 @@ var LeadGender = /* @__PURE__ */ ((LeadGender2) => {
3426
3921
  return LeadGender2;
3427
3922
  })(LeadGender || {});
3428
3923
 
3429
- // src/models/credits.ts
3430
- var FeatureType = /* @__PURE__ */ ((FeatureType2) => {
3431
- FeatureType2["AI_GENERATION"] = "ai_generation";
3432
- FeatureType2["BULK_WHATSAPP"] = "bulk_whatsapp";
3433
- return FeatureType2;
3434
- })(FeatureType || {});
3435
-
3436
3924
  // src/models/promo-codes.ts
3437
3925
  var DiscountType = /* @__PURE__ */ ((DiscountType2) => {
3438
3926
  DiscountType2["PERCENTAGE"] = "PERCENTAGE";
@@ -3442,6 +3930,7 @@ var DiscountType = /* @__PURE__ */ ((DiscountType2) => {
3442
3930
 
3443
3931
  exports.ACTIVITY_EVENTS = ACTIVITY_EVENTS;
3444
3932
  exports.ACTIVITY_MESSAGE_VARIABLES = ACTIVITY_MESSAGE_VARIABLES;
3933
+ exports.ALLOWED_IMAGE_MIMES = ALLOWED_IMAGE_MIMES;
3445
3934
  exports.ActivitiesResource = ActivitiesResource;
3446
3935
  exports.AdminCatalogResource = AdminCatalogResource;
3447
3936
  exports.AdminSubscriptionManagementResource = AdminSubscriptionManagementResource;
@@ -3473,6 +3962,7 @@ exports.CommissionRuleType = CommissionRuleType;
3473
3962
  exports.CommissionRulesResource = CommissionRulesResource;
3474
3963
  exports.CommissionStatus = CommissionStatus;
3475
3964
  exports.ContractAssetType = ContractAssetType;
3965
+ exports.ContractInstallmentStatus = ContractInstallmentStatus;
3476
3966
  exports.ContractStatus = ContractStatus;
3477
3967
  exports.ContractsResource = ContractsResource;
3478
3968
  exports.CreditsResource = CreditsResource;
@@ -3487,9 +3977,14 @@ exports.GymSpaceSdk = GymSpaceSdk;
3487
3977
  exports.GymsResource = GymsResource;
3488
3978
  exports.HEADERS = HEADERS;
3489
3979
  exports.HealthResource = HealthResource;
3980
+ exports.INTER_MESSAGE_DELAY_MS = INTER_MESSAGE_DELAY_MS;
3490
3981
  exports.InvitationStatus = InvitationStatus;
3491
3982
  exports.InvitationsResource = InvitationsResource;
3492
3983
  exports.LeadGender = LeadGender;
3984
+ exports.MAX_CAPTION_LENGTH = MAX_CAPTION_LENGTH;
3985
+ exports.MAX_IMAGES_PER_CAMPAIGN = MAX_IMAGES_PER_CAMPAIGN;
3986
+ exports.MAX_MESSAGES_PER_CAMPAIGN = MAX_MESSAGES_PER_CAMPAIGN;
3987
+ exports.MembersResource = MembersResource;
3493
3988
  exports.MembershipPlansResource = MembershipPlansResource;
3494
3989
  exports.MessageStatus = MessageStatus;
3495
3990
  exports.MessagesResource = MessagesResource;
@@ -3511,8 +4006,10 @@ exports.PromoCodesResource = PromoCodesResource;
3511
4006
  exports.PublicCatalogResource = PublicCatalogResource;
3512
4007
  exports.ROLE_NAMES = ROLE_NAMES;
3513
4008
  exports.ROLE_PERMISSIONS = ROLE_PERMISSIONS;
4009
+ exports.ReceivablesResource = ReceivablesResource;
3514
4010
  exports.RoleNames = RoleNames;
3515
4011
  exports.RolesResource = RolesResource;
4012
+ exports.SUPPORTED_MESSAGE_TYPES = SUPPORTED_MESSAGE_TYPES;
3516
4013
  exports.SalesResource = SalesResource;
3517
4014
  exports.SubscriptionPlansResource = SubscriptionPlansResource;
3518
4015
  exports.SubscriptionStatus = SubscriptionStatus;