@open-loyalty/mcp-server 1.1.0 → 1.3.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/README.md +180 -177
- package/dist/auth/provider.js +2 -14
- package/dist/auth/storage.js +22 -0
- package/dist/client/http.js +10 -0
- package/dist/config.d.ts +0 -13
- package/dist/config.js +0 -14
- package/dist/http.js +35 -3
- package/dist/instructions.d.ts +5 -0
- package/dist/instructions.js +440 -0
- package/dist/prompts/fan-engagement-setup.d.ts +107 -0
- package/dist/prompts/fan-engagement-setup.js +492 -0
- package/dist/server.d.ts +1 -1
- package/dist/server.js +60 -273
- package/dist/tools/achievement/handlers.d.ts +117 -0
- package/dist/tools/achievement/handlers.js +161 -0
- package/dist/tools/achievement/index.d.ts +479 -0
- package/dist/tools/achievement/index.js +74 -0
- package/dist/tools/achievement/schemas.d.ts +433 -0
- package/dist/tools/achievement/schemas.js +142 -0
- package/dist/tools/achievement.d.ts +141 -121
- package/dist/tools/achievement.js +60 -24
- package/dist/tools/admin.d.ts +6 -6
- package/dist/tools/admin.js +12 -12
- package/dist/tools/analytics.d.ts +11 -11
- package/dist/tools/analytics.js +30 -29
- package/dist/tools/apikey.d.ts +3 -3
- package/dist/tools/apikey.js +6 -6
- package/dist/tools/audit.d.ts +2 -2
- package/dist/tools/audit.js +4 -4
- package/dist/tools/badge.d.ts +6 -6
- package/dist/tools/badge.js +23 -18
- package/dist/tools/campaign/handlers.d.ts +42 -0
- package/dist/tools/campaign/handlers.js +223 -0
- package/dist/tools/campaign/index.d.ts +783 -0
- package/dist/tools/campaign/index.js +117 -0
- package/dist/tools/campaign/member-handlers.d.ts +60 -0
- package/dist/tools/campaign/member-handlers.js +159 -0
- package/dist/tools/campaign/schemas.d.ts +704 -0
- package/dist/tools/campaign/schemas.js +259 -0
- package/dist/tools/campaign/types.d.ts +161 -0
- package/dist/tools/campaign/types.js +2 -0
- package/dist/tools/custom-event.d.ts +315 -0
- package/dist/tools/custom-event.js +270 -0
- package/dist/tools/export.d.ts +4 -4
- package/dist/tools/export.js +12 -12
- package/dist/tools/import.d.ts +3 -3
- package/dist/tools/import.js +23 -15
- package/dist/tools/index.js +13 -5
- package/dist/tools/member/handlers.d.ts +111 -0
- package/dist/tools/member/handlers.js +206 -0
- package/dist/tools/member/index.d.ts +169 -0
- package/dist/tools/member/index.js +92 -0
- package/dist/tools/member/schemas.d.ts +89 -0
- package/dist/tools/member/schemas.js +65 -0
- package/dist/tools/points.d.ts +7 -6
- package/dist/tools/points.js +21 -20
- package/dist/tools/referral/handlers.d.ts +47 -0
- package/dist/tools/referral/handlers.js +115 -0
- package/dist/tools/referral/index.d.ts +44 -0
- package/dist/tools/referral/index.js +44 -0
- package/dist/tools/referral/schemas.d.ts +34 -0
- package/dist/tools/referral/schemas.js +52 -0
- package/dist/tools/reward/handlers.d.ts +110 -0
- package/dist/tools/reward/handlers.js +289 -0
- package/dist/tools/reward/index.d.ts +177 -0
- package/dist/tools/reward/index.js +93 -0
- package/dist/tools/reward/schemas.d.ts +116 -0
- package/dist/tools/reward/schemas.js +92 -0
- package/dist/tools/role.d.ts +6 -6
- package/dist/tools/role.js +12 -12
- package/dist/tools/segment/handlers.d.ts +87 -0
- package/dist/tools/segment/handlers.js +174 -0
- package/dist/tools/segment/index.d.ts +395 -0
- package/dist/tools/segment/index.js +88 -0
- package/dist/tools/segment/schemas.d.ts +337 -0
- package/dist/tools/segment/schemas.js +79 -0
- package/dist/tools/segment.d.ts +10 -10
- package/dist/tools/segment.js +55 -31
- package/dist/tools/store.d.ts +4 -4
- package/dist/tools/store.js +8 -8
- package/dist/tools/tierset.d.ts +10 -10
- package/dist/tools/tierset.js +69 -37
- package/dist/tools/transaction.d.ts +4 -4
- package/dist/tools/transaction.js +12 -12
- package/dist/tools/wallet-type.d.ts +221 -16
- package/dist/tools/wallet-type.js +248 -17
- package/dist/tools/webhook.d.ts +6 -6
- package/dist/tools/webhook.js +90 -31
- package/dist/types/schemas/achievement.d.ts +18 -18
- package/dist/types/schemas/campaign.d.ts +64 -184
- package/dist/types/schemas/campaign.js +2 -7
- package/dist/types/schemas/common.d.ts +5 -0
- package/dist/types/schemas/common.js +5 -0
- package/dist/types/schemas/member.d.ts +2 -2
- package/dist/types/schemas/reward.d.ts +94 -18
- package/dist/types/schemas/reward.js +8 -3
- package/dist/types/schemas/wallet-type.d.ts +306 -8
- package/dist/types/schemas/wallet-type.js +82 -1
- package/dist/utils/errors.js +32 -5
- package/dist/workflows/app-login-streak.d.ts +39 -0
- package/dist/workflows/app-login-streak.js +298 -0
- package/dist/workflows/early-arrival.d.ts +33 -0
- package/dist/workflows/early-arrival.js +148 -0
- package/dist/workflows/index.d.ts +101 -0
- package/dist/workflows/index.js +208 -0
- package/dist/workflows/match-attendance.d.ts +45 -0
- package/dist/workflows/match-attendance.js +308 -0
- package/dist/workflows/sportsbar-visit.d.ts +41 -0
- package/dist/workflows/sportsbar-visit.js +284 -0
- package/dist/workflows/vod-watching.d.ts +43 -0
- package/dist/workflows/vod-watching.js +326 -0
- package/package.json +8 -2
package/dist/tools/apikey.d.ts
CHANGED
|
@@ -44,7 +44,7 @@ export declare function apiKeyDelete(input: {
|
|
|
44
44
|
apiKeyId: string;
|
|
45
45
|
}): Promise<void>;
|
|
46
46
|
export declare const apiKeyToolDefinitions: readonly [{
|
|
47
|
-
readonly name: "
|
|
47
|
+
readonly name: "ol_apikey_create";
|
|
48
48
|
readonly title: "Create API Key";
|
|
49
49
|
readonly description: "Create a new API key for an admin user. CRITICAL: The API token is ONLY returned at creation time. Store it securely immediately - it cannot be retrieved later. Returns apiKeyId, token, adminId, name, and expirationDate.";
|
|
50
50
|
readonly readOnly: false;
|
|
@@ -55,7 +55,7 @@ export declare const apiKeyToolDefinitions: readonly [{
|
|
|
55
55
|
};
|
|
56
56
|
readonly handler: typeof apiKeyCreate;
|
|
57
57
|
}, {
|
|
58
|
-
readonly name: "
|
|
58
|
+
readonly name: "ol_apikey_list";
|
|
59
59
|
readonly title: "List API Keys";
|
|
60
60
|
readonly description: "List API keys for an admin user. Returns list of API keys with apiKeyId, adminId, name, and expirationDate. Note: tokens are not returned in list responses for security.";
|
|
61
61
|
readonly readOnly: true;
|
|
@@ -66,7 +66,7 @@ export declare const apiKeyToolDefinitions: readonly [{
|
|
|
66
66
|
};
|
|
67
67
|
readonly handler: typeof apiKeyList;
|
|
68
68
|
}, {
|
|
69
|
-
readonly name: "
|
|
69
|
+
readonly name: "ol_apikey_delete";
|
|
70
70
|
readonly title: "Delete API Key (Permanent)";
|
|
71
71
|
readonly description: "Delete an API key. Returns void on success (204 No Content). The API key will be immediately invalidated.";
|
|
72
72
|
readonly readOnly: false;
|
package/dist/tools/apikey.js
CHANGED
|
@@ -28,7 +28,7 @@ export async function apiKeyCreate(input) {
|
|
|
28
28
|
return response;
|
|
29
29
|
}
|
|
30
30
|
catch (error) {
|
|
31
|
-
throw formatApiError(error, "
|
|
31
|
+
throw formatApiError(error, "ol_apikey_create");
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
export async function apiKeyList(input) {
|
|
@@ -44,7 +44,7 @@ export async function apiKeyList(input) {
|
|
|
44
44
|
return response;
|
|
45
45
|
}
|
|
46
46
|
catch (error) {
|
|
47
|
-
throw formatApiError(error, "
|
|
47
|
+
throw formatApiError(error, "ol_apikey_list");
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
export async function apiKeyDelete(input) {
|
|
@@ -52,13 +52,13 @@ export async function apiKeyDelete(input) {
|
|
|
52
52
|
await apiDelete(`/admin/${input.adminId}/api-key/${input.apiKeyId}`);
|
|
53
53
|
}
|
|
54
54
|
catch (error) {
|
|
55
|
-
throw formatApiError(error, "
|
|
55
|
+
throw formatApiError(error, "ol_apikey_delete");
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
// Tool definitions
|
|
59
59
|
export const apiKeyToolDefinitions = [
|
|
60
60
|
{
|
|
61
|
-
name: "
|
|
61
|
+
name: "ol_apikey_create",
|
|
62
62
|
title: "Create API Key",
|
|
63
63
|
description: "Create a new API key for an admin user. CRITICAL: The API token is ONLY returned at creation time. Store it securely immediately - it cannot be retrieved later. Returns apiKeyId, token, adminId, name, and expirationDate.",
|
|
64
64
|
readOnly: false,
|
|
@@ -66,7 +66,7 @@ export const apiKeyToolDefinitions = [
|
|
|
66
66
|
handler: apiKeyCreate,
|
|
67
67
|
},
|
|
68
68
|
{
|
|
69
|
-
name: "
|
|
69
|
+
name: "ol_apikey_list",
|
|
70
70
|
title: "List API Keys",
|
|
71
71
|
description: "List API keys for an admin user. Returns list of API keys with apiKeyId, adminId, name, and expirationDate. Note: tokens are not returned in list responses for security.",
|
|
72
72
|
readOnly: true,
|
|
@@ -74,7 +74,7 @@ export const apiKeyToolDefinitions = [
|
|
|
74
74
|
handler: apiKeyList,
|
|
75
75
|
},
|
|
76
76
|
{
|
|
77
|
-
name: "
|
|
77
|
+
name: "ol_apikey_delete",
|
|
78
78
|
title: "Delete API Key (Permanent)",
|
|
79
79
|
description: "Delete an API key. Returns void on success (204 No Content). The API key will be immediately invalidated.",
|
|
80
80
|
readOnly: false,
|
package/dist/tools/audit.d.ts
CHANGED
|
@@ -80,7 +80,7 @@ export declare function auditExport(input: {
|
|
|
80
80
|
exportId: string;
|
|
81
81
|
}>;
|
|
82
82
|
export declare const auditToolDefinitions: readonly [{
|
|
83
|
-
readonly name: "
|
|
83
|
+
readonly name: "ol_audit_list";
|
|
84
84
|
readonly title: "List Audit Logs";
|
|
85
85
|
readonly description: "List audit log entries with optional filtering. Returns paginated list of audit entries with auditLogId, eventType, entityType, entityId, username, timestamp, and details. Audit logs track all administrative actions. Use for compliance and troubleshooting.";
|
|
86
86
|
readonly readOnly: true;
|
|
@@ -97,7 +97,7 @@ export declare const auditToolDefinitions: readonly [{
|
|
|
97
97
|
};
|
|
98
98
|
readonly handler: typeof auditList;
|
|
99
99
|
}, {
|
|
100
|
-
readonly name: "
|
|
100
|
+
readonly name: "ol_audit_export";
|
|
101
101
|
readonly title: "Export Audit Logs";
|
|
102
102
|
readonly description: "Create an export of system logs. Returns exportId that can be used to track export status. The export will be processed asynchronously. Use date filters to scope the export range.";
|
|
103
103
|
readonly readOnly: false;
|
package/dist/tools/audit.js
CHANGED
|
@@ -47,7 +47,7 @@ export async function auditList(input) {
|
|
|
47
47
|
return response;
|
|
48
48
|
}
|
|
49
49
|
catch (error) {
|
|
50
|
-
throw formatApiError(error, "
|
|
50
|
+
throw formatApiError(error, "ol_audit_list");
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
export async function auditExport(input) {
|
|
@@ -70,13 +70,13 @@ export async function auditExport(input) {
|
|
|
70
70
|
return response;
|
|
71
71
|
}
|
|
72
72
|
catch (error) {
|
|
73
|
-
throw formatApiError(error, "
|
|
73
|
+
throw formatApiError(error, "ol_audit_export");
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
76
|
// Tool definitions
|
|
77
77
|
export const auditToolDefinitions = [
|
|
78
78
|
{
|
|
79
|
-
name: "
|
|
79
|
+
name: "ol_audit_list",
|
|
80
80
|
title: "List Audit Logs",
|
|
81
81
|
description: "List audit log entries with optional filtering. Returns paginated list of audit entries with auditLogId, eventType, entityType, entityId, username, timestamp, and details. Audit logs track all administrative actions. Use for compliance and troubleshooting.",
|
|
82
82
|
readOnly: true,
|
|
@@ -84,7 +84,7 @@ export const auditToolDefinitions = [
|
|
|
84
84
|
handler: auditList,
|
|
85
85
|
},
|
|
86
86
|
{
|
|
87
|
-
name: "
|
|
87
|
+
name: "ol_audit_export",
|
|
88
88
|
title: "Export Audit Logs",
|
|
89
89
|
description: "Create an export of system logs. Returns exportId that can be used to track export status. The export will be processed asynchronously. Use date filters to scope the export range.",
|
|
90
90
|
readOnly: false,
|
package/dist/tools/badge.d.ts
CHANGED
|
@@ -14,7 +14,7 @@ export declare const BadgeGetInputSchema: {
|
|
|
14
14
|
export declare const BadgeUpdateInputSchema: {
|
|
15
15
|
storeCode: z.ZodOptional<z.ZodString>;
|
|
16
16
|
badgeTypeId: z.ZodString;
|
|
17
|
-
name: z.
|
|
17
|
+
name: z.ZodString;
|
|
18
18
|
translations: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
19
19
|
name: z.ZodString;
|
|
20
20
|
description: z.ZodOptional<z.ZodString>;
|
|
@@ -80,7 +80,7 @@ export declare function badgeGetMemberBadges(input: {
|
|
|
80
80
|
};
|
|
81
81
|
}>;
|
|
82
82
|
export declare const badgeToolDefinitions: readonly [{
|
|
83
|
-
readonly name: "
|
|
83
|
+
readonly name: "ol_badge_list";
|
|
84
84
|
readonly title: "List Badges";
|
|
85
85
|
readonly description: "List badge types. Badges are visual rewards linked to achievements. When a member completes an achievement with a badgeTypeId, they earn that badge. Use for displaying available badges.";
|
|
86
86
|
readonly readOnly: true;
|
|
@@ -93,7 +93,7 @@ export declare const badgeToolDefinitions: readonly [{
|
|
|
93
93
|
};
|
|
94
94
|
readonly handler: typeof badgeList;
|
|
95
95
|
}, {
|
|
96
|
-
readonly name: "
|
|
96
|
+
readonly name: "ol_badge_get";
|
|
97
97
|
readonly title: "Get Badge Details";
|
|
98
98
|
readonly description: "Get badge type details including name, image URL, and linked achievements count.";
|
|
99
99
|
readonly readOnly: true;
|
|
@@ -103,14 +103,14 @@ export declare const badgeToolDefinitions: readonly [{
|
|
|
103
103
|
};
|
|
104
104
|
readonly handler: typeof badgeGet;
|
|
105
105
|
}, {
|
|
106
|
-
readonly name: "
|
|
106
|
+
readonly name: "ol_badge_update";
|
|
107
107
|
readonly title: "Update Badge";
|
|
108
108
|
readonly description: "Update badge type configuration. Badge types are created automatically when referenced by achievements. Use this to update name, image, or translations.";
|
|
109
109
|
readonly readOnly: false;
|
|
110
110
|
readonly inputSchema: {
|
|
111
111
|
storeCode: z.ZodOptional<z.ZodString>;
|
|
112
112
|
badgeTypeId: z.ZodString;
|
|
113
|
-
name: z.
|
|
113
|
+
name: z.ZodString;
|
|
114
114
|
translations: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
115
115
|
name: z.ZodString;
|
|
116
116
|
description: z.ZodOptional<z.ZodString>;
|
|
@@ -126,7 +126,7 @@ export declare const badgeToolDefinitions: readonly [{
|
|
|
126
126
|
};
|
|
127
127
|
readonly handler: typeof badgeUpdate;
|
|
128
128
|
}, {
|
|
129
|
-
readonly name: "
|
|
129
|
+
readonly name: "ol_badge_get_member_badges";
|
|
130
130
|
readonly title: "Get Member Badges";
|
|
131
131
|
readonly description: "Get badges earned by a member. Returns each badge with completedCount showing how many times it was earned. Use for displaying member's badge collection.";
|
|
132
132
|
readonly readOnly: true;
|
package/dist/tools/badge.js
CHANGED
|
@@ -4,29 +4,29 @@ import { formatApiError } from "../utils/errors.js";
|
|
|
4
4
|
import { getStoreCode } from "../config.js";
|
|
5
5
|
// Input Schemas
|
|
6
6
|
export const BadgeListInputSchema = {
|
|
7
|
-
storeCode: z.string().optional().describe("Store code.
|
|
7
|
+
storeCode: z.string().optional().describe("Store code for multi-tenant routing. DO NOT pass this parameter - the configured default will be used automatically. Only provide a value if the user explicitly asks to work with a different store."),
|
|
8
8
|
page: z.number().optional().describe("Page number (default: 1)."),
|
|
9
9
|
perPage: z.number().optional().describe("Items per page (default: 10)."),
|
|
10
10
|
name: z.string().optional().describe("Filter by badge name."),
|
|
11
11
|
badgeTypeId: z.string().optional().describe("Filter by specific badge type ID."),
|
|
12
12
|
};
|
|
13
13
|
export const BadgeGetInputSchema = {
|
|
14
|
-
storeCode: z.string().optional().describe("Store code.
|
|
14
|
+
storeCode: z.string().optional().describe("Store code for multi-tenant routing. DO NOT pass this parameter - the configured default will be used automatically. Only provide a value if the user explicitly asks to work with a different store."),
|
|
15
15
|
badgeTypeId: z.string().describe("The badge type ID (UUID) to retrieve."),
|
|
16
16
|
};
|
|
17
17
|
export const BadgeUpdateInputSchema = {
|
|
18
|
-
storeCode: z.string().optional().describe("Store code.
|
|
18
|
+
storeCode: z.string().optional().describe("Store code for multi-tenant routing. DO NOT pass this parameter - the configured default will be used automatically. Only provide a value if the user explicitly asks to work with a different store."),
|
|
19
19
|
badgeTypeId: z.string().describe("The badge type ID (UUID) to update."),
|
|
20
|
-
name: z.string().
|
|
20
|
+
name: z.string().describe("Badge name (REQUIRED). API requires name as a direct field."),
|
|
21
21
|
translations: z.record(z.string(), z.object({
|
|
22
22
|
name: z.string(),
|
|
23
23
|
description: z.string().optional(),
|
|
24
|
-
})).optional().describe("Badge translations."),
|
|
24
|
+
})).optional().describe("Badge translations (for convenience - will extract name from translations.en.name if name not provided directly)."),
|
|
25
25
|
imageUrl: z.string().optional().describe("URL to badge image."),
|
|
26
26
|
active: z.boolean().optional().describe("Whether badge type is active."),
|
|
27
27
|
};
|
|
28
28
|
export const BadgeGetMemberBadgesInputSchema = {
|
|
29
|
-
storeCode: z.string().optional().describe("Store code.
|
|
29
|
+
storeCode: z.string().optional().describe("Store code for multi-tenant routing. DO NOT pass this parameter - the configured default will be used automatically. Only provide a value if the user explicitly asks to work with a different store."),
|
|
30
30
|
memberId: z.string().describe("The member ID (UUID)."),
|
|
31
31
|
page: z.number().optional().describe("Page number (default: 1)."),
|
|
32
32
|
perPage: z.number().optional().describe("Items per page (default: 10)."),
|
|
@@ -65,7 +65,7 @@ export async function badgeList(input) {
|
|
|
65
65
|
};
|
|
66
66
|
}
|
|
67
67
|
catch (error) {
|
|
68
|
-
throw formatApiError(error, "
|
|
68
|
+
throw formatApiError(error, "ol_badge_list");
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
export async function badgeGet(input) {
|
|
@@ -75,16 +75,21 @@ export async function badgeGet(input) {
|
|
|
75
75
|
return response;
|
|
76
76
|
}
|
|
77
77
|
catch (error) {
|
|
78
|
-
throw formatApiError(error, "
|
|
78
|
+
throw formatApiError(error, "ol_badge_get");
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
81
|
export async function badgeUpdate(input) {
|
|
82
82
|
const storeCode = getStoreCode(input.storeCode);
|
|
83
83
|
const badgePayload = {};
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
84
|
+
// API requires name as direct field, not nested in translations
|
|
85
|
+
// Extract from translations.en.name if name not provided directly
|
|
86
|
+
let badgeName = input.name;
|
|
87
|
+
if (!badgeName && input.translations?.en?.name) {
|
|
88
|
+
badgeName = input.translations.en.name;
|
|
89
|
+
}
|
|
90
|
+
if (badgeName !== undefined)
|
|
91
|
+
badgePayload.name = badgeName;
|
|
92
|
+
// Note: API does not accept nested translations - only direct fields
|
|
88
93
|
if (input.imageUrl !== undefined)
|
|
89
94
|
badgePayload.imageUrl = input.imageUrl;
|
|
90
95
|
if (input.active !== undefined)
|
|
@@ -94,7 +99,7 @@ export async function badgeUpdate(input) {
|
|
|
94
99
|
await apiPut(`/${storeCode}/badge-type/${input.badgeTypeId}`, { badgeType: badgePayload });
|
|
95
100
|
}
|
|
96
101
|
catch (error) {
|
|
97
|
-
throw formatApiError(error, "
|
|
102
|
+
throw formatApiError(error, "ol_badge_update");
|
|
98
103
|
}
|
|
99
104
|
}
|
|
100
105
|
export async function badgeGetMemberBadges(input) {
|
|
@@ -129,13 +134,13 @@ export async function badgeGetMemberBadges(input) {
|
|
|
129
134
|
};
|
|
130
135
|
}
|
|
131
136
|
catch (error) {
|
|
132
|
-
throw formatApiError(error, "
|
|
137
|
+
throw formatApiError(error, "ol_badge_get_member_badges");
|
|
133
138
|
}
|
|
134
139
|
}
|
|
135
140
|
// Tool definitions
|
|
136
141
|
export const badgeToolDefinitions = [
|
|
137
142
|
{
|
|
138
|
-
name: "
|
|
143
|
+
name: "ol_badge_list",
|
|
139
144
|
title: "List Badges",
|
|
140
145
|
description: "List badge types. Badges are visual rewards linked to achievements. When a member completes an achievement with a badgeTypeId, they earn that badge. Use for displaying available badges.",
|
|
141
146
|
readOnly: true,
|
|
@@ -143,7 +148,7 @@ export const badgeToolDefinitions = [
|
|
|
143
148
|
handler: badgeList,
|
|
144
149
|
},
|
|
145
150
|
{
|
|
146
|
-
name: "
|
|
151
|
+
name: "ol_badge_get",
|
|
147
152
|
title: "Get Badge Details",
|
|
148
153
|
description: "Get badge type details including name, image URL, and linked achievements count.",
|
|
149
154
|
readOnly: true,
|
|
@@ -151,7 +156,7 @@ export const badgeToolDefinitions = [
|
|
|
151
156
|
handler: badgeGet,
|
|
152
157
|
},
|
|
153
158
|
{
|
|
154
|
-
name: "
|
|
159
|
+
name: "ol_badge_update",
|
|
155
160
|
title: "Update Badge",
|
|
156
161
|
description: "Update badge type configuration. Badge types are created automatically when referenced by achievements. Use this to update name, image, or translations.",
|
|
157
162
|
readOnly: false,
|
|
@@ -159,7 +164,7 @@ export const badgeToolDefinitions = [
|
|
|
159
164
|
handler: badgeUpdate,
|
|
160
165
|
},
|
|
161
166
|
{
|
|
162
|
-
name: "
|
|
167
|
+
name: "ol_badge_get_member_badges",
|
|
163
168
|
title: "Get Member Badges",
|
|
164
169
|
description: "Get badges earned by a member. Returns each badge with completedCount showing how many times it was earned. Use for displaying member's badge collection.",
|
|
165
170
|
readOnly: true,
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { CampaignListItem } from "../../types/schemas/campaign.js";
|
|
2
|
+
import { SimulatedEffect, CampaignSimulateInput, CampaignCreateInput } from "./types.js";
|
|
3
|
+
export declare function campaignList(input: {
|
|
4
|
+
storeCode?: string;
|
|
5
|
+
page?: number;
|
|
6
|
+
perPage?: number;
|
|
7
|
+
active?: boolean;
|
|
8
|
+
type?: string;
|
|
9
|
+
trigger?: string;
|
|
10
|
+
}): Promise<{
|
|
11
|
+
campaigns: CampaignListItem[];
|
|
12
|
+
total: {
|
|
13
|
+
all?: number;
|
|
14
|
+
filtered?: number;
|
|
15
|
+
};
|
|
16
|
+
}>;
|
|
17
|
+
export declare function campaignGet(input: {
|
|
18
|
+
storeCode?: string;
|
|
19
|
+
campaignId: string;
|
|
20
|
+
}): Promise<Record<string, unknown>>;
|
|
21
|
+
export declare function campaignCreate(input: CampaignCreateInput): Promise<{
|
|
22
|
+
campaignId: string;
|
|
23
|
+
}>;
|
|
24
|
+
export declare function campaignUpdate(input: Record<string, unknown>): Promise<void>;
|
|
25
|
+
export declare function campaignPatch(input: {
|
|
26
|
+
storeCode?: string;
|
|
27
|
+
campaignId: string;
|
|
28
|
+
active?: boolean;
|
|
29
|
+
displayOrder?: number;
|
|
30
|
+
}): Promise<void>;
|
|
31
|
+
export declare function campaignDelete(input: {
|
|
32
|
+
storeCode?: string;
|
|
33
|
+
campaignId: string;
|
|
34
|
+
}): Promise<void>;
|
|
35
|
+
export declare function campaignSimulate(input: CampaignSimulateInput): Promise<{
|
|
36
|
+
simulatedEffects: SimulatedEffect[];
|
|
37
|
+
evaluationWarnings?: Array<{
|
|
38
|
+
campaignId: string;
|
|
39
|
+
message: string;
|
|
40
|
+
}>;
|
|
41
|
+
simulatedMember?: Record<string, unknown>;
|
|
42
|
+
}>;
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import { apiGet, apiPost, apiPut, apiPatch, apiDelete } from "../../client/http.js";
|
|
2
|
+
import { formatApiError } from "../../utils/errors.js";
|
|
3
|
+
import { getStoreCode } from "../../config.js";
|
|
4
|
+
// Core CRUD handlers
|
|
5
|
+
export async function campaignList(input) {
|
|
6
|
+
const storeCode = getStoreCode(input.storeCode);
|
|
7
|
+
const params = new URLSearchParams();
|
|
8
|
+
if (input.page)
|
|
9
|
+
params.append("_page", String(input.page));
|
|
10
|
+
if (input.perPage)
|
|
11
|
+
params.append("_itemsOnPage", String(input.perPage));
|
|
12
|
+
if (input.active !== undefined)
|
|
13
|
+
params.append("active", String(input.active));
|
|
14
|
+
if (input.type)
|
|
15
|
+
params.append("type", input.type);
|
|
16
|
+
if (input.trigger)
|
|
17
|
+
params.append("trigger", input.trigger);
|
|
18
|
+
const queryString = params.toString();
|
|
19
|
+
const url = `/${storeCode}/campaign${queryString ? `?${queryString}` : ""}`;
|
|
20
|
+
try {
|
|
21
|
+
const response = await apiGet(url);
|
|
22
|
+
const campaigns = (response.items || []).map((item) => {
|
|
23
|
+
const campaign = item;
|
|
24
|
+
const translations = campaign.translations;
|
|
25
|
+
let name = "";
|
|
26
|
+
if (Array.isArray(translations)) {
|
|
27
|
+
const enTranslation = translations.find((t) => t.locale === "en" || t.locale?.startsWith("en"));
|
|
28
|
+
name = enTranslation?.name || translations[0]?.name || campaign.name || "";
|
|
29
|
+
}
|
|
30
|
+
else if (translations && typeof translations === "object") {
|
|
31
|
+
name = translations.en?.name || campaign.name || "";
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
name = campaign.name || "";
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
campaignId: campaign.campaignId,
|
|
38
|
+
name,
|
|
39
|
+
type: campaign.type,
|
|
40
|
+
trigger: campaign.trigger,
|
|
41
|
+
active: (campaign.active ?? false),
|
|
42
|
+
displayOrder: campaign.displayOrder,
|
|
43
|
+
};
|
|
44
|
+
});
|
|
45
|
+
const total = response.total || {};
|
|
46
|
+
return {
|
|
47
|
+
campaigns,
|
|
48
|
+
total: {
|
|
49
|
+
all: typeof total.all === "number" ? total.all : undefined,
|
|
50
|
+
filtered: typeof total.filtered === "number" ? total.filtered : undefined,
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
throw formatApiError(error, "ol_campaign_list");
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
export async function campaignGet(input) {
|
|
59
|
+
const storeCode = getStoreCode(input.storeCode);
|
|
60
|
+
try {
|
|
61
|
+
const response = await apiGet(`/${storeCode}/campaign/${input.campaignId}`);
|
|
62
|
+
return response;
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
throw formatApiError(error, "ol_campaign_get");
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
export async function campaignCreate(input) {
|
|
69
|
+
const storeCode = getStoreCode(input.storeCode);
|
|
70
|
+
const campaignPayload = {
|
|
71
|
+
type: input.type,
|
|
72
|
+
trigger: input.trigger,
|
|
73
|
+
translations: input.translations,
|
|
74
|
+
activity: input.activity,
|
|
75
|
+
rules: input.rules,
|
|
76
|
+
};
|
|
77
|
+
if (input.visibility)
|
|
78
|
+
campaignPayload.visibility = input.visibility;
|
|
79
|
+
if (input.audience)
|
|
80
|
+
campaignPayload.audience = input.audience;
|
|
81
|
+
if (input.limits)
|
|
82
|
+
campaignPayload.limits = input.limits;
|
|
83
|
+
if (input.active !== undefined)
|
|
84
|
+
campaignPayload.active = input.active;
|
|
85
|
+
if (input.displayOrder !== undefined)
|
|
86
|
+
campaignPayload.displayOrder = input.displayOrder;
|
|
87
|
+
if (input.labels)
|
|
88
|
+
campaignPayload.labels = input.labels;
|
|
89
|
+
if (input.event)
|
|
90
|
+
campaignPayload.event = input.event;
|
|
91
|
+
if (input.achievementId)
|
|
92
|
+
campaignPayload.achievementId = input.achievementId;
|
|
93
|
+
try {
|
|
94
|
+
const response = await apiPost(`/${storeCode}/campaign`, { campaign: campaignPayload });
|
|
95
|
+
return { campaignId: response.campaignId };
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
throw formatApiError(error, "ol_campaign_create");
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
export async function campaignUpdate(input) {
|
|
102
|
+
const storeCode = getStoreCode(input.storeCode);
|
|
103
|
+
const campaignId = input.campaignId;
|
|
104
|
+
const { storeCode: _sc, campaignId: _cid, ...campaignPayload } = input;
|
|
105
|
+
try {
|
|
106
|
+
await apiPut(`/${storeCode}/campaign/${campaignId}`, { campaign: campaignPayload });
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
throw formatApiError(error, "ol_campaign_update");
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
export async function campaignPatch(input) {
|
|
113
|
+
const storeCode = getStoreCode(input.storeCode);
|
|
114
|
+
const patchPayload = {};
|
|
115
|
+
if (input.active !== undefined)
|
|
116
|
+
patchPayload.active = input.active;
|
|
117
|
+
if (input.displayOrder !== undefined)
|
|
118
|
+
patchPayload.displayOrder = input.displayOrder;
|
|
119
|
+
try {
|
|
120
|
+
await apiPatch(`/${storeCode}/campaign/${input.campaignId}`, { campaign: patchPayload });
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
throw formatApiError(error, "ol_campaign_patch");
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
export async function campaignDelete(input) {
|
|
127
|
+
const storeCode = getStoreCode(input.storeCode);
|
|
128
|
+
try {
|
|
129
|
+
await apiDelete(`/${storeCode}/campaign/${input.campaignId}`);
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
throw formatApiError(error, "ol_campaign_delete");
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
// Simulation handler
|
|
136
|
+
export async function campaignSimulate(input) {
|
|
137
|
+
const storeCode = getStoreCode(input.storeCode);
|
|
138
|
+
const simulatePayload = {
|
|
139
|
+
trigger: input.trigger,
|
|
140
|
+
customer: {},
|
|
141
|
+
};
|
|
142
|
+
const customer = {};
|
|
143
|
+
if (input.customer.customerId)
|
|
144
|
+
customer.id = input.customer.customerId;
|
|
145
|
+
if (input.customer.id)
|
|
146
|
+
customer.id = input.customer.id;
|
|
147
|
+
if (input.customer.email)
|
|
148
|
+
customer.email = input.customer.email;
|
|
149
|
+
if (input.customer.loyaltyCardNumber)
|
|
150
|
+
customer.loyaltyCardNumber = input.customer.loyaltyCardNumber;
|
|
151
|
+
if (input.customer.phone)
|
|
152
|
+
customer.phone = input.customer.phone;
|
|
153
|
+
if (input.customer.firstName)
|
|
154
|
+
customer.firstName = input.customer.firstName;
|
|
155
|
+
if (input.customer.lastName)
|
|
156
|
+
customer.lastName = input.customer.lastName;
|
|
157
|
+
simulatePayload.customer = customer;
|
|
158
|
+
if (input.transaction) {
|
|
159
|
+
const transaction = {};
|
|
160
|
+
if (input.transaction.grossValue !== undefined)
|
|
161
|
+
transaction.grossValue = input.transaction.grossValue;
|
|
162
|
+
if (input.transaction.documentNumber)
|
|
163
|
+
transaction.documentNumber = input.transaction.documentNumber;
|
|
164
|
+
if (input.transaction.purchasedAt)
|
|
165
|
+
transaction.purchasedAt = input.transaction.purchasedAt;
|
|
166
|
+
if (input.transaction.documentType)
|
|
167
|
+
transaction.documentType = input.transaction.documentType;
|
|
168
|
+
if (input.transaction.purchasePlace)
|
|
169
|
+
transaction.purchasePlace = input.transaction.purchasePlace;
|
|
170
|
+
if (input.transaction.items)
|
|
171
|
+
transaction.items = input.transaction.items;
|
|
172
|
+
if (input.transaction.labels)
|
|
173
|
+
transaction.labels = input.transaction.labels;
|
|
174
|
+
simulatePayload.transaction = transaction;
|
|
175
|
+
}
|
|
176
|
+
if (input.customEvent) {
|
|
177
|
+
simulatePayload.event = input.customEvent.eventCode;
|
|
178
|
+
if (input.customEvent.attributes) {
|
|
179
|
+
simulatePayload.eventAttributes = input.customEvent.attributes;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
if (input.referrer) {
|
|
183
|
+
const referrer = {};
|
|
184
|
+
if (input.referrer.id)
|
|
185
|
+
referrer.id = input.referrer.id;
|
|
186
|
+
if (input.referrer.email)
|
|
187
|
+
referrer.email = input.referrer.email;
|
|
188
|
+
if (input.referrer.loyaltyCardNumber)
|
|
189
|
+
referrer.loyaltyCardNumber = input.referrer.loyaltyCardNumber;
|
|
190
|
+
simulatePayload.referrer = referrer;
|
|
191
|
+
}
|
|
192
|
+
try {
|
|
193
|
+
const response = await apiPost(`/${storeCode}/campaign/simulate`, { simulate: simulatePayload });
|
|
194
|
+
const effectsByCampaign = new Map();
|
|
195
|
+
for (const effect of response.effects || []) {
|
|
196
|
+
const campaignId = effect.campaign?.campaignId || "unknown";
|
|
197
|
+
const campaignName = effect.campaign?.name || undefined;
|
|
198
|
+
if (!effectsByCampaign.has(campaignId)) {
|
|
199
|
+
effectsByCampaign.set(campaignId, {
|
|
200
|
+
campaignId,
|
|
201
|
+
campaignName,
|
|
202
|
+
effects: [],
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
const campaignEffect = effectsByCampaign.get(campaignId);
|
|
206
|
+
campaignEffect.effects.push({
|
|
207
|
+
type: effect.type,
|
|
208
|
+
target: effect.target,
|
|
209
|
+
points: effect.points,
|
|
210
|
+
wallet: effect.wallet,
|
|
211
|
+
rewardId: effect.rewardId,
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
return {
|
|
215
|
+
simulatedEffects: Array.from(effectsByCampaign.values()),
|
|
216
|
+
evaluationWarnings: response.evaluationWarnings,
|
|
217
|
+
simulatedMember: response.simulatedMember,
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
catch (error) {
|
|
221
|
+
throw formatApiError(error, "ol_campaign_simulate");
|
|
222
|
+
}
|
|
223
|
+
}
|