@open-loyalty/mcp-server 1.0.0
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/LICENSE +21 -0
- package/README.md +654 -0
- package/dist/client/http.d.ts +8 -0
- package/dist/client/http.js +69 -0
- package/dist/config.d.ts +17 -0
- package/dist/config.js +40 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +20 -0
- package/dist/server.d.ts +4 -0
- package/dist/server.js +334 -0
- package/dist/tools/achievement.d.ts +983 -0
- package/dist/tools/achievement.js +311 -0
- package/dist/tools/admin.d.ts +153 -0
- package/dist/tools/admin.js +193 -0
- package/dist/tools/analytics.d.ts +162 -0
- package/dist/tools/analytics.js +245 -0
- package/dist/tools/apikey.d.ts +72 -0
- package/dist/tools/apikey.js +78 -0
- package/dist/tools/audit.d.ts +107 -0
- package/dist/tools/audit.js +90 -0
- package/dist/tools/badge.d.ts +135 -0
- package/dist/tools/badge.js +165 -0
- package/dist/tools/campaign.d.ts +1775 -0
- package/dist/tools/campaign.js +724 -0
- package/dist/tools/export.d.ts +110 -0
- package/dist/tools/export.js +147 -0
- package/dist/tools/import.d.ts +110 -0
- package/dist/tools/import.js +126 -0
- package/dist/tools/index.d.ts +22 -0
- package/dist/tools/index.js +527 -0
- package/dist/tools/member.d.ts +345 -0
- package/dist/tools/member.js +358 -0
- package/dist/tools/member.test.d.ts +1 -0
- package/dist/tools/member.test.js +213 -0
- package/dist/tools/points.d.ts +188 -0
- package/dist/tools/points.js +306 -0
- package/dist/tools/points.test.d.ts +1 -0
- package/dist/tools/points.test.js +292 -0
- package/dist/tools/reward.d.ts +261 -0
- package/dist/tools/reward.js +371 -0
- package/dist/tools/reward.test.d.ts +1 -0
- package/dist/tools/reward.test.js +240 -0
- package/dist/tools/role.d.ts +161 -0
- package/dist/tools/role.js +160 -0
- package/dist/tools/segment.d.ts +797 -0
- package/dist/tools/segment.js +299 -0
- package/dist/tools/store.d.ts +101 -0
- package/dist/tools/store.js +117 -0
- package/dist/tools/tierset.d.ts +288 -0
- package/dist/tools/tierset.js +244 -0
- package/dist/tools/transaction.d.ts +357 -0
- package/dist/tools/transaction.js +242 -0
- package/dist/tools/transaction.test.d.ts +1 -0
- package/dist/tools/transaction.test.js +235 -0
- package/dist/tools/wallet-type.d.ts +32 -0
- package/dist/tools/wallet-type.js +58 -0
- package/dist/tools/webhook.d.ts +179 -0
- package/dist/tools/webhook.js +171 -0
- package/dist/types/schemas/achievement.d.ts +1116 -0
- package/dist/types/schemas/achievement.js +172 -0
- package/dist/types/schemas/admin.d.ts +263 -0
- package/dist/types/schemas/admin.js +99 -0
- package/dist/types/schemas/analytics.d.ts +542 -0
- package/dist/types/schemas/analytics.js +130 -0
- package/dist/types/schemas/badge.d.ts +131 -0
- package/dist/types/schemas/badge.js +48 -0
- package/dist/types/schemas/campaign.d.ts +2005 -0
- package/dist/types/schemas/campaign.js +189 -0
- package/dist/types/schemas/common.d.ts +52 -0
- package/dist/types/schemas/common.js +26 -0
- package/dist/types/schemas/export.d.ts +127 -0
- package/dist/types/schemas/export.js +43 -0
- package/dist/types/schemas/import.d.ts +344 -0
- package/dist/types/schemas/import.js +68 -0
- package/dist/types/schemas/member.d.ts +443 -0
- package/dist/types/schemas/member.js +92 -0
- package/dist/types/schemas/points.d.ts +188 -0
- package/dist/types/schemas/points.js +54 -0
- package/dist/types/schemas/reward.d.ts +278 -0
- package/dist/types/schemas/reward.js +69 -0
- package/dist/types/schemas/role.d.ts +260 -0
- package/dist/types/schemas/role.js +75 -0
- package/dist/types/schemas/segment.d.ts +592 -0
- package/dist/types/schemas/segment.js +114 -0
- package/dist/types/schemas/tierset.d.ts +552 -0
- package/dist/types/schemas/tierset.js +87 -0
- package/dist/types/schemas/transaction.d.ts +1022 -0
- package/dist/types/schemas/transaction.js +63 -0
- package/dist/types/schemas/wallet-type.d.ts +99 -0
- package/dist/types/schemas/wallet-type.js +17 -0
- package/dist/types/schemas/webhook.d.ts +195 -0
- package/dist/types/schemas/webhook.js +39 -0
- package/dist/utils/cursor.d.ts +84 -0
- package/dist/utils/cursor.js +117 -0
- package/dist/utils/errors.d.ts +12 -0
- package/dist/utils/errors.js +69 -0
- package/dist/utils/pagination.d.ts +39 -0
- package/dist/utils/pagination.js +77 -0
- package/package.json +65 -0
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { Member } from "../types/schemas/member.js";
|
|
3
|
+
export declare const MemberCreateInputSchema: {
|
|
4
|
+
storeCode: z.ZodOptional<z.ZodString>;
|
|
5
|
+
email: z.ZodString;
|
|
6
|
+
firstName: z.ZodOptional<z.ZodString>;
|
|
7
|
+
lastName: z.ZodOptional<z.ZodString>;
|
|
8
|
+
phone: z.ZodOptional<z.ZodString>;
|
|
9
|
+
birthDate: z.ZodOptional<z.ZodString>;
|
|
10
|
+
gender: z.ZodOptional<z.ZodEnum<["male", "female", "not_disclosed"]>>;
|
|
11
|
+
loyaltyCardNumber: z.ZodOptional<z.ZodString>;
|
|
12
|
+
agreement1: z.ZodOptional<z.ZodBoolean>;
|
|
13
|
+
agreement2: z.ZodOptional<z.ZodBoolean>;
|
|
14
|
+
agreement3: z.ZodOptional<z.ZodBoolean>;
|
|
15
|
+
address: z.ZodOptional<z.ZodObject<{
|
|
16
|
+
street: z.ZodOptional<z.ZodString>;
|
|
17
|
+
city: z.ZodOptional<z.ZodString>;
|
|
18
|
+
postal: z.ZodOptional<z.ZodString>;
|
|
19
|
+
country: z.ZodOptional<z.ZodString>;
|
|
20
|
+
province: z.ZodOptional<z.ZodString>;
|
|
21
|
+
}, "strip", z.ZodTypeAny, {
|
|
22
|
+
street?: string | undefined;
|
|
23
|
+
city?: string | undefined;
|
|
24
|
+
postal?: string | undefined;
|
|
25
|
+
country?: string | undefined;
|
|
26
|
+
province?: string | undefined;
|
|
27
|
+
}, {
|
|
28
|
+
street?: string | undefined;
|
|
29
|
+
city?: string | undefined;
|
|
30
|
+
postal?: string | undefined;
|
|
31
|
+
country?: string | undefined;
|
|
32
|
+
province?: string | undefined;
|
|
33
|
+
}>>;
|
|
34
|
+
};
|
|
35
|
+
export declare const MemberGetInputSchema: {
|
|
36
|
+
storeCode: z.ZodOptional<z.ZodString>;
|
|
37
|
+
memberId: z.ZodString;
|
|
38
|
+
};
|
|
39
|
+
export declare const MemberListInputSchema: {
|
|
40
|
+
storeCode: z.ZodOptional<z.ZodString>;
|
|
41
|
+
cursor: z.ZodOptional<z.ZodString>;
|
|
42
|
+
page: z.ZodOptional<z.ZodNumber>;
|
|
43
|
+
perPage: z.ZodOptional<z.ZodNumber>;
|
|
44
|
+
email: z.ZodOptional<z.ZodString>;
|
|
45
|
+
firstName: z.ZodOptional<z.ZodString>;
|
|
46
|
+
lastName: z.ZodOptional<z.ZodString>;
|
|
47
|
+
phone: z.ZodOptional<z.ZodString>;
|
|
48
|
+
loyaltyCardNumber: z.ZodOptional<z.ZodString>;
|
|
49
|
+
active: z.ZodOptional<z.ZodBoolean>;
|
|
50
|
+
};
|
|
51
|
+
export declare const MemberUpdateInputSchema: {
|
|
52
|
+
storeCode: z.ZodOptional<z.ZodString>;
|
|
53
|
+
memberId: z.ZodString;
|
|
54
|
+
firstName: z.ZodOptional<z.ZodString>;
|
|
55
|
+
lastName: z.ZodOptional<z.ZodString>;
|
|
56
|
+
phone: z.ZodOptional<z.ZodString>;
|
|
57
|
+
birthDate: z.ZodOptional<z.ZodString>;
|
|
58
|
+
gender: z.ZodOptional<z.ZodEnum<["male", "female", "not_disclosed"]>>;
|
|
59
|
+
address: z.ZodOptional<z.ZodObject<{
|
|
60
|
+
street: z.ZodOptional<z.ZodString>;
|
|
61
|
+
city: z.ZodOptional<z.ZodString>;
|
|
62
|
+
postal: z.ZodOptional<z.ZodString>;
|
|
63
|
+
country: z.ZodOptional<z.ZodString>;
|
|
64
|
+
province: z.ZodOptional<z.ZodString>;
|
|
65
|
+
}, "strip", z.ZodTypeAny, {
|
|
66
|
+
street?: string | undefined;
|
|
67
|
+
city?: string | undefined;
|
|
68
|
+
postal?: string | undefined;
|
|
69
|
+
country?: string | undefined;
|
|
70
|
+
province?: string | undefined;
|
|
71
|
+
}, {
|
|
72
|
+
street?: string | undefined;
|
|
73
|
+
city?: string | undefined;
|
|
74
|
+
postal?: string | undefined;
|
|
75
|
+
country?: string | undefined;
|
|
76
|
+
province?: string | undefined;
|
|
77
|
+
}>>;
|
|
78
|
+
agreement1: z.ZodOptional<z.ZodBoolean>;
|
|
79
|
+
agreement2: z.ZodOptional<z.ZodBoolean>;
|
|
80
|
+
agreement3: z.ZodOptional<z.ZodBoolean>;
|
|
81
|
+
};
|
|
82
|
+
export declare const MemberIdInputSchema: {
|
|
83
|
+
storeCode: z.ZodOptional<z.ZodString>;
|
|
84
|
+
memberId: z.ZodString;
|
|
85
|
+
};
|
|
86
|
+
export declare const MemberAssignTierInputSchema: {
|
|
87
|
+
storeCode: z.ZodOptional<z.ZodString>;
|
|
88
|
+
memberId: z.ZodString;
|
|
89
|
+
levelId: z.ZodString;
|
|
90
|
+
};
|
|
91
|
+
export declare function memberCreate(input: {
|
|
92
|
+
storeCode?: string;
|
|
93
|
+
email: string;
|
|
94
|
+
firstName?: string;
|
|
95
|
+
lastName?: string;
|
|
96
|
+
phone?: string;
|
|
97
|
+
birthDate?: string;
|
|
98
|
+
gender?: string;
|
|
99
|
+
loyaltyCardNumber?: string;
|
|
100
|
+
agreement1?: boolean;
|
|
101
|
+
agreement2?: boolean;
|
|
102
|
+
agreement3?: boolean;
|
|
103
|
+
address?: {
|
|
104
|
+
street?: string;
|
|
105
|
+
city?: string;
|
|
106
|
+
postal?: string;
|
|
107
|
+
country?: string;
|
|
108
|
+
province?: string;
|
|
109
|
+
};
|
|
110
|
+
}): Promise<{
|
|
111
|
+
memberId: string;
|
|
112
|
+
loyaltyCardNumber: string;
|
|
113
|
+
email: string;
|
|
114
|
+
}>;
|
|
115
|
+
export declare function memberGet(input: {
|
|
116
|
+
storeCode?: string;
|
|
117
|
+
memberId: string;
|
|
118
|
+
}): Promise<Member>;
|
|
119
|
+
export declare function memberList(input: {
|
|
120
|
+
storeCode?: string;
|
|
121
|
+
cursor?: string;
|
|
122
|
+
page?: number;
|
|
123
|
+
perPage?: number;
|
|
124
|
+
email?: string;
|
|
125
|
+
firstName?: string;
|
|
126
|
+
lastName?: string;
|
|
127
|
+
phone?: string;
|
|
128
|
+
loyaltyCardNumber?: string;
|
|
129
|
+
active?: boolean;
|
|
130
|
+
}): Promise<{
|
|
131
|
+
members: Array<{
|
|
132
|
+
memberId: string;
|
|
133
|
+
email: string;
|
|
134
|
+
firstName?: string;
|
|
135
|
+
lastName?: string;
|
|
136
|
+
loyaltyCardNumber?: string;
|
|
137
|
+
active: boolean;
|
|
138
|
+
}>;
|
|
139
|
+
total: {
|
|
140
|
+
all?: number;
|
|
141
|
+
filtered?: number;
|
|
142
|
+
};
|
|
143
|
+
cursor?: string;
|
|
144
|
+
}>;
|
|
145
|
+
export declare function memberUpdate(input: {
|
|
146
|
+
storeCode?: string;
|
|
147
|
+
memberId: string;
|
|
148
|
+
firstName?: string;
|
|
149
|
+
lastName?: string;
|
|
150
|
+
phone?: string;
|
|
151
|
+
birthDate?: string;
|
|
152
|
+
gender?: string;
|
|
153
|
+
address?: {
|
|
154
|
+
street?: string;
|
|
155
|
+
city?: string;
|
|
156
|
+
postal?: string;
|
|
157
|
+
country?: string;
|
|
158
|
+
province?: string;
|
|
159
|
+
};
|
|
160
|
+
agreement1?: boolean;
|
|
161
|
+
agreement2?: boolean;
|
|
162
|
+
agreement3?: boolean;
|
|
163
|
+
}): Promise<void>;
|
|
164
|
+
export declare function memberActivate(input: {
|
|
165
|
+
storeCode?: string;
|
|
166
|
+
memberId: string;
|
|
167
|
+
}): Promise<void>;
|
|
168
|
+
export declare function memberDeactivate(input: {
|
|
169
|
+
storeCode?: string;
|
|
170
|
+
memberId: string;
|
|
171
|
+
}): Promise<void>;
|
|
172
|
+
export declare function memberDelete(input: {
|
|
173
|
+
storeCode?: string;
|
|
174
|
+
memberId: string;
|
|
175
|
+
}): Promise<void>;
|
|
176
|
+
export declare function memberGetTierProgress(input: {
|
|
177
|
+
storeCode?: string;
|
|
178
|
+
memberId: string;
|
|
179
|
+
}): Promise<{
|
|
180
|
+
currentTier?: {
|
|
181
|
+
levelId: string;
|
|
182
|
+
name: string;
|
|
183
|
+
};
|
|
184
|
+
nextTier?: {
|
|
185
|
+
levelId: string;
|
|
186
|
+
name: string;
|
|
187
|
+
};
|
|
188
|
+
currentValue: number;
|
|
189
|
+
requiredValue?: number;
|
|
190
|
+
progressPercent: number;
|
|
191
|
+
}>;
|
|
192
|
+
export declare function memberAssignTier(input: {
|
|
193
|
+
storeCode?: string;
|
|
194
|
+
memberId: string;
|
|
195
|
+
levelId: string;
|
|
196
|
+
}): Promise<void>;
|
|
197
|
+
export declare function memberRemoveManualTier(input: {
|
|
198
|
+
storeCode?: string;
|
|
199
|
+
memberId: string;
|
|
200
|
+
}): Promise<void>;
|
|
201
|
+
export declare const memberToolDefinitions: readonly [{
|
|
202
|
+
readonly name: "openloyalty_member_create";
|
|
203
|
+
readonly description: "Register a new loyalty program member. Returns memberId for subsequent operations like points_add or member_get. Email must be unique within the store.";
|
|
204
|
+
readonly inputSchema: {
|
|
205
|
+
storeCode: z.ZodOptional<z.ZodString>;
|
|
206
|
+
email: z.ZodString;
|
|
207
|
+
firstName: z.ZodOptional<z.ZodString>;
|
|
208
|
+
lastName: z.ZodOptional<z.ZodString>;
|
|
209
|
+
phone: z.ZodOptional<z.ZodString>;
|
|
210
|
+
birthDate: z.ZodOptional<z.ZodString>;
|
|
211
|
+
gender: z.ZodOptional<z.ZodEnum<["male", "female", "not_disclosed"]>>;
|
|
212
|
+
loyaltyCardNumber: z.ZodOptional<z.ZodString>;
|
|
213
|
+
agreement1: z.ZodOptional<z.ZodBoolean>;
|
|
214
|
+
agreement2: z.ZodOptional<z.ZodBoolean>;
|
|
215
|
+
agreement3: z.ZodOptional<z.ZodBoolean>;
|
|
216
|
+
address: z.ZodOptional<z.ZodObject<{
|
|
217
|
+
street: z.ZodOptional<z.ZodString>;
|
|
218
|
+
city: z.ZodOptional<z.ZodString>;
|
|
219
|
+
postal: z.ZodOptional<z.ZodString>;
|
|
220
|
+
country: z.ZodOptional<z.ZodString>;
|
|
221
|
+
province: z.ZodOptional<z.ZodString>;
|
|
222
|
+
}, "strip", z.ZodTypeAny, {
|
|
223
|
+
street?: string | undefined;
|
|
224
|
+
city?: string | undefined;
|
|
225
|
+
postal?: string | undefined;
|
|
226
|
+
country?: string | undefined;
|
|
227
|
+
province?: string | undefined;
|
|
228
|
+
}, {
|
|
229
|
+
street?: string | undefined;
|
|
230
|
+
city?: string | undefined;
|
|
231
|
+
postal?: string | undefined;
|
|
232
|
+
country?: string | undefined;
|
|
233
|
+
province?: string | undefined;
|
|
234
|
+
}>>;
|
|
235
|
+
};
|
|
236
|
+
readonly handler: typeof memberCreate;
|
|
237
|
+
}, {
|
|
238
|
+
readonly name: "openloyalty_member_get";
|
|
239
|
+
readonly description: "Get member details including profile, points balance, and tier status. Use memberId from member_create or member_list.";
|
|
240
|
+
readonly inputSchema: {
|
|
241
|
+
storeCode: z.ZodOptional<z.ZodString>;
|
|
242
|
+
memberId: z.ZodString;
|
|
243
|
+
};
|
|
244
|
+
readonly handler: typeof memberGet;
|
|
245
|
+
}, {
|
|
246
|
+
readonly name: "openloyalty_member_list";
|
|
247
|
+
readonly description: string;
|
|
248
|
+
readonly inputSchema: {
|
|
249
|
+
storeCode: z.ZodOptional<z.ZodString>;
|
|
250
|
+
cursor: z.ZodOptional<z.ZodString>;
|
|
251
|
+
page: z.ZodOptional<z.ZodNumber>;
|
|
252
|
+
perPage: z.ZodOptional<z.ZodNumber>;
|
|
253
|
+
email: z.ZodOptional<z.ZodString>;
|
|
254
|
+
firstName: z.ZodOptional<z.ZodString>;
|
|
255
|
+
lastName: z.ZodOptional<z.ZodString>;
|
|
256
|
+
phone: z.ZodOptional<z.ZodString>;
|
|
257
|
+
loyaltyCardNumber: z.ZodOptional<z.ZodString>;
|
|
258
|
+
active: z.ZodOptional<z.ZodBoolean>;
|
|
259
|
+
};
|
|
260
|
+
readonly handler: typeof memberList;
|
|
261
|
+
}, {
|
|
262
|
+
readonly name: "openloyalty_member_update";
|
|
263
|
+
readonly description: "Update member profile fields. Cannot change email. Use member_get first to see current values.";
|
|
264
|
+
readonly inputSchema: {
|
|
265
|
+
storeCode: z.ZodOptional<z.ZodString>;
|
|
266
|
+
memberId: z.ZodString;
|
|
267
|
+
firstName: z.ZodOptional<z.ZodString>;
|
|
268
|
+
lastName: z.ZodOptional<z.ZodString>;
|
|
269
|
+
phone: z.ZodOptional<z.ZodString>;
|
|
270
|
+
birthDate: z.ZodOptional<z.ZodString>;
|
|
271
|
+
gender: z.ZodOptional<z.ZodEnum<["male", "female", "not_disclosed"]>>;
|
|
272
|
+
address: z.ZodOptional<z.ZodObject<{
|
|
273
|
+
street: z.ZodOptional<z.ZodString>;
|
|
274
|
+
city: z.ZodOptional<z.ZodString>;
|
|
275
|
+
postal: z.ZodOptional<z.ZodString>;
|
|
276
|
+
country: z.ZodOptional<z.ZodString>;
|
|
277
|
+
province: z.ZodOptional<z.ZodString>;
|
|
278
|
+
}, "strip", z.ZodTypeAny, {
|
|
279
|
+
street?: string | undefined;
|
|
280
|
+
city?: string | undefined;
|
|
281
|
+
postal?: string | undefined;
|
|
282
|
+
country?: string | undefined;
|
|
283
|
+
province?: string | undefined;
|
|
284
|
+
}, {
|
|
285
|
+
street?: string | undefined;
|
|
286
|
+
city?: string | undefined;
|
|
287
|
+
postal?: string | undefined;
|
|
288
|
+
country?: string | undefined;
|
|
289
|
+
province?: string | undefined;
|
|
290
|
+
}>>;
|
|
291
|
+
agreement1: z.ZodOptional<z.ZodBoolean>;
|
|
292
|
+
agreement2: z.ZodOptional<z.ZodBoolean>;
|
|
293
|
+
agreement3: z.ZodOptional<z.ZodBoolean>;
|
|
294
|
+
};
|
|
295
|
+
readonly handler: typeof memberUpdate;
|
|
296
|
+
}, {
|
|
297
|
+
readonly name: "openloyalty_member_activate";
|
|
298
|
+
readonly description: "Activate a member account. Inactive members cannot earn or spend points.";
|
|
299
|
+
readonly inputSchema: {
|
|
300
|
+
storeCode: z.ZodOptional<z.ZodString>;
|
|
301
|
+
memberId: z.ZodString;
|
|
302
|
+
};
|
|
303
|
+
readonly handler: typeof memberActivate;
|
|
304
|
+
}, {
|
|
305
|
+
readonly name: "openloyalty_member_deactivate";
|
|
306
|
+
readonly description: "Deactivate a member account. Deactivated members cannot earn or spend points but retain their balance.";
|
|
307
|
+
readonly inputSchema: {
|
|
308
|
+
storeCode: z.ZodOptional<z.ZodString>;
|
|
309
|
+
memberId: z.ZodString;
|
|
310
|
+
};
|
|
311
|
+
readonly handler: typeof memberDeactivate;
|
|
312
|
+
}, {
|
|
313
|
+
readonly name: "openloyalty_member_delete";
|
|
314
|
+
readonly description: "Permanently removes member and all associated data. Cannot be undone. Use for GDPR compliance or member requests.";
|
|
315
|
+
readonly inputSchema: {
|
|
316
|
+
storeCode: z.ZodOptional<z.ZodString>;
|
|
317
|
+
memberId: z.ZodString;
|
|
318
|
+
};
|
|
319
|
+
readonly handler: typeof memberDelete;
|
|
320
|
+
}, {
|
|
321
|
+
readonly name: "openloyalty_member_get_tier_progress";
|
|
322
|
+
readonly description: "Get member tier progression status showing current tier and progress to next. Returns currentValue, requiredValue, and progressPercent.";
|
|
323
|
+
readonly inputSchema: {
|
|
324
|
+
storeCode: z.ZodOptional<z.ZodString>;
|
|
325
|
+
memberId: z.ZodString;
|
|
326
|
+
};
|
|
327
|
+
readonly handler: typeof memberGetTierProgress;
|
|
328
|
+
}, {
|
|
329
|
+
readonly name: "openloyalty_member_assign_tier";
|
|
330
|
+
readonly description: "Manually assign a tier level to a member, overriding automatic tier calculation. Use tierset_get_tiers to find available levelId values.";
|
|
331
|
+
readonly inputSchema: {
|
|
332
|
+
storeCode: z.ZodOptional<z.ZodString>;
|
|
333
|
+
memberId: z.ZodString;
|
|
334
|
+
levelId: z.ZodString;
|
|
335
|
+
};
|
|
336
|
+
readonly handler: typeof memberAssignTier;
|
|
337
|
+
}, {
|
|
338
|
+
readonly name: "openloyalty_member_remove_manual_tier";
|
|
339
|
+
readonly description: "Remove manually assigned tier from member, restoring automatic tier calculation based on conditions.";
|
|
340
|
+
readonly inputSchema: {
|
|
341
|
+
storeCode: z.ZodOptional<z.ZodString>;
|
|
342
|
+
memberId: z.ZodString;
|
|
343
|
+
};
|
|
344
|
+
readonly handler: typeof memberRemoveManualTier;
|
|
345
|
+
}];
|
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { apiGet, apiPost, apiPut, apiDelete } from "../client/http.js";
|
|
3
|
+
import { MemberSchema, } from "../types/schemas/member.js";
|
|
4
|
+
import { formatApiError } from "../utils/errors.js";
|
|
5
|
+
import { getConfig } from "../config.js";
|
|
6
|
+
import { buildPaginationParams } from "../utils/pagination.js";
|
|
7
|
+
// Input Schemas
|
|
8
|
+
export const MemberCreateInputSchema = {
|
|
9
|
+
storeCode: z.string().optional().describe("Store code. If not provided, uses the default store code from configuration."),
|
|
10
|
+
email: z.string().describe("Member email address (required, must be unique)."),
|
|
11
|
+
firstName: z.string().optional().describe("Member first name."),
|
|
12
|
+
lastName: z.string().optional().describe("Member last name."),
|
|
13
|
+
phone: z.string().optional().describe("Member phone number."),
|
|
14
|
+
birthDate: z.string().optional().describe("Member birth date (YYYY-MM-DD format)."),
|
|
15
|
+
gender: z.enum(["male", "female", "not_disclosed"]).optional().describe("Member gender."),
|
|
16
|
+
loyaltyCardNumber: z.string().optional().describe("Loyalty card number. Auto-generated if not provided."),
|
|
17
|
+
agreement1: z.boolean().optional().describe("Terms acceptance."),
|
|
18
|
+
agreement2: z.boolean().optional().describe("Marketing consent."),
|
|
19
|
+
agreement3: z.boolean().optional().describe("Additional agreement."),
|
|
20
|
+
address: z.object({
|
|
21
|
+
street: z.string().optional(),
|
|
22
|
+
city: z.string().optional(),
|
|
23
|
+
postal: z.string().optional(),
|
|
24
|
+
country: z.string().optional(),
|
|
25
|
+
province: z.string().optional(),
|
|
26
|
+
}).optional().describe("Member address."),
|
|
27
|
+
};
|
|
28
|
+
export const MemberGetInputSchema = {
|
|
29
|
+
storeCode: z.string().optional().describe("Store code. If not provided, uses the default store code from configuration."),
|
|
30
|
+
memberId: z.string().describe("The member ID (UUID) to retrieve."),
|
|
31
|
+
};
|
|
32
|
+
export const MemberListInputSchema = {
|
|
33
|
+
storeCode: z.string().optional().describe("Store code. If not provided, uses the default store code from configuration."),
|
|
34
|
+
cursor: z.string().optional().describe("Pagination cursor from previous response. If provided, page/perPage are ignored."),
|
|
35
|
+
page: z.number().optional().describe("Page number (default: 1)."),
|
|
36
|
+
perPage: z.number().optional().describe("Items per page (default: 10)."),
|
|
37
|
+
email: z.string().optional().describe("Filter by email address."),
|
|
38
|
+
firstName: z.string().optional().describe("Filter by first name."),
|
|
39
|
+
lastName: z.string().optional().describe("Filter by last name."),
|
|
40
|
+
phone: z.string().optional().describe("Filter by phone number."),
|
|
41
|
+
loyaltyCardNumber: z.string().optional().describe("Filter by loyalty card number."),
|
|
42
|
+
active: z.boolean().optional().describe("Filter by active status."),
|
|
43
|
+
};
|
|
44
|
+
export const MemberUpdateInputSchema = {
|
|
45
|
+
storeCode: z.string().optional().describe("Store code. If not provided, uses the default store code from configuration."),
|
|
46
|
+
memberId: z.string().describe("The member ID (UUID) to update."),
|
|
47
|
+
firstName: z.string().optional().describe("Member first name."),
|
|
48
|
+
lastName: z.string().optional().describe("Member last name."),
|
|
49
|
+
phone: z.string().optional().describe("Member phone number."),
|
|
50
|
+
birthDate: z.string().optional().describe("Member birth date (YYYY-MM-DD format)."),
|
|
51
|
+
gender: z.enum(["male", "female", "not_disclosed"]).optional().describe("Member gender."),
|
|
52
|
+
address: z.object({
|
|
53
|
+
street: z.string().optional(),
|
|
54
|
+
city: z.string().optional(),
|
|
55
|
+
postal: z.string().optional(),
|
|
56
|
+
country: z.string().optional(),
|
|
57
|
+
province: z.string().optional(),
|
|
58
|
+
}).optional().describe("Member address."),
|
|
59
|
+
agreement1: z.boolean().optional().describe("Terms acceptance."),
|
|
60
|
+
agreement2: z.boolean().optional().describe("Marketing consent."),
|
|
61
|
+
agreement3: z.boolean().optional().describe("Additional agreement."),
|
|
62
|
+
};
|
|
63
|
+
export const MemberIdInputSchema = {
|
|
64
|
+
storeCode: z.string().optional().describe("Store code. If not provided, uses the default store code from configuration."),
|
|
65
|
+
memberId: z.string().describe("The member ID (UUID)."),
|
|
66
|
+
};
|
|
67
|
+
export const MemberAssignTierInputSchema = {
|
|
68
|
+
storeCode: z.string().optional().describe("Store code. If not provided, uses the default store code from configuration."),
|
|
69
|
+
memberId: z.string().describe("The member ID (UUID)."),
|
|
70
|
+
levelId: z.string().describe("The tier level ID (UUID) to assign."),
|
|
71
|
+
};
|
|
72
|
+
// Handler functions
|
|
73
|
+
export async function memberCreate(input) {
|
|
74
|
+
const config = getConfig();
|
|
75
|
+
const storeCode = input.storeCode || config.defaultStoreCode;
|
|
76
|
+
const payload = {
|
|
77
|
+
email: input.email,
|
|
78
|
+
};
|
|
79
|
+
if (input.firstName)
|
|
80
|
+
payload.firstName = input.firstName;
|
|
81
|
+
if (input.lastName)
|
|
82
|
+
payload.lastName = input.lastName;
|
|
83
|
+
if (input.phone)
|
|
84
|
+
payload.phone = input.phone;
|
|
85
|
+
if (input.birthDate)
|
|
86
|
+
payload.birthDate = input.birthDate;
|
|
87
|
+
if (input.gender)
|
|
88
|
+
payload.gender = input.gender;
|
|
89
|
+
if (input.loyaltyCardNumber)
|
|
90
|
+
payload.loyaltyCardNumber = input.loyaltyCardNumber;
|
|
91
|
+
if (input.agreement1 !== undefined)
|
|
92
|
+
payload.agreement1 = input.agreement1;
|
|
93
|
+
if (input.agreement2 !== undefined)
|
|
94
|
+
payload.agreement2 = input.agreement2;
|
|
95
|
+
if (input.agreement3 !== undefined)
|
|
96
|
+
payload.agreement3 = input.agreement3;
|
|
97
|
+
if (input.address)
|
|
98
|
+
payload.address = input.address;
|
|
99
|
+
try {
|
|
100
|
+
const response = await apiPost(`/${storeCode}/member`, { customer: payload });
|
|
101
|
+
return {
|
|
102
|
+
memberId: response.customerId,
|
|
103
|
+
loyaltyCardNumber: response.loyaltyCardNumber || "",
|
|
104
|
+
email: response.email,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
throw formatApiError(error, "openloyalty_member_create");
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
export async function memberGet(input) {
|
|
112
|
+
const config = getConfig();
|
|
113
|
+
const storeCode = input.storeCode || config.defaultStoreCode;
|
|
114
|
+
try {
|
|
115
|
+
const response = await apiGet(`/${storeCode}/member/${input.memberId}`);
|
|
116
|
+
// Map API response to our schema
|
|
117
|
+
const data = response;
|
|
118
|
+
const mapped = {
|
|
119
|
+
memberId: data.customerId || data.memberId,
|
|
120
|
+
email: data.email,
|
|
121
|
+
firstName: data.firstName,
|
|
122
|
+
lastName: data.lastName,
|
|
123
|
+
phone: data.phone,
|
|
124
|
+
birthDate: data.birthDate,
|
|
125
|
+
gender: data.gender,
|
|
126
|
+
loyaltyCardNumber: data.loyaltyCardNumber,
|
|
127
|
+
active: data.active ?? true,
|
|
128
|
+
createdAt: data.createdAt,
|
|
129
|
+
address: data.address,
|
|
130
|
+
agreement1: data.agreement1,
|
|
131
|
+
agreement2: data.agreement2,
|
|
132
|
+
agreement3: data.agreement3,
|
|
133
|
+
levelId: data.levelId || data.level?.levelId,
|
|
134
|
+
levelName: data.levelName || data.level?.name,
|
|
135
|
+
points: data.points,
|
|
136
|
+
};
|
|
137
|
+
return MemberSchema.parse(mapped);
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
throw formatApiError(error, "openloyalty_member_get");
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
export async function memberList(input) {
|
|
144
|
+
const config = getConfig();
|
|
145
|
+
const storeCode = input.storeCode || config.defaultStoreCode;
|
|
146
|
+
const params = new URLSearchParams();
|
|
147
|
+
// Use buildPaginationParams for cursor/page handling
|
|
148
|
+
buildPaginationParams({ cursor: input.cursor, page: input.page, perPage: input.perPage }, params);
|
|
149
|
+
if (input.email)
|
|
150
|
+
params.append("email", input.email);
|
|
151
|
+
if (input.firstName)
|
|
152
|
+
params.append("firstName", input.firstName);
|
|
153
|
+
if (input.lastName)
|
|
154
|
+
params.append("lastName", input.lastName);
|
|
155
|
+
if (input.phone)
|
|
156
|
+
params.append("phone", input.phone);
|
|
157
|
+
if (input.loyaltyCardNumber)
|
|
158
|
+
params.append("loyaltyCardNumber", input.loyaltyCardNumber);
|
|
159
|
+
if (input.active !== undefined)
|
|
160
|
+
params.append("active", String(input.active));
|
|
161
|
+
const queryString = params.toString();
|
|
162
|
+
const url = `/${storeCode}/member${queryString ? `?${queryString}` : ""}`;
|
|
163
|
+
try {
|
|
164
|
+
const response = await apiGet(url);
|
|
165
|
+
const members = (response.items || []).map((c) => {
|
|
166
|
+
const customer = c;
|
|
167
|
+
return {
|
|
168
|
+
memberId: (customer.customerId || customer.memberId),
|
|
169
|
+
email: customer.email,
|
|
170
|
+
firstName: customer.firstName,
|
|
171
|
+
lastName: customer.lastName,
|
|
172
|
+
loyaltyCardNumber: customer.loyaltyCardNumber,
|
|
173
|
+
active: (customer.active ?? true),
|
|
174
|
+
};
|
|
175
|
+
});
|
|
176
|
+
const total = response.total || {};
|
|
177
|
+
return {
|
|
178
|
+
members,
|
|
179
|
+
total: {
|
|
180
|
+
all: typeof total.all === 'number' ? total.all : undefined,
|
|
181
|
+
filtered: typeof total.filtered === 'number' ? total.filtered : undefined,
|
|
182
|
+
},
|
|
183
|
+
cursor: response.scroll,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
catch (error) {
|
|
187
|
+
throw formatApiError(error, "openloyalty_member_list");
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
export async function memberUpdate(input) {
|
|
191
|
+
const config = getConfig();
|
|
192
|
+
const storeCode = input.storeCode || config.defaultStoreCode;
|
|
193
|
+
const payload = {};
|
|
194
|
+
if (input.firstName)
|
|
195
|
+
payload.firstName = input.firstName;
|
|
196
|
+
if (input.lastName)
|
|
197
|
+
payload.lastName = input.lastName;
|
|
198
|
+
if (input.phone)
|
|
199
|
+
payload.phone = input.phone;
|
|
200
|
+
if (input.birthDate)
|
|
201
|
+
payload.birthDate = input.birthDate;
|
|
202
|
+
if (input.gender)
|
|
203
|
+
payload.gender = input.gender;
|
|
204
|
+
if (input.address)
|
|
205
|
+
payload.address = input.address;
|
|
206
|
+
if (input.agreement1 !== undefined)
|
|
207
|
+
payload.agreement1 = input.agreement1;
|
|
208
|
+
if (input.agreement2 !== undefined)
|
|
209
|
+
payload.agreement2 = input.agreement2;
|
|
210
|
+
if (input.agreement3 !== undefined)
|
|
211
|
+
payload.agreement3 = input.agreement3;
|
|
212
|
+
try {
|
|
213
|
+
await apiPut(`/${storeCode}/member/${input.memberId}`, { customer: payload });
|
|
214
|
+
}
|
|
215
|
+
catch (error) {
|
|
216
|
+
throw formatApiError(error, "openloyalty_member_update");
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
export async function memberActivate(input) {
|
|
220
|
+
const config = getConfig();
|
|
221
|
+
const storeCode = input.storeCode || config.defaultStoreCode;
|
|
222
|
+
try {
|
|
223
|
+
await apiPost(`/${storeCode}/member/${input.memberId}/activate`);
|
|
224
|
+
}
|
|
225
|
+
catch (error) {
|
|
226
|
+
throw formatApiError(error, "openloyalty_member_activate");
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
export async function memberDeactivate(input) {
|
|
230
|
+
const config = getConfig();
|
|
231
|
+
const storeCode = input.storeCode || config.defaultStoreCode;
|
|
232
|
+
try {
|
|
233
|
+
await apiPost(`/${storeCode}/member/${input.memberId}/deactivate`);
|
|
234
|
+
}
|
|
235
|
+
catch (error) {
|
|
236
|
+
throw formatApiError(error, "openloyalty_member_deactivate");
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
export async function memberDelete(input) {
|
|
240
|
+
const config = getConfig();
|
|
241
|
+
const storeCode = input.storeCode || config.defaultStoreCode;
|
|
242
|
+
try {
|
|
243
|
+
await apiDelete(`/${storeCode}/member/${input.memberId}`);
|
|
244
|
+
}
|
|
245
|
+
catch (error) {
|
|
246
|
+
throw formatApiError(error, "openloyalty_member_delete");
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
export async function memberGetTierProgress(input) {
|
|
250
|
+
const config = getConfig();
|
|
251
|
+
const storeCode = input.storeCode || config.defaultStoreCode;
|
|
252
|
+
try {
|
|
253
|
+
const response = await apiGet(`/${storeCode}/member/${input.memberId}/tier`);
|
|
254
|
+
const currentLevel = response.currentLevel;
|
|
255
|
+
const nextLevel = response.nextLevel;
|
|
256
|
+
return {
|
|
257
|
+
currentTier: currentLevel ? {
|
|
258
|
+
levelId: currentLevel.levelId,
|
|
259
|
+
name: currentLevel.name,
|
|
260
|
+
} : undefined,
|
|
261
|
+
nextTier: nextLevel ? {
|
|
262
|
+
levelId: nextLevel.levelId,
|
|
263
|
+
name: nextLevel.name,
|
|
264
|
+
} : undefined,
|
|
265
|
+
currentValue: (response.currentValue || 0),
|
|
266
|
+
requiredValue: response.requiredValue,
|
|
267
|
+
progressPercent: (response.progressPercent || response.progress || 0),
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
catch (error) {
|
|
271
|
+
throw formatApiError(error, "openloyalty_member_get_tier_progress");
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
export async function memberAssignTier(input) {
|
|
275
|
+
const config = getConfig();
|
|
276
|
+
const storeCode = input.storeCode || config.defaultStoreCode;
|
|
277
|
+
try {
|
|
278
|
+
await apiPost(`/${storeCode}/member/${input.memberId}/tier`, { levelId: input.levelId });
|
|
279
|
+
}
|
|
280
|
+
catch (error) {
|
|
281
|
+
throw formatApiError(error, "openloyalty_member_assign_tier");
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
export async function memberRemoveManualTier(input) {
|
|
285
|
+
const config = getConfig();
|
|
286
|
+
const storeCode = input.storeCode || config.defaultStoreCode;
|
|
287
|
+
try {
|
|
288
|
+
// API uses POST to /remove-manually-level, not DELETE to /tier
|
|
289
|
+
await apiPost(`/${storeCode}/member/${input.memberId}/remove-manually-level`);
|
|
290
|
+
}
|
|
291
|
+
catch (error) {
|
|
292
|
+
throw formatApiError(error, "openloyalty_member_remove_manual_tier");
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
// Tool definitions
|
|
296
|
+
export const memberToolDefinitions = [
|
|
297
|
+
{
|
|
298
|
+
name: "openloyalty_member_create",
|
|
299
|
+
description: "Register a new loyalty program member. Returns memberId for subsequent operations like points_add or member_get. Email must be unique within the store.",
|
|
300
|
+
inputSchema: MemberCreateInputSchema,
|
|
301
|
+
handler: memberCreate,
|
|
302
|
+
},
|
|
303
|
+
{
|
|
304
|
+
name: "openloyalty_member_get",
|
|
305
|
+
description: "Get member details including profile, points balance, and tier status. Use memberId from member_create or member_list.",
|
|
306
|
+
inputSchema: MemberGetInputSchema,
|
|
307
|
+
handler: memberGet,
|
|
308
|
+
},
|
|
309
|
+
{
|
|
310
|
+
name: "openloyalty_member_list",
|
|
311
|
+
description: "Search and list members with optional filters. Use member_get for full details of a specific member. " +
|
|
312
|
+
"Supports cursor pagination: provide 'cursor' from previous response to get next page.",
|
|
313
|
+
inputSchema: MemberListInputSchema,
|
|
314
|
+
handler: memberList,
|
|
315
|
+
},
|
|
316
|
+
{
|
|
317
|
+
name: "openloyalty_member_update",
|
|
318
|
+
description: "Update member profile fields. Cannot change email. Use member_get first to see current values.",
|
|
319
|
+
inputSchema: MemberUpdateInputSchema,
|
|
320
|
+
handler: memberUpdate,
|
|
321
|
+
},
|
|
322
|
+
{
|
|
323
|
+
name: "openloyalty_member_activate",
|
|
324
|
+
description: "Activate a member account. Inactive members cannot earn or spend points.",
|
|
325
|
+
inputSchema: MemberIdInputSchema,
|
|
326
|
+
handler: memberActivate,
|
|
327
|
+
},
|
|
328
|
+
{
|
|
329
|
+
name: "openloyalty_member_deactivate",
|
|
330
|
+
description: "Deactivate a member account. Deactivated members cannot earn or spend points but retain their balance.",
|
|
331
|
+
inputSchema: MemberIdInputSchema,
|
|
332
|
+
handler: memberDeactivate,
|
|
333
|
+
},
|
|
334
|
+
{
|
|
335
|
+
name: "openloyalty_member_delete",
|
|
336
|
+
description: "Permanently removes member and all associated data. Cannot be undone. Use for GDPR compliance or member requests.",
|
|
337
|
+
inputSchema: MemberIdInputSchema,
|
|
338
|
+
handler: memberDelete,
|
|
339
|
+
},
|
|
340
|
+
{
|
|
341
|
+
name: "openloyalty_member_get_tier_progress",
|
|
342
|
+
description: "Get member tier progression status showing current tier and progress to next. Returns currentValue, requiredValue, and progressPercent.",
|
|
343
|
+
inputSchema: MemberIdInputSchema,
|
|
344
|
+
handler: memberGetTierProgress,
|
|
345
|
+
},
|
|
346
|
+
{
|
|
347
|
+
name: "openloyalty_member_assign_tier",
|
|
348
|
+
description: "Manually assign a tier level to a member, overriding automatic tier calculation. Use tierset_get_tiers to find available levelId values.",
|
|
349
|
+
inputSchema: MemberAssignTierInputSchema,
|
|
350
|
+
handler: memberAssignTier,
|
|
351
|
+
},
|
|
352
|
+
{
|
|
353
|
+
name: "openloyalty_member_remove_manual_tier",
|
|
354
|
+
description: "Remove manually assigned tier from member, restoring automatic tier calculation based on conditions.",
|
|
355
|
+
inputSchema: MemberIdInputSchema,
|
|
356
|
+
handler: memberRemoveManualTier,
|
|
357
|
+
},
|
|
358
|
+
];
|