@open-loyalty/mcp-server 1.3.7 → 1.5.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.
Files changed (100) hide show
  1. package/dist/config.d.ts +4 -3
  2. package/dist/config.js +9 -7
  3. package/dist/instructions.d.ts +1 -1
  4. package/dist/instructions.js +26 -8
  5. package/dist/tools/achievement/handlers.js +60 -1
  6. package/dist/tools/achievement/index.d.ts +8 -8
  7. package/dist/tools/achievement/index.js +10 -11
  8. package/dist/tools/achievement/schemas.d.ts +8 -8
  9. package/dist/tools/achievement/schemas.js +36 -32
  10. package/dist/tools/analytics.js +9 -9
  11. package/dist/tools/badge.js +4 -4
  12. package/dist/tools/campaign/handlers.js +35 -1
  13. package/dist/tools/campaign/index.d.ts +97 -34
  14. package/dist/tools/campaign/index.js +14 -12
  15. package/dist/tools/campaign/schemas.d.ts +96 -33
  16. package/dist/tools/campaign/schemas.js +89 -55
  17. package/dist/tools/custom-event.js +10 -9
  18. package/dist/tools/export.js +4 -4
  19. package/dist/tools/import.d.ts +1 -1
  20. package/dist/tools/import.js +11 -6
  21. package/dist/tools/index.js +4 -4
  22. package/dist/tools/member/handlers.js +48 -1
  23. package/dist/tools/member/index.d.ts +1 -1
  24. package/dist/tools/member/index.js +3 -1
  25. package/dist/tools/member/schemas.js +12 -12
  26. package/dist/tools/points/handlers.d.ts +75 -0
  27. package/dist/tools/{points.js → points/handlers.js} +21 -112
  28. package/dist/tools/points/index.d.ts +84 -0
  29. package/dist/tools/points/index.js +63 -0
  30. package/dist/tools/points/schemas.d.ts +45 -0
  31. package/dist/tools/points/schemas.js +47 -0
  32. package/dist/tools/referral/schemas.js +3 -3
  33. package/dist/tools/reward/handlers.d.ts +2 -0
  34. package/dist/tools/reward/handlers.js +79 -6
  35. package/dist/tools/reward/index.d.ts +2 -0
  36. package/dist/tools/reward/index.js +10 -10
  37. package/dist/tools/reward/schemas.d.ts +2 -0
  38. package/dist/tools/reward/schemas.js +42 -23
  39. package/dist/tools/segment/index.js +7 -5
  40. package/dist/tools/segment/schemas.js +11 -11
  41. package/dist/tools/tierset/handlers.d.ts +26 -0
  42. package/dist/tools/tierset/handlers.js +196 -0
  43. package/dist/tools/tierset/index.d.ts +124 -0
  44. package/dist/tools/tierset/index.js +88 -0
  45. package/dist/tools/tierset/schemas.d.ts +127 -0
  46. package/dist/tools/tierset/schemas.js +62 -0
  47. package/dist/tools/transaction/handlers.d.ts +89 -0
  48. package/dist/tools/transaction/handlers.js +159 -0
  49. package/dist/tools/transaction/index.d.ts +153 -0
  50. package/dist/tools/transaction/index.js +54 -0
  51. package/dist/tools/transaction/schemas.d.ts +126 -0
  52. package/dist/tools/transaction/schemas.js +60 -0
  53. package/dist/tools/wallet-type/handlers.d.ts +63 -0
  54. package/dist/tools/{wallet-type.js → wallet-type/handlers.js} +15 -78
  55. package/dist/tools/{wallet-type.d.ts → wallet-type/index.d.ts} +3 -64
  56. package/dist/tools/wallet-type/index.js +65 -0
  57. package/dist/tools/wallet-type/schemas.d.ts +1 -0
  58. package/dist/tools/wallet-type/schemas.js +1 -0
  59. package/dist/tools/webhook.js +6 -6
  60. package/dist/types/schemas/achievement.d.ts +48 -48
  61. package/dist/types/schemas/admin.d.ts +10 -10
  62. package/dist/types/schemas/campaign.d.ts +12 -12
  63. package/dist/types/schemas/common.js +1 -1
  64. package/dist/types/schemas/member.d.ts +18 -18
  65. package/dist/types/schemas/role.d.ts +4 -4
  66. package/dist/types/schemas/tierset.js +2 -1
  67. package/dist/types/schemas/transaction.d.ts +12 -12
  68. package/dist/types/schemas/wallet-type.js +12 -10
  69. package/dist/types/schemas/webhook.d.ts +6 -6
  70. package/dist/utils/errors.js +40 -0
  71. package/package.json +3 -2
  72. package/dist/prompts/fan-engagement-setup.d.ts +0 -107
  73. package/dist/prompts/fan-engagement-setup.js +0 -492
  74. package/dist/tools/achievement.d.ts +0 -1017
  75. package/dist/tools/achievement.js +0 -354
  76. package/dist/tools/campaign.d.ts +0 -1800
  77. package/dist/tools/campaign.js +0 -737
  78. package/dist/tools/member.d.ts +0 -366
  79. package/dist/tools/member.js +0 -352
  80. package/dist/tools/points.d.ts +0 -201
  81. package/dist/tools/reward.d.ts +0 -279
  82. package/dist/tools/reward.js +0 -361
  83. package/dist/tools/segment.d.ts +0 -816
  84. package/dist/tools/segment.js +0 -333
  85. package/dist/tools/tierset.d.ts +0 -273
  86. package/dist/tools/tierset.js +0 -289
  87. package/dist/tools/transaction.d.ts +0 -365
  88. package/dist/tools/transaction.js +0 -259
  89. package/dist/workflows/app-login-streak.d.ts +0 -39
  90. package/dist/workflows/app-login-streak.js +0 -298
  91. package/dist/workflows/early-arrival.d.ts +0 -33
  92. package/dist/workflows/early-arrival.js +0 -148
  93. package/dist/workflows/index.d.ts +0 -101
  94. package/dist/workflows/index.js +0 -208
  95. package/dist/workflows/match-attendance.d.ts +0 -45
  96. package/dist/workflows/match-attendance.js +0 -308
  97. package/dist/workflows/sportsbar-visit.d.ts +0 -41
  98. package/dist/workflows/sportsbar-visit.js +0 -284
  99. package/dist/workflows/vod-watching.d.ts +0 -43
  100. package/dist/workflows/vod-watching.js +0 -326
@@ -1,279 +0,0 @@
1
- import { z } from "zod";
2
- import { Reward } from "../types/schemas/reward.js";
3
- export declare const RewardListInputSchema: {
4
- storeCode: z.ZodOptional<z.ZodString>;
5
- page: z.ZodOptional<z.ZodNumber>;
6
- perPage: z.ZodOptional<z.ZodNumber>;
7
- active: z.ZodOptional<z.ZodBoolean>;
8
- type: z.ZodOptional<z.ZodEnum<["static_coupon", "dynamic_coupon", "conversion_coupon", "material", "fortune_wheel"]>>;
9
- categoryId: z.ZodOptional<z.ZodString>;
10
- };
11
- export declare const RewardCreateInputSchema: {
12
- storeCode: z.ZodOptional<z.ZodString>;
13
- name: z.ZodString;
14
- type: z.ZodEnum<["static_coupon", "dynamic_coupon", "conversion_coupon", "material", "fortune_wheel"]>;
15
- costInPoints: z.ZodOptional<z.ZodNumber>;
16
- description: z.ZodOptional<z.ZodString>;
17
- usageInstruction: z.ZodOptional<z.ZodString>;
18
- active: z.ZodOptional<z.ZodBoolean>;
19
- categories: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
20
- levels: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
21
- segments: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
22
- target: z.ZodOptional<z.ZodNullable<z.ZodEnum<["level", "segment"]>>>;
23
- couponValue: z.ZodOptional<z.ZodNumber>;
24
- couponValueType: z.ZodOptional<z.ZodEnum<["Money", "Percentage"]>>;
25
- daysValid: z.ZodOptional<z.ZodNumber>;
26
- };
27
- export declare const RewardGetInputSchema: {
28
- storeCode: z.ZodOptional<z.ZodString>;
29
- rewardId: z.ZodString;
30
- };
31
- export declare const RewardUpdateInputSchema: {
32
- storeCode: z.ZodOptional<z.ZodString>;
33
- rewardId: z.ZodString;
34
- name: z.ZodOptional<z.ZodString>;
35
- costInPoints: z.ZodOptional<z.ZodNumber>;
36
- description: z.ZodOptional<z.ZodString>;
37
- active: z.ZodOptional<z.ZodBoolean>;
38
- categories: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
39
- levels: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
40
- segments: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
41
- };
42
- export declare const RewardIdInputSchema: {
43
- storeCode: z.ZodOptional<z.ZodString>;
44
- rewardId: z.ZodString;
45
- };
46
- export declare const RewardBuyInputSchema: {
47
- storeCode: z.ZodOptional<z.ZodString>;
48
- rewardId: z.ZodString;
49
- memberId: z.ZodString;
50
- quantity: z.ZodOptional<z.ZodNumber>;
51
- couponValue: z.ZodOptional<z.ZodNumber>;
52
- withoutPoints: z.ZodOptional<z.ZodBoolean>;
53
- };
54
- export declare const RewardRedeemInputSchema: {
55
- storeCode: z.ZodOptional<z.ZodString>;
56
- memberId: z.ZodString;
57
- couponCode: z.ZodString;
58
- };
59
- export declare const RewardCategoryListInputSchema: {
60
- storeCode: z.ZodOptional<z.ZodString>;
61
- page: z.ZodOptional<z.ZodNumber>;
62
- perPage: z.ZodOptional<z.ZodNumber>;
63
- active: z.ZodOptional<z.ZodBoolean>;
64
- };
65
- export declare function rewardList(input: {
66
- storeCode?: string;
67
- page?: number;
68
- perPage?: number;
69
- active?: boolean;
70
- type?: string;
71
- categoryId?: string;
72
- }): Promise<{
73
- rewards: Array<{
74
- rewardId: string;
75
- name: string;
76
- type: string;
77
- costInPoints?: number;
78
- active: boolean;
79
- }>;
80
- total: {
81
- all?: number;
82
- filtered?: number;
83
- };
84
- }>;
85
- export declare function rewardCreate(input: {
86
- storeCode?: string;
87
- name: string;
88
- type: string;
89
- costInPoints?: number;
90
- description?: string;
91
- usageInstruction?: string;
92
- active?: boolean;
93
- categories?: string[];
94
- levels?: string[];
95
- segments?: string[];
96
- target?: string | null;
97
- couponValue?: number;
98
- couponValueType?: string;
99
- daysValid?: number;
100
- }): Promise<{
101
- rewardId: string;
102
- name: string;
103
- costInPoints?: number;
104
- }>;
105
- export declare function rewardGet(input: {
106
- storeCode?: string;
107
- rewardId: string;
108
- }): Promise<Reward>;
109
- export declare function rewardUpdate(input: {
110
- storeCode?: string;
111
- rewardId: string;
112
- name?: string;
113
- costInPoints?: number;
114
- description?: string;
115
- active?: boolean;
116
- categories?: string[];
117
- levels?: string[];
118
- segments?: string[];
119
- }): Promise<void>;
120
- export declare function rewardActivate(input: {
121
- storeCode?: string;
122
- rewardId: string;
123
- }): Promise<void>;
124
- export declare function rewardDeactivate(input: {
125
- storeCode?: string;
126
- rewardId: string;
127
- }): Promise<void>;
128
- export declare function rewardBuy(input: {
129
- storeCode?: string;
130
- rewardId: string;
131
- memberId: string;
132
- quantity?: number;
133
- couponValue?: number;
134
- withoutPoints?: boolean;
135
- }): Promise<{
136
- issuedRewardId: string;
137
- couponCode?: string;
138
- }>;
139
- export declare function rewardRedeem(input: {
140
- storeCode?: string;
141
- memberId: string;
142
- couponCode: string;
143
- }): Promise<{
144
- code: string;
145
- used: boolean;
146
- }>;
147
- export declare function rewardCategoryList(input: {
148
- storeCode?: string;
149
- page?: number;
150
- perPage?: number;
151
- active?: boolean;
152
- }): Promise<{
153
- categories: Array<{
154
- categoryId: string;
155
- name: string;
156
- active: boolean;
157
- }>;
158
- }>;
159
- export declare const rewardToolDefinitions: readonly [{
160
- readonly name: "openloyalty_reward_list";
161
- readonly title: "Browse Rewards";
162
- readonly description: string;
163
- readonly readOnly: true;
164
- readonly inputSchema: {
165
- storeCode: z.ZodOptional<z.ZodString>;
166
- page: z.ZodOptional<z.ZodNumber>;
167
- perPage: z.ZodOptional<z.ZodNumber>;
168
- active: z.ZodOptional<z.ZodBoolean>;
169
- type: z.ZodOptional<z.ZodEnum<["static_coupon", "dynamic_coupon", "conversion_coupon", "material", "fortune_wheel"]>>;
170
- categoryId: z.ZodOptional<z.ZodString>;
171
- };
172
- readonly handler: typeof rewardList;
173
- }, {
174
- readonly name: "openloyalty_reward_create";
175
- readonly title: "Create New Reward";
176
- readonly description: string;
177
- readonly readOnly: false;
178
- readonly inputSchema: {
179
- storeCode: z.ZodOptional<z.ZodString>;
180
- name: z.ZodString;
181
- type: z.ZodEnum<["static_coupon", "dynamic_coupon", "conversion_coupon", "material", "fortune_wheel"]>;
182
- costInPoints: z.ZodOptional<z.ZodNumber>;
183
- description: z.ZodOptional<z.ZodString>;
184
- usageInstruction: z.ZodOptional<z.ZodString>;
185
- active: z.ZodOptional<z.ZodBoolean>;
186
- categories: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
187
- levels: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
188
- segments: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
189
- target: z.ZodOptional<z.ZodNullable<z.ZodEnum<["level", "segment"]>>>;
190
- couponValue: z.ZodOptional<z.ZodNumber>;
191
- couponValueType: z.ZodOptional<z.ZodEnum<["Money", "Percentage"]>>;
192
- daysValid: z.ZodOptional<z.ZodNumber>;
193
- };
194
- readonly handler: typeof rewardCreate;
195
- }, {
196
- readonly name: "openloyalty_reward_get";
197
- readonly title: "Get Reward Details";
198
- readonly description: "Get full reward details including configuration, targeting, and coupon settings.";
199
- readonly readOnly: true;
200
- readonly inputSchema: {
201
- storeCode: z.ZodOptional<z.ZodString>;
202
- rewardId: z.ZodString;
203
- };
204
- readonly handler: typeof rewardGet;
205
- }, {
206
- readonly name: "openloyalty_reward_update";
207
- readonly title: "Update Reward";
208
- readonly description: "Update reward configuration. Cannot change reward type after creation.";
209
- readonly readOnly: false;
210
- readonly inputSchema: {
211
- storeCode: z.ZodOptional<z.ZodString>;
212
- rewardId: z.ZodString;
213
- name: z.ZodOptional<z.ZodString>;
214
- costInPoints: z.ZodOptional<z.ZodNumber>;
215
- description: z.ZodOptional<z.ZodString>;
216
- active: z.ZodOptional<z.ZodBoolean>;
217
- categories: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
218
- levels: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
219
- segments: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
220
- };
221
- readonly handler: typeof rewardUpdate;
222
- }, {
223
- readonly name: "openloyalty_reward_activate";
224
- readonly title: "Activate Reward";
225
- readonly description: "Activate a reward, making it available for members to redeem.";
226
- readonly readOnly: false;
227
- readonly inputSchema: {
228
- storeCode: z.ZodOptional<z.ZodString>;
229
- rewardId: z.ZodString;
230
- };
231
- readonly handler: typeof rewardActivate;
232
- }, {
233
- readonly name: "openloyalty_reward_deactivate";
234
- readonly title: "Deactivate Reward";
235
- readonly description: "Deactivate a reward, hiding it from members. Already purchased rewards remain valid.";
236
- readonly readOnly: false;
237
- readonly inputSchema: {
238
- storeCode: z.ZodOptional<z.ZodString>;
239
- rewardId: z.ZodString;
240
- };
241
- readonly handler: typeof rewardDeactivate;
242
- }, {
243
- readonly name: "openloyalty_reward_buy";
244
- readonly title: "Redeem Reward for Member";
245
- readonly description: string;
246
- readonly readOnly: false;
247
- readonly inputSchema: {
248
- storeCode: z.ZodOptional<z.ZodString>;
249
- rewardId: z.ZodString;
250
- memberId: z.ZodString;
251
- quantity: z.ZodOptional<z.ZodNumber>;
252
- couponValue: z.ZodOptional<z.ZodNumber>;
253
- withoutPoints: z.ZodOptional<z.ZodBoolean>;
254
- };
255
- readonly handler: typeof rewardBuy;
256
- }, {
257
- readonly name: "openloyalty_reward_redeem";
258
- readonly title: "Use Coupon Code";
259
- readonly description: string;
260
- readonly readOnly: false;
261
- readonly inputSchema: {
262
- storeCode: z.ZodOptional<z.ZodString>;
263
- memberId: z.ZodString;
264
- couponCode: z.ZodString;
265
- };
266
- readonly handler: typeof rewardRedeem;
267
- }, {
268
- readonly name: "openloyalty_reward_category_list";
269
- readonly title: "List Reward Categories";
270
- readonly description: "List reward categories. Use categoryId when creating or filtering rewards.";
271
- readonly readOnly: true;
272
- readonly inputSchema: {
273
- storeCode: z.ZodOptional<z.ZodString>;
274
- page: z.ZodOptional<z.ZodNumber>;
275
- perPage: z.ZodOptional<z.ZodNumber>;
276
- active: z.ZodOptional<z.ZodBoolean>;
277
- };
278
- readonly handler: typeof rewardCategoryList;
279
- }];
@@ -1,361 +0,0 @@
1
- import { z } from "zod";
2
- import { apiGet, apiPost, apiPut } from "../client/http.js";
3
- import { RewardSchema, } from "../types/schemas/reward.js";
4
- import { formatApiError, OpenLoyaltyError } from "../utils/errors.js";
5
- import { getStoreCode } from "../config.js";
6
- import { omitUndefined } from "../utils/payload.js";
7
- // Input Schemas
8
- export const RewardListInputSchema = {
9
- storeCode: z.string().optional().describe("Store code. If not provided, uses the default store code from configuration."),
10
- page: z.number().optional().describe("Page number (default: 1)."),
11
- perPage: z.number().optional().describe("Items per page (default: 10)."),
12
- active: z.boolean().optional().describe("Filter by active status."),
13
- type: z.enum(["static_coupon", "dynamic_coupon", "conversion_coupon", "material", "fortune_wheel"]).optional().describe("Filter by reward type."),
14
- categoryId: z.string().optional().describe("Filter by category ID."),
15
- };
16
- export const RewardCreateInputSchema = {
17
- storeCode: z.string().optional().describe("Store code. If not provided, uses the default store code from configuration."),
18
- name: z.string().describe("Reward name (required, max 255 chars)."),
19
- type: z.enum(["static_coupon", "dynamic_coupon", "conversion_coupon", "material", "fortune_wheel"]).describe("Reward type: static_coupon (fixed discount), dynamic_coupon (variable value), " +
20
- "conversion_coupon (converts points to coupon), material (physical goods), fortune_wheel (gamified)."),
21
- costInPoints: z.number().optional().describe("Points required to redeem this reward."),
22
- description: z.string().optional().describe("Reward description."),
23
- usageInstruction: z.string().optional().describe("Instructions for using the reward."),
24
- active: z.boolean().optional().describe("Whether reward is active (default: false)."),
25
- categories: z.array(z.string()).optional().describe("Array of category UUIDs."),
26
- levels: z.array(z.string()).optional().describe("Array of tier level UUIDs that can see/redeem."),
27
- segments: z.array(z.string()).optional().describe("Array of segment UUIDs that can see/redeem."),
28
- target: z.enum(["level", "segment"]).nullable().optional().describe("Target type for visibility: level (tier-based), segment (segment-based), or null (all)."),
29
- couponValue: z.number().optional().describe("Coupon value (required for static_coupon)."),
30
- couponValueType: z.enum(["Money", "Percentage"]).optional().describe("Coupon value type."),
31
- daysValid: z.number().optional().describe("Days the coupon remains valid after purchase."),
32
- };
33
- export const RewardGetInputSchema = {
34
- storeCode: z.string().optional().describe("Store code. If not provided, uses the default store code from configuration."),
35
- rewardId: z.string().describe("The reward ID (UUID) to retrieve."),
36
- };
37
- export const RewardUpdateInputSchema = {
38
- storeCode: z.string().optional().describe("Store code. If not provided, uses the default store code from configuration."),
39
- rewardId: z.string().describe("The reward ID (UUID) to update."),
40
- name: z.string().optional().describe("Reward name."),
41
- costInPoints: z.number().optional().describe("Points required to redeem."),
42
- description: z.string().optional().describe("Reward description."),
43
- active: z.boolean().optional().describe("Whether reward is active."),
44
- categories: z.array(z.string()).optional().describe("Array of category UUIDs."),
45
- levels: z.array(z.string()).optional().describe("Array of tier level UUIDs."),
46
- segments: z.array(z.string()).optional().describe("Array of segment UUIDs."),
47
- };
48
- export const RewardIdInputSchema = {
49
- storeCode: z.string().optional().describe("Store code. If not provided, uses the default store code from configuration."),
50
- rewardId: z.string().describe("The reward ID (UUID)."),
51
- };
52
- export const RewardBuyInputSchema = {
53
- storeCode: z.string().optional().describe("Store code. If not provided, uses the default store code from configuration."),
54
- rewardId: z.string().describe("The reward ID (UUID) to purchase."),
55
- memberId: z.string().describe("The member ID (UUID) purchasing the reward."),
56
- quantity: z.number().optional().describe("Number of rewards to purchase (1-32, default: 1)."),
57
- couponValue: z.number().optional().describe("Coupon value (for dynamic coupons)."),
58
- withoutPoints: z.boolean().optional().describe("Admin only: skip points deduction."),
59
- };
60
- export const RewardRedeemInputSchema = {
61
- storeCode: z.string().optional().describe("Store code. If not provided, uses the default store code from configuration."),
62
- memberId: z.string().describe("The member ID (UUID) redeeming the coupon."),
63
- couponCode: z.string().describe("The coupon code to redeem."),
64
- };
65
- export const RewardCategoryListInputSchema = {
66
- storeCode: z.string().optional().describe("Store code. If not provided, uses the default store code from configuration."),
67
- page: z.number().optional().describe("Page number (default: 1)."),
68
- perPage: z.number().optional().describe("Items per page (default: 10)."),
69
- active: z.boolean().optional().describe("Filter by active status."),
70
- };
71
- // Handler functions
72
- export async function rewardList(input) {
73
- const storeCode = getStoreCode(input.storeCode);
74
- const params = new URLSearchParams();
75
- if (input.page)
76
- params.append("_page", String(input.page));
77
- if (input.perPage)
78
- params.append("_itemsOnPage", String(input.perPage));
79
- if (input.active !== undefined)
80
- params.append("active", String(input.active));
81
- if (input.type)
82
- params.append("reward", input.type);
83
- if (input.categoryId)
84
- params.append("categoryId", input.categoryId);
85
- const queryString = params.toString();
86
- const url = `/${storeCode}/reward${queryString ? `?${queryString}` : ""}`;
87
- try {
88
- const response = await apiGet(url);
89
- const items = response.items || [];
90
- const rewards = items.map((r) => {
91
- const reward = r;
92
- return {
93
- rewardId: reward.rewardId,
94
- name: reward.name,
95
- type: (reward.reward || reward.type),
96
- costInPoints: reward.costInPoints,
97
- active: (reward.active ?? false),
98
- };
99
- });
100
- const total = response.total || {};
101
- return {
102
- rewards,
103
- total: {
104
- all: typeof total.all === 'number' ? total.all : undefined,
105
- filtered: typeof total.filtered === 'number' ? total.filtered : undefined,
106
- }
107
- };
108
- }
109
- catch (error) {
110
- throw formatApiError(error, "openloyalty_reward_list");
111
- }
112
- }
113
- export async function rewardCreate(input) {
114
- const storeCode = getStoreCode(input.storeCode);
115
- const payload = omitUndefined({
116
- name: input.name,
117
- type: input.type,
118
- costInPoints: input.costInPoints,
119
- description: input.description,
120
- usageInstruction: input.usageInstruction,
121
- active: input.active,
122
- categories: input.categories,
123
- levels: input.levels,
124
- segments: input.segments,
125
- target: input.target,
126
- couponValue: input.couponValue,
127
- couponValueType: input.couponValueType,
128
- daysValid: input.daysValid,
129
- });
130
- try {
131
- const response = await apiPost(`/${storeCode}/reward`, { reward: payload });
132
- return {
133
- rewardId: response.rewardId,
134
- name: input.name,
135
- costInPoints: input.costInPoints,
136
- };
137
- }
138
- catch (error) {
139
- throw formatApiError(error, "openloyalty_reward_create");
140
- }
141
- }
142
- export async function rewardGet(input) {
143
- const storeCode = getStoreCode(input.storeCode);
144
- try {
145
- const response = await apiGet(`/${storeCode}/reward/${input.rewardId}`);
146
- return RewardSchema.parse(response);
147
- }
148
- catch (error) {
149
- throw formatApiError(error, "openloyalty_reward_get");
150
- }
151
- }
152
- export async function rewardUpdate(input) {
153
- const storeCode = getStoreCode(input.storeCode);
154
- const payload = omitUndefined({
155
- name: input.name,
156
- costInPoints: input.costInPoints,
157
- description: input.description,
158
- active: input.active,
159
- categories: input.categories,
160
- levels: input.levels,
161
- segments: input.segments,
162
- });
163
- try {
164
- await apiPut(`/${storeCode}/reward/${input.rewardId}`, { reward: payload });
165
- }
166
- catch (error) {
167
- throw formatApiError(error, "openloyalty_reward_update");
168
- }
169
- }
170
- export async function rewardActivate(input) {
171
- const storeCode = getStoreCode(input.storeCode);
172
- try {
173
- await apiPost(`/${storeCode}/reward/${input.rewardId}/activate`);
174
- }
175
- catch (error) {
176
- throw formatApiError(error, "openloyalty_reward_activate");
177
- }
178
- }
179
- export async function rewardDeactivate(input) {
180
- const storeCode = getStoreCode(input.storeCode);
181
- try {
182
- await apiPost(`/${storeCode}/reward/${input.rewardId}/deactivate`);
183
- }
184
- catch (error) {
185
- throw formatApiError(error, "openloyalty_reward_deactivate");
186
- }
187
- }
188
- export async function rewardBuy(input) {
189
- const storeCode = getStoreCode(input.storeCode);
190
- const payload = omitUndefined({
191
- customerId: input.memberId,
192
- quantity: input.quantity,
193
- couponValue: input.couponValue,
194
- withoutPoints: input.withoutPoints,
195
- });
196
- try {
197
- const response = await apiPost(`/${storeCode}/reward/${input.rewardId}/buy`, payload);
198
- // API returns array of issued rewards
199
- const firstIssued = Array.isArray(response) ? response[0] : response;
200
- return {
201
- issuedRewardId: firstIssued?.issuedRewardId || "",
202
- couponCode: firstIssued?.couponCode,
203
- };
204
- }
205
- catch (error) {
206
- const errorMessage = error instanceof Error ? error.message : String(error);
207
- if (errorMessage.includes("NotEnoughPoints") || errorMessage.includes("insufficient")) {
208
- throw new OpenLoyaltyError({
209
- code: "INSUFFICIENT_BALANCE",
210
- message: "Member does not have enough points to purchase this reward",
211
- hint: `Use points_get_balance(memberId: "${input.memberId}") to check available balance. Then use reward_get(rewardId: "${input.rewardId}") to see the costInPoints required.`,
212
- relatedTool: "openloyalty_reward_buy",
213
- });
214
- }
215
- throw formatApiError(error, "openloyalty_reward_buy");
216
- }
217
- }
218
- export async function rewardRedeem(input) {
219
- const storeCode = getStoreCode(input.storeCode);
220
- try {
221
- const response = await apiPost(`/${storeCode}/member/${input.memberId}/reward/redeem`, { couponCode: input.couponCode });
222
- return { code: response.code || input.couponCode, used: true };
223
- }
224
- catch (error) {
225
- const errorMessage = error instanceof Error ? error.message : String(error);
226
- if (errorMessage.includes("CouponDoesNotExist")) {
227
- throw new OpenLoyaltyError({
228
- code: "COUPON_NOT_FOUND",
229
- message: `Coupon '${input.couponCode}' does not exist`,
230
- hint: `Verify the coupon code is correct. Use reward_buy to purchase a reward and obtain a valid coupon code.`,
231
- relatedTool: "openloyalty_reward_redeem",
232
- });
233
- }
234
- if (errorMessage.includes("CouponAlreadyUsed")) {
235
- throw new OpenLoyaltyError({
236
- code: "COUPON_ALREADY_USED",
237
- message: `Coupon '${input.couponCode}' has already been redeemed`,
238
- hint: `Each coupon can only be used once. The member may need to purchase another reward to get a new coupon.`,
239
- relatedTool: "openloyalty_reward_redeem",
240
- });
241
- }
242
- if (errorMessage.includes("CouponIsExpired")) {
243
- throw new OpenLoyaltyError({
244
- code: "COUPON_EXPIRED",
245
- message: `Coupon '${input.couponCode}' has expired`,
246
- hint: `Coupons have a validity period. The member will need to purchase a new reward for a fresh coupon.`,
247
- relatedTool: "openloyalty_reward_redeem",
248
- });
249
- }
250
- throw formatApiError(error, "openloyalty_reward_redeem");
251
- }
252
- }
253
- export async function rewardCategoryList(input) {
254
- const storeCode = getStoreCode(input.storeCode);
255
- const params = new URLSearchParams();
256
- if (input.page)
257
- params.append("_page", String(input.page));
258
- if (input.perPage)
259
- params.append("_itemsOnPage", String(input.perPage));
260
- if (input.active !== undefined)
261
- params.append("active", String(input.active));
262
- const queryString = params.toString();
263
- const url = `/${storeCode}/rewardCategory${queryString ? `?${queryString}` : ""}`;
264
- try {
265
- const response = await apiGet(url);
266
- const items = response.items || response.categories || [];
267
- const categories = items.map((c) => {
268
- const cat = c;
269
- return {
270
- categoryId: (cat.rewardCategoryId || cat.categoryId),
271
- name: cat.name,
272
- active: (cat.active ?? false),
273
- };
274
- });
275
- return { categories };
276
- }
277
- catch (error) {
278
- throw formatApiError(error, "openloyalty_reward_category_list");
279
- }
280
- }
281
- // Tool definitions
282
- export const rewardToolDefinitions = [
283
- {
284
- name: "openloyalty_reward_list",
285
- title: "Browse Rewards",
286
- description: "List available rewards. Use reward_get for full details or reward_buy to redeem. " +
287
- "Filter by type, active status, or category.",
288
- readOnly: true,
289
- inputSchema: RewardListInputSchema,
290
- handler: rewardList,
291
- },
292
- {
293
- name: "openloyalty_reward_create",
294
- title: "Create New Reward",
295
- description: "Create a new reward that members can redeem with points. " +
296
- "Types: static_coupon (fixed discount), dynamic_coupon (variable value set at purchase), " +
297
- "material (physical goods), conversion_coupon (converts points), fortune_wheel (gamified). " +
298
- "Returns rewardId.",
299
- readOnly: false,
300
- inputSchema: RewardCreateInputSchema,
301
- handler: rewardCreate,
302
- },
303
- {
304
- name: "openloyalty_reward_get",
305
- title: "Get Reward Details",
306
- description: "Get full reward details including configuration, targeting, and coupon settings.",
307
- readOnly: true,
308
- inputSchema: RewardGetInputSchema,
309
- handler: rewardGet,
310
- },
311
- {
312
- name: "openloyalty_reward_update",
313
- title: "Update Reward",
314
- description: "Update reward configuration. Cannot change reward type after creation.",
315
- readOnly: false,
316
- inputSchema: RewardUpdateInputSchema,
317
- handler: rewardUpdate,
318
- },
319
- {
320
- name: "openloyalty_reward_activate",
321
- title: "Activate Reward",
322
- description: "Activate a reward, making it available for members to redeem.",
323
- readOnly: false,
324
- inputSchema: RewardIdInputSchema,
325
- handler: rewardActivate,
326
- },
327
- {
328
- name: "openloyalty_reward_deactivate",
329
- title: "Deactivate Reward",
330
- description: "Deactivate a reward, hiding it from members. Already purchased rewards remain valid.",
331
- readOnly: false,
332
- inputSchema: RewardIdInputSchema,
333
- handler: rewardDeactivate,
334
- },
335
- {
336
- name: "openloyalty_reward_buy",
337
- title: "Redeem Reward for Member",
338
- description: "Purchase reward for member, deducting points. Returns issuedRewardId and couponCode if applicable. " +
339
- "Use reward_redeem to mark the coupon as used.",
340
- readOnly: false,
341
- inputSchema: RewardBuyInputSchema,
342
- handler: rewardBuy,
343
- },
344
- {
345
- name: "openloyalty_reward_redeem",
346
- title: "Use Coupon Code",
347
- description: "Mark coupon as used. Validates coupon exists, belongs to member, and is active. " +
348
- "Fails if coupon is expired, already used, or doesn't exist.",
349
- readOnly: false,
350
- inputSchema: RewardRedeemInputSchema,
351
- handler: rewardRedeem,
352
- },
353
- {
354
- name: "openloyalty_reward_category_list",
355
- title: "List Reward Categories",
356
- description: "List reward categories. Use categoryId when creating or filtering rewards.",
357
- readOnly: true,
358
- inputSchema: RewardCategoryListInputSchema,
359
- handler: rewardCategoryList,
360
- },
361
- ];