@gymspace/sdk 1.2.12 → 1.2.14

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.
@@ -0,0 +1,151 @@
1
+ // Request DTOs
2
+ export interface CreateTagDto {
3
+ name: string;
4
+ color?: string;
5
+ description?: string;
6
+ }
7
+
8
+ export interface UpdateTagDto {
9
+ name?: string;
10
+ color?: string;
11
+ description?: string;
12
+ }
13
+
14
+ export interface AssignTagsDto {
15
+ tagIds: string[];
16
+ }
17
+
18
+ export interface RemoveTagsDto {
19
+ tagIds: string[];
20
+ }
21
+
22
+ // Response types
23
+ export interface Tag {
24
+ id: string;
25
+ gymId: string;
26
+ name: string;
27
+ color?: string;
28
+ description?: string;
29
+ clientCount?: number;
30
+ createdAt: string;
31
+ updatedAt: string;
32
+ createdBy?: {
33
+ id: string;
34
+ name: string;
35
+ };
36
+ }
37
+
38
+ export interface TagWithAssignment extends Tag {
39
+ assignedAt?: string;
40
+ assignedBy?: {
41
+ id: string;
42
+ name: string;
43
+ };
44
+ }
45
+
46
+ // Query/Filter params
47
+ export interface SearchTagsParams {
48
+ page?: number;
49
+ limit?: number;
50
+ search?: string;
51
+ includeCount?: boolean;
52
+ sortBy?: 'name' | 'createdAt' | 'clientCount';
53
+ sortOrder?: 'asc' | 'desc';
54
+ }
55
+
56
+ export interface GetTagClientsParams {
57
+ page?: number;
58
+ limit?: number;
59
+ search?: string;
60
+ status?: 'active' | 'inactive';
61
+ }
62
+
63
+ // Response types for specific operations
64
+ export interface AssignTagsResponse {
65
+ message: string;
66
+ assigned: number;
67
+ skipped: number;
68
+ client: {
69
+ id: string;
70
+ name: string;
71
+ tags: TagWithAssignment[];
72
+ };
73
+ }
74
+
75
+ export interface RemoveTagsResponse {
76
+ message: string;
77
+ removed: number;
78
+ notFound: number;
79
+ client: {
80
+ id: string;
81
+ name: string;
82
+ tags: TagWithAssignment[];
83
+ };
84
+ }
85
+
86
+ export interface DeleteTagResponse {
87
+ message: string;
88
+ deletedCount: number;
89
+ affectedClients: number;
90
+ }
91
+
92
+ export interface ClientTagsResponse {
93
+ client: {
94
+ id: string;
95
+ name: string;
96
+ clientNumber: string;
97
+ };
98
+ tags: TagWithAssignment[];
99
+ total: number;
100
+ }
101
+
102
+ export interface TagClientsResponse {
103
+ data: Array<{
104
+ id: string;
105
+ clientNumber: string;
106
+ name: string;
107
+ email?: string;
108
+ phone?: string;
109
+ status: string;
110
+ assignedAt: string;
111
+ assignedBy: {
112
+ id: string;
113
+ name: string;
114
+ };
115
+ }>;
116
+ meta: {
117
+ total: number;
118
+ page: number;
119
+ limit: number;
120
+ totalPages: number;
121
+ };
122
+ tag: {
123
+ id: string;
124
+ name: string;
125
+ color?: string;
126
+ };
127
+ }
128
+
129
+ export interface TagStatsResponse {
130
+ totalTags: number;
131
+ totalAssignments: number;
132
+ averageTagsPerClient: number;
133
+ mostUsedTags: Array<{
134
+ id: string;
135
+ name: string;
136
+ color?: string;
137
+ clientCount: number;
138
+ }>;
139
+ leastUsedTags: Array<{
140
+ id: string;
141
+ name: string;
142
+ color?: string;
143
+ clientCount: number;
144
+ }>;
145
+ unusedTags: Array<{
146
+ id: string;
147
+ name: string;
148
+ color?: string;
149
+ clientCount: number;
150
+ }>;
151
+ }
@@ -0,0 +1,113 @@
1
+ import { BaseResource } from './base';
2
+ import {
3
+ Activity,
4
+ CreateActivityDto,
5
+ UpdateActivityDto,
6
+ SearchActivitiesParams,
7
+ CreateActivityNotificationDto,
8
+ UpdateActivityNotificationDto,
9
+ ActivityNotification,
10
+ ActivityStats,
11
+ ActivityStatsParams,
12
+ EligibleClientsResponse,
13
+ DeleteActivityParams,
14
+ } from '../models/activities';
15
+ import { RequestOptions, PaginatedResponseDto } from '../types';
16
+
17
+ export class ActivitiesResource extends BaseResource {
18
+ private basePath = 'activities';
19
+
20
+ async createActivity(data: CreateActivityDto, options?: RequestOptions): Promise<Activity> {
21
+ return this.client.post<Activity>(this.basePath, data, options);
22
+ }
23
+
24
+ async searchActivities(
25
+ params?: SearchActivitiesParams,
26
+ options?: RequestOptions,
27
+ ): Promise<PaginatedResponseDto<Activity>> {
28
+ return this.paginate<Activity>(this.basePath, params as any, options);
29
+ }
30
+
31
+ async getActivity(id: string, options?: RequestOptions): Promise<Activity> {
32
+ return this.client.get<Activity>(`${this.basePath}/${id}`, undefined, options);
33
+ }
34
+
35
+ async updateActivity(
36
+ id: string,
37
+ data: UpdateActivityDto,
38
+ options?: RequestOptions,
39
+ ): Promise<Activity> {
40
+ return this.client.patch<Activity>(`${this.basePath}/${id}`, data, options);
41
+ }
42
+
43
+ async deleteActivity(
44
+ id: string,
45
+ params?: DeleteActivityParams,
46
+ options?: RequestOptions,
47
+ ): Promise<void> {
48
+ const queryString = params?.deleteRecurrence ? '?deleteRecurrence=true' : '';
49
+ return this.client.delete<void>(`${this.basePath}/${id}${queryString}`, options);
50
+ }
51
+
52
+ async createNotification(
53
+ activityId: string,
54
+ data: CreateActivityNotificationDto,
55
+ options?: RequestOptions,
56
+ ): Promise<ActivityNotification> {
57
+ return this.client.post<ActivityNotification>(
58
+ `${this.basePath}/${activityId}/notifications`,
59
+ data,
60
+ options,
61
+ );
62
+ }
63
+
64
+ async getNotifications(
65
+ activityId: string,
66
+ options?: RequestOptions,
67
+ ): Promise<{ data: ActivityNotification[] }> {
68
+ return this.client.get<{ data: ActivityNotification[] }>(
69
+ `${this.basePath}/${activityId}/notifications`,
70
+ undefined,
71
+ options,
72
+ );
73
+ }
74
+
75
+ async updateNotification(
76
+ activityId: string,
77
+ notificationId: string,
78
+ data: UpdateActivityNotificationDto,
79
+ options?: RequestOptions,
80
+ ): Promise<ActivityNotification> {
81
+ return this.client.patch<ActivityNotification>(
82
+ `${this.basePath}/${activityId}/notifications/${notificationId}`,
83
+ data,
84
+ options,
85
+ );
86
+ }
87
+
88
+ async deleteNotification(
89
+ activityId: string,
90
+ notificationId: string,
91
+ options?: RequestOptions,
92
+ ): Promise<void> {
93
+ return this.client.delete<void>(
94
+ `${this.basePath}/${activityId}/notifications/${notificationId}`,
95
+ options,
96
+ );
97
+ }
98
+
99
+ async getStats(params?: ActivityStatsParams, options?: RequestOptions): Promise<ActivityStats> {
100
+ return this.client.get<ActivityStats>(`${this.basePath}/stats`, params, options);
101
+ }
102
+
103
+ async getEligibleClients(
104
+ activityId: string,
105
+ options?: RequestOptions,
106
+ ): Promise<EligibleClientsResponse> {
107
+ return this.client.get<EligibleClientsResponse>(
108
+ `${this.basePath}/${activityId}/eligible-clients`,
109
+ undefined,
110
+ options,
111
+ );
112
+ }
113
+ }
@@ -0,0 +1,83 @@
1
+ import { BaseResource } from './base';
2
+ import { RequestOptions } from '../types';
3
+ import {
4
+ BulkTemplate,
5
+ CreateBulkTemplateDto,
6
+ UpdateBulkTemplateDto,
7
+ BulkMessageVariable,
8
+ SendBulkMessagesDto,
9
+ BulkMessageResultDto,
10
+ BulkLogsResponseDto,
11
+ GenerateAIMessageDto,
12
+ GenerateAIMessageResponseDto,
13
+ } from '../models/bulk-messaging';
14
+
15
+ export class BulkMessagingResource extends BaseResource {
16
+ private basePath = 'whatsapp/bulk-messaging';
17
+ private templatesPath = 'whatsapp/bulk-templates';
18
+
19
+ async createTemplate(
20
+ data: CreateBulkTemplateDto,
21
+ options?: RequestOptions,
22
+ ): Promise<BulkTemplate> {
23
+ return this.client.post<BulkTemplate>(this.templatesPath, data, options);
24
+ }
25
+
26
+ async getTemplates(options?: RequestOptions): Promise<BulkTemplate[]> {
27
+ return this.client.get<BulkTemplate[]>(this.templatesPath, undefined, options);
28
+ }
29
+
30
+ async getTemplate(id: string, options?: RequestOptions): Promise<BulkTemplate> {
31
+ return this.client.get<BulkTemplate>(`${this.templatesPath}/${id}`, undefined, options);
32
+ }
33
+
34
+ async updateTemplate(
35
+ id: string,
36
+ data: UpdateBulkTemplateDto,
37
+ options?: RequestOptions,
38
+ ): Promise<BulkTemplate> {
39
+ return this.client.put<BulkTemplate>(`${this.templatesPath}/${id}`, data, options);
40
+ }
41
+
42
+ async deleteTemplate(id: string, options?: RequestOptions): Promise<void> {
43
+ return this.client.delete<void>(`${this.templatesPath}/${id}`, options);
44
+ }
45
+
46
+ async getAvailableVariables(options?: RequestOptions): Promise<BulkMessageVariable[]> {
47
+ return this.client.get<BulkMessageVariable[]>(
48
+ `${this.basePath}/available-variables`,
49
+ undefined,
50
+ options,
51
+ );
52
+ }
53
+
54
+ /**
55
+ * Generate AI message with streaming support
56
+ * Note: This proxies to the agent endpoint for streaming responses
57
+ */
58
+ async generateAIMessage(
59
+ data: GenerateAIMessageDto,
60
+ options?: RequestOptions,
61
+ ): Promise<GenerateAIMessageResponseDto> {
62
+ return this.client.post<GenerateAIMessageResponseDto>(
63
+ `${this.basePath}/generate-ai`,
64
+ data,
65
+ options,
66
+ );
67
+ }
68
+
69
+ /**
70
+ * Send bulk messages to multiple clients
71
+ * Note: SDK sends clientIds, API fetches full client and gym data before sending to agent
72
+ */
73
+ async send(data: SendBulkMessagesDto, options?: RequestOptions): Promise<BulkMessageResultDto> {
74
+ return this.client.post<BulkMessageResultDto>(`${this.basePath}/send`, data, options);
75
+ }
76
+
77
+ /**
78
+ * Get logs for a bulk message send operation
79
+ */
80
+ async getLogs(sendId: string, options?: RequestOptions): Promise<BulkLogsResponseDto> {
81
+ return this.client.get<BulkLogsResponseDto>(`${this.basePath}/logs`, { sendId }, options);
82
+ }
83
+ }
@@ -1,27 +1,40 @@
1
1
  import { BaseResource } from './base';
2
- import {
3
- CheckIn,
4
- CreateCheckInDto,
2
+ import {
3
+ CheckIn,
4
+ CreateCheckInDto,
5
5
  SearchCheckInsParams,
6
6
  GetCheckInStatsParams,
7
7
  CheckInStats,
8
8
  GetClientCheckInHistoryParams,
9
9
  CurrentlyInGymResponse,
10
10
  CheckInListResponse,
11
- ClientCheckInHistory
11
+ ClientCheckInHistory,
12
12
  } from '../models/check-ins';
13
13
  import { RequestOptions, PaginatedResponseDto } from '../types';
14
14
 
15
15
  export class CheckInsResource extends BaseResource {
16
16
  private basePath = 'check-ins';
17
17
 
18
+ /**
19
+ * Creates a new check-in for a client.
20
+ *
21
+ * **Permissions Required:**
22
+ * - Gym owners with full gym access
23
+ * - Active collaborators with CHECKINS_CREATE permission
24
+ *
25
+ * @param data - The check-in data including client ID and optional notes
26
+ * @param options - Optional request configuration
27
+ * @returns The created check-in record with client and user details
28
+ * @throws {ValidationError} When client is not found or already checked in
29
+ * @throws {AuthorizationError} When user lacks required permissions
30
+ */
18
31
  async createCheckIn(data: CreateCheckInDto, options?: RequestOptions): Promise<CheckIn> {
19
32
  return this.client.post<CheckIn>(this.basePath, data, options);
20
33
  }
21
34
 
22
35
  async searchCheckIns(
23
36
  params?: SearchCheckInsParams,
24
- options?: RequestOptions
37
+ options?: RequestOptions,
25
38
  ): Promise<CheckInListResponse> {
26
39
  return this.client.get<CheckInListResponse>(this.basePath, params, options);
27
40
  }
@@ -34,30 +47,49 @@ export class CheckInsResource extends BaseResource {
34
47
  return this.client.get<CheckIn>(`${this.basePath}/${id}`, undefined, options);
35
48
  }
36
49
 
50
+ /**
51
+ * Deletes a check-in record.
52
+ *
53
+ * **Permissions Required:**
54
+ * - Gym owners with full gym access
55
+ * - Active collaborators with CHECKINS_CREATE permission
56
+ *
57
+ * **Business Rules:**
58
+ * - Only check-ins from today can be deleted
59
+ * - The same permission level required for creation is required for deletion
60
+ * - Cannot delete check-ins from previous days
61
+ *
62
+ * @param id - The ID of the check-in to delete
63
+ * @param options - Optional request configuration
64
+ * @returns Promise that resolves when the check-in is successfully deleted
65
+ * @throws {NotFoundError} When the check-in is not found
66
+ * @throws {AuthorizationError} When user lacks required permissions
67
+ * @throws {ValidationError} When trying to delete a check-in from a previous day
68
+ */
37
69
  async deleteCheckIn(id: string, options?: RequestOptions): Promise<void> {
38
70
  return this.client.delete<void>(`${this.basePath}/${id}`, options);
39
71
  }
40
72
 
41
73
  async getGymCheckInStats(
42
74
  params: GetCheckInStatsParams,
43
- options?: RequestOptions
75
+ options?: RequestOptions,
44
76
  ): Promise<CheckInStats> {
45
77
  return this.client.get<CheckInStats>(
46
78
  `${this.basePath}/stats/${params.period}`,
47
79
  undefined,
48
- options
80
+ options,
49
81
  );
50
82
  }
51
83
 
52
84
  async getClientCheckInHistory(
53
85
  clientId: string,
54
86
  params?: GetClientCheckInHistoryParams,
55
- options?: RequestOptions
87
+ options?: RequestOptions,
56
88
  ): Promise<ClientCheckInHistory> {
57
89
  return this.client.get<ClientCheckInHistory>(
58
90
  `${this.basePath}/client/${clientId}/history`,
59
91
  params,
60
- options
92
+ options,
61
93
  );
62
94
  }
63
- }
95
+ }
@@ -4,7 +4,13 @@ import {
4
4
  CreateContractDto,
5
5
  RenewContractDto,
6
6
  FreezeContractDto,
7
+ CancelContractDto,
8
+ SuspendContractDto,
9
+ ResumeContractDto,
10
+ ReactivateContractDto,
7
11
  GetContractsParams,
12
+ ContractLifecycleEvent,
13
+ CancellationAnalytics,
8
14
  } from '../models/contracts';
9
15
  import { RequestOptions, PaginatedResponseDto } from '../types';
10
16
 
@@ -48,12 +54,58 @@ export class ContractsResource extends BaseResource {
48
54
 
49
55
  async cancelContract(
50
56
  id: string,
51
- data: { reason: string },
57
+ data: CancelContractDto,
52
58
  options?: RequestOptions,
53
59
  ): Promise<Contract> {
54
60
  return this.client.put<Contract>(`${this.basePath}/${id}/cancel`, data, options);
55
61
  }
56
62
 
63
+ async suspendContract(
64
+ id: string,
65
+ data: SuspendContractDto,
66
+ options?: RequestOptions,
67
+ ): Promise<Contract> {
68
+ return this.client.post<Contract>(`${this.basePath}/${id}/suspend`, data, options);
69
+ }
70
+
71
+ async resumeContract(
72
+ id: string,
73
+ data: ResumeContractDto,
74
+ options?: RequestOptions,
75
+ ): Promise<Contract> {
76
+ return this.client.post<Contract>(`${this.basePath}/${id}/resume`, data, options);
77
+ }
78
+
79
+ async reactivateContract(
80
+ id: string,
81
+ data: ReactivateContractDto,
82
+ options?: RequestOptions,
83
+ ): Promise<Contract> {
84
+ return this.client.post<Contract>(`${this.basePath}/${id}/reactivate`, data, options);
85
+ }
86
+
87
+ async getLifecycleHistory(
88
+ id: string,
89
+ options?: RequestOptions,
90
+ ): Promise<ContractLifecycleEvent[]> {
91
+ return this.client.get<ContractLifecycleEvent[]>(
92
+ `${this.basePath}/${id}/lifecycle-history`,
93
+ undefined,
94
+ options,
95
+ );
96
+ }
97
+
98
+ async getCancellationAnalytics(
99
+ params?: { startDate?: string; endDate?: string },
100
+ options?: RequestOptions,
101
+ ): Promise<CancellationAnalytics> {
102
+ return this.client.get<CancellationAnalytics>(
103
+ `${this.basePath}/analytics/cancellation-reasons`,
104
+ params,
105
+ options,
106
+ );
107
+ }
108
+
57
109
  async resendWhatsAppNotification(
58
110
  contractId: string,
59
111
  options?: RequestOptions,
@@ -1,40 +1,32 @@
1
1
  import { BaseResource } from './base';
2
- import { Gym, CreateGymDto, UpdateGymDto, GymStats, UpdateGymScheduleDto, UpdateGymSocialMediaDto } from '../models/gyms';
2
+ import {
3
+ Gym,
4
+ CreateGymDto,
5
+ UpdateGymDto,
6
+ GymStats,
7
+ UpdateGymScheduleDto,
8
+ UpdateGymSocialMediaDto,
9
+ UpdateGymInventorySettingsDto,
10
+ UpdateGymContractSettingsDto,
11
+ } from '../models/gyms';
3
12
  import { RequestOptions } from '../types';
4
13
 
5
14
  export class GymsResource extends BaseResource {
6
15
  private basePath = 'gyms';
7
16
 
8
- async createGym(
9
- data: CreateGymDto,
10
- options?: RequestOptions
11
- ): Promise<Gym> {
12
- return this.client.post<Gym>(
13
- this.basePath,
14
- data,
15
- options
16
- );
17
+ async createGym(data: CreateGymDto, options?: RequestOptions): Promise<Gym> {
18
+ return this.client.post<Gym>(this.basePath, data, options);
17
19
  }
18
20
 
19
- async getOrganizationGyms(
20
- options?: RequestOptions
21
- ): Promise<Gym[]> {
22
- return this.client.get<Gym[]>(
23
- this.basePath,
24
- undefined,
25
- options
26
- );
21
+ async getOrganizationGyms(options?: RequestOptions): Promise<Gym[]> {
22
+ return this.client.get<Gym[]>(this.basePath, undefined, options);
27
23
  }
28
24
 
29
25
  async getGym(id: string, options?: RequestOptions): Promise<Gym> {
30
26
  return this.client.get<Gym>(`${this.basePath}/${id}`, undefined, options);
31
27
  }
32
28
 
33
- async updateGym(
34
- id: string,
35
- data: UpdateGymDto,
36
- options?: RequestOptions
37
- ): Promise<Gym> {
29
+ async updateGym(id: string, data: UpdateGymDto, options?: RequestOptions): Promise<Gym> {
38
30
  return this.client.put<Gym>(`${this.basePath}/${id}`, data, options);
39
31
  }
40
32
 
@@ -54,7 +46,7 @@ export class GymsResource extends BaseResource {
54
46
  email?: string;
55
47
  assetId?: string;
56
48
  }>,
57
- options?: RequestOptions
49
+ options?: RequestOptions,
58
50
  ): Promise<Gym> {
59
51
  return this.client.put<Gym>(`${this.basePath}/current`, data, options);
60
52
  }
@@ -62,7 +54,7 @@ export class GymsResource extends BaseResource {
62
54
  async updateGymSchedule(
63
55
  id: string,
64
56
  data: UpdateGymScheduleDto,
65
- options?: RequestOptions
57
+ options?: RequestOptions,
66
58
  ): Promise<Gym> {
67
59
  return this.client.put<Gym>(`${this.basePath}/${id}/schedule`, data, options);
68
60
  }
@@ -70,8 +62,54 @@ export class GymsResource extends BaseResource {
70
62
  async updateGymSocialMedia(
71
63
  id: string,
72
64
  data: UpdateGymSocialMediaDto,
73
- options?: RequestOptions
65
+ options?: RequestOptions,
74
66
  ): Promise<Gym> {
75
67
  return this.client.put<Gym>(`${this.basePath}/${id}/social-media`, data, options);
76
68
  }
77
- }
69
+
70
+ /**
71
+ * Update current gym inventory settings (stock configuration)
72
+ * Uses gym from context (x-gym-id header)
73
+ * @param data Inventory settings data
74
+ * @param options Request options
75
+ * @returns Updated gym with new settings
76
+ *
77
+ * @example
78
+ * ```typescript
79
+ * const gym = await sdk.gyms.updateInventorySettings({
80
+ * defaultMinStock: 15,
81
+ * defaultMaxStock: 1000,
82
+ * enableLowStockAlerts: true
83
+ * });
84
+ * ```
85
+ */
86
+ async updateInventorySettings(
87
+ data: UpdateGymInventorySettingsDto,
88
+ options?: RequestOptions,
89
+ ): Promise<Gym> {
90
+ return this.client.patch<Gym>(`${this.basePath}/current/inventory-settings`, data, options);
91
+ }
92
+
93
+ /**
94
+ * Update current gym contract expiration settings
95
+ * Uses gym from context (x-gym-id header)
96
+ * @param data Contract settings data
97
+ * @param options Request options
98
+ * @returns Updated gym with new settings
99
+ *
100
+ * @example
101
+ * ```typescript
102
+ * const gym = await sdk.gyms.updateContractSettings({
103
+ * expiringSoonDays: 7,
104
+ * gracePeriodDays: 0,
105
+ * enableExpirationNotifications: true
106
+ * });
107
+ * ```
108
+ */
109
+ async updateContractSettings(
110
+ data: UpdateGymContractSettingsDto,
111
+ options?: RequestOptions,
112
+ ): Promise<Gym> {
113
+ return this.client.patch<Gym>(`${this.basePath}/current/contract-settings`, data, options);
114
+ }
115
+ }
@@ -23,4 +23,7 @@ export * from './subscription-plans';
23
23
  export * from './admin-subscription-management';
24
24
  export * from './payment-methods';
25
25
  export * from './whatsapp';
26
- export * from './whatsapp-templates';
26
+ export * from './whatsapp-templates';
27
+ export * from './bulk-messaging';
28
+ export * from './activities';
29
+ export * from './tags';
@@ -65,6 +65,14 @@ export interface UpdateSubscriptionPlanDto {
65
65
 
66
66
  export class SubscriptionPlansResource extends BaseResource {
67
67
  private basePath = 'admin/subscription-plans';
68
+ private publicBasePath = 'subscription-plans/public';
69
+
70
+ /**
71
+ * List all active subscription plans (Public - no authentication required)
72
+ */
73
+ async listPublicPlans(options?: RequestOptions): Promise<SubscriptionPlanDto[]> {
74
+ return this.client.get<SubscriptionPlanDto[]>(`${this.publicBasePath}`, undefined, options);
75
+ }
68
76
 
69
77
  /**
70
78
  * List all subscription plans (Super Admin only)
@@ -107,4 +115,4 @@ export class SubscriptionPlansResource extends BaseResource {
107
115
  async deletePlan(id: string, options?: RequestOptions): Promise<{ success: boolean }> {
108
116
  return this.client.delete<{ success: boolean }>(`${this.basePath}/${id}`, options);
109
117
  }
110
- }
118
+ }