@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.
- package/dist/config.d.ts +4 -3
- package/dist/config.js +9 -7
- package/dist/instructions.d.ts +1 -1
- package/dist/instructions.js +26 -8
- package/dist/tools/achievement/handlers.js +60 -1
- package/dist/tools/achievement/index.d.ts +8 -8
- package/dist/tools/achievement/index.js +10 -11
- package/dist/tools/achievement/schemas.d.ts +8 -8
- package/dist/tools/achievement/schemas.js +36 -32
- package/dist/tools/analytics.js +9 -9
- package/dist/tools/badge.js +4 -4
- package/dist/tools/campaign/handlers.js +35 -1
- package/dist/tools/campaign/index.d.ts +97 -34
- package/dist/tools/campaign/index.js +14 -12
- package/dist/tools/campaign/schemas.d.ts +96 -33
- package/dist/tools/campaign/schemas.js +89 -55
- package/dist/tools/custom-event.js +10 -9
- package/dist/tools/export.js +4 -4
- package/dist/tools/import.d.ts +1 -1
- package/dist/tools/import.js +11 -6
- package/dist/tools/index.js +4 -4
- package/dist/tools/member/handlers.js +48 -1
- package/dist/tools/member/index.d.ts +1 -1
- package/dist/tools/member/index.js +3 -1
- package/dist/tools/member/schemas.js +12 -12
- package/dist/tools/points/handlers.d.ts +75 -0
- package/dist/tools/{points.js → points/handlers.js} +21 -112
- package/dist/tools/points/index.d.ts +84 -0
- package/dist/tools/points/index.js +63 -0
- package/dist/tools/points/schemas.d.ts +45 -0
- package/dist/tools/points/schemas.js +47 -0
- package/dist/tools/referral/schemas.js +3 -3
- package/dist/tools/reward/handlers.d.ts +2 -0
- package/dist/tools/reward/handlers.js +79 -6
- package/dist/tools/reward/index.d.ts +2 -0
- package/dist/tools/reward/index.js +10 -10
- package/dist/tools/reward/schemas.d.ts +2 -0
- package/dist/tools/reward/schemas.js +42 -23
- package/dist/tools/segment/index.js +7 -5
- package/dist/tools/segment/schemas.js +11 -11
- package/dist/tools/tierset/handlers.d.ts +26 -0
- package/dist/tools/tierset/handlers.js +196 -0
- package/dist/tools/tierset/index.d.ts +124 -0
- package/dist/tools/tierset/index.js +88 -0
- package/dist/tools/tierset/schemas.d.ts +127 -0
- package/dist/tools/tierset/schemas.js +62 -0
- package/dist/tools/transaction/handlers.d.ts +89 -0
- package/dist/tools/transaction/handlers.js +159 -0
- package/dist/tools/transaction/index.d.ts +153 -0
- package/dist/tools/transaction/index.js +54 -0
- package/dist/tools/transaction/schemas.d.ts +126 -0
- package/dist/tools/transaction/schemas.js +60 -0
- package/dist/tools/wallet-type/handlers.d.ts +63 -0
- package/dist/tools/{wallet-type.js → wallet-type/handlers.js} +15 -78
- package/dist/tools/{wallet-type.d.ts → wallet-type/index.d.ts} +3 -64
- package/dist/tools/wallet-type/index.js +65 -0
- package/dist/tools/wallet-type/schemas.d.ts +1 -0
- package/dist/tools/wallet-type/schemas.js +1 -0
- package/dist/tools/webhook.js +6 -6
- package/dist/types/schemas/achievement.d.ts +48 -48
- package/dist/types/schemas/admin.d.ts +10 -10
- package/dist/types/schemas/campaign.d.ts +12 -12
- package/dist/types/schemas/common.js +1 -1
- package/dist/types/schemas/member.d.ts +18 -18
- package/dist/types/schemas/role.d.ts +4 -4
- package/dist/types/schemas/tierset.js +2 -1
- package/dist/types/schemas/transaction.d.ts +12 -12
- package/dist/types/schemas/wallet-type.js +12 -10
- package/dist/types/schemas/webhook.d.ts +6 -6
- package/dist/utils/errors.js +40 -0
- package/package.json +3 -2
- package/dist/prompts/fan-engagement-setup.d.ts +0 -107
- package/dist/prompts/fan-engagement-setup.js +0 -492
- package/dist/tools/achievement.d.ts +0 -1017
- package/dist/tools/achievement.js +0 -354
- package/dist/tools/campaign.d.ts +0 -1800
- package/dist/tools/campaign.js +0 -737
- package/dist/tools/member.d.ts +0 -366
- package/dist/tools/member.js +0 -352
- package/dist/tools/points.d.ts +0 -201
- package/dist/tools/reward.d.ts +0 -279
- package/dist/tools/reward.js +0 -361
- package/dist/tools/segment.d.ts +0 -816
- package/dist/tools/segment.js +0 -333
- package/dist/tools/tierset.d.ts +0 -273
- package/dist/tools/tierset.js +0 -289
- package/dist/tools/transaction.d.ts +0 -365
- package/dist/tools/transaction.js +0 -259
- package/dist/workflows/app-login-streak.d.ts +0 -39
- package/dist/workflows/app-login-streak.js +0 -298
- package/dist/workflows/early-arrival.d.ts +0 -33
- package/dist/workflows/early-arrival.js +0 -148
- package/dist/workflows/index.d.ts +0 -101
- package/dist/workflows/index.js +0 -208
- package/dist/workflows/match-attendance.d.ts +0 -45
- package/dist/workflows/match-attendance.js +0 -308
- package/dist/workflows/sportsbar-visit.d.ts +0 -41
- package/dist/workflows/sportsbar-visit.js +0 -284
- package/dist/workflows/vod-watching.d.ts +0 -43
- package/dist/workflows/vod-watching.js +0 -326
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// Re-export schemas
|
|
2
|
+
export { PointsAddInputSchema, PointsSpendInputSchema, PointsTransferInputSchema, PointsBalanceInputSchema, PointsHistoryInputSchema, PointsHistogramInputSchema, } from "./schemas.js";
|
|
3
|
+
// Re-export handlers
|
|
4
|
+
export { pointsAdd, pointsSpend, pointsTransfer, pointsGetBalance, pointsGetHistory, pointsGetHistogram, } from "./handlers.js";
|
|
5
|
+
// Imports for tool definitions
|
|
6
|
+
import { PointsAddInputSchema, PointsSpendInputSchema, PointsTransferInputSchema, PointsBalanceInputSchema, PointsHistoryInputSchema, PointsHistogramInputSchema, } from "./schemas.js";
|
|
7
|
+
import { pointsAdd, pointsSpend, pointsTransfer, pointsGetBalance, pointsGetHistory, pointsGetHistogram, } from "./handlers.js";
|
|
8
|
+
// Tool definitions
|
|
9
|
+
export const pointsToolDefinitions = [
|
|
10
|
+
{
|
|
11
|
+
name: "ol_points_add",
|
|
12
|
+
title: "Add Points to Member",
|
|
13
|
+
description: "Add points to a member's wallet manually. " +
|
|
14
|
+
"BUSINESS IMPACT: Manual point additions bypass campaign rules and limits -- there is no automated undo. " +
|
|
15
|
+
"Confirm amount and reason with user before proceeding. " +
|
|
16
|
+
"Use for welcome bonuses, goodwill adjustments, or compensation. Returns transferId.",
|
|
17
|
+
readOnly: false,
|
|
18
|
+
inputSchema: PointsAddInputSchema,
|
|
19
|
+
handler: pointsAdd,
|
|
20
|
+
}, {
|
|
21
|
+
name: "ol_points_spend",
|
|
22
|
+
title: "Spend Member Points",
|
|
23
|
+
description: "Deduct points from member wallet. Fails if insufficient balance. " +
|
|
24
|
+
"WORKFLOW: Use ol_points_get_balance first to verify available (activeUnits) points before spending. " +
|
|
25
|
+
"Returns transferId.",
|
|
26
|
+
readOnly: false,
|
|
27
|
+
inputSchema: PointsSpendInputSchema,
|
|
28
|
+
handler: pointsSpend,
|
|
29
|
+
}, {
|
|
30
|
+
name: "ol_points_transfer",
|
|
31
|
+
title: "Transfer Points Between Members",
|
|
32
|
+
description: "Transfer points from one member to another (P2P transfer). " +
|
|
33
|
+
"Sender must have sufficient balance. Returns transferId.",
|
|
34
|
+
readOnly: false,
|
|
35
|
+
inputSchema: PointsTransferInputSchema,
|
|
36
|
+
handler: pointsTransfer,
|
|
37
|
+
}, {
|
|
38
|
+
name: "ol_points_get_balance",
|
|
39
|
+
title: "Check Points Balance",
|
|
40
|
+
description: "Get member points balance breakdown. activeUnits is available for spending. " +
|
|
41
|
+
"earnedUnits shows lifetime earnings, lockedUnits shows pending points.",
|
|
42
|
+
readOnly: true,
|
|
43
|
+
inputSchema: PointsBalanceInputSchema,
|
|
44
|
+
handler: pointsGetBalance,
|
|
45
|
+
}, {
|
|
46
|
+
name: "ol_points_get_history",
|
|
47
|
+
title: "View Points History",
|
|
48
|
+
description: "Get points transaction history for a member. Filter by type: adding, spending, " +
|
|
49
|
+
"p2p_spending, p2p_adding, blocked, expired. Returns paginated list of transfers. " +
|
|
50
|
+
"Supports cursor pagination: provide 'cursor' from previous response to get next page.",
|
|
51
|
+
readOnly: true,
|
|
52
|
+
inputSchema: PointsHistoryInputSchema,
|
|
53
|
+
handler: pointsGetHistory,
|
|
54
|
+
}, {
|
|
55
|
+
name: "ol_points_get_histogram",
|
|
56
|
+
title: "View Points Trends",
|
|
57
|
+
description: "Get points histogram data for visualization. Shows earning and spending patterns over time. " +
|
|
58
|
+
"Use interval (day/week/month) to aggregate data and dateFrom/dateTo to filter range.",
|
|
59
|
+
readOnly: true,
|
|
60
|
+
inputSchema: PointsHistogramInputSchema,
|
|
61
|
+
handler: pointsGetHistogram,
|
|
62
|
+
},
|
|
63
|
+
];
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const PointsAddInputSchema: {
|
|
3
|
+
storeCode: z.ZodOptional<z.ZodString>;
|
|
4
|
+
memberId: z.ZodString;
|
|
5
|
+
points: z.ZodNumber;
|
|
6
|
+
walletCode: z.ZodOptional<z.ZodString>;
|
|
7
|
+
comment: z.ZodOptional<z.ZodString>;
|
|
8
|
+
expiresInDays: z.ZodOptional<z.ZodNumber>;
|
|
9
|
+
lockedUntilDays: z.ZodOptional<z.ZodNumber>;
|
|
10
|
+
};
|
|
11
|
+
export declare const PointsSpendInputSchema: {
|
|
12
|
+
storeCode: z.ZodOptional<z.ZodString>;
|
|
13
|
+
memberId: z.ZodString;
|
|
14
|
+
points: z.ZodNumber;
|
|
15
|
+
walletCode: z.ZodOptional<z.ZodString>;
|
|
16
|
+
comment: z.ZodOptional<z.ZodString>;
|
|
17
|
+
};
|
|
18
|
+
export declare const PointsTransferInputSchema: {
|
|
19
|
+
storeCode: z.ZodOptional<z.ZodString>;
|
|
20
|
+
senderId: z.ZodString;
|
|
21
|
+
receiverId: z.ZodString;
|
|
22
|
+
points: z.ZodNumber;
|
|
23
|
+
};
|
|
24
|
+
export declare const PointsBalanceInputSchema: {
|
|
25
|
+
storeCode: z.ZodOptional<z.ZodString>;
|
|
26
|
+
memberId: z.ZodString;
|
|
27
|
+
walletCode: z.ZodOptional<z.ZodString>;
|
|
28
|
+
};
|
|
29
|
+
export declare const PointsHistoryInputSchema: {
|
|
30
|
+
storeCode: z.ZodOptional<z.ZodString>;
|
|
31
|
+
memberId: z.ZodString;
|
|
32
|
+
cursor: z.ZodOptional<z.ZodString>;
|
|
33
|
+
page: z.ZodOptional<z.ZodNumber>;
|
|
34
|
+
perPage: z.ZodOptional<z.ZodNumber>;
|
|
35
|
+
type: z.ZodOptional<z.ZodEnum<["adding", "spending", "p2p_spending", "p2p_adding", "blocked", "expired"]>>;
|
|
36
|
+
};
|
|
37
|
+
export declare const PointsHistogramInputSchema: {
|
|
38
|
+
storeCode: z.ZodOptional<z.ZodString>;
|
|
39
|
+
memberId: z.ZodString;
|
|
40
|
+
pointType: z.ZodEnum<["spent", "earned", "expired", "pending"]>;
|
|
41
|
+
walletCode: z.ZodOptional<z.ZodString>;
|
|
42
|
+
interval: z.ZodOptional<z.ZodEnum<["day", "week", "month"]>>;
|
|
43
|
+
dateFrom: z.ZodOptional<z.ZodString>;
|
|
44
|
+
dateTo: z.ZodOptional<z.ZodString>;
|
|
45
|
+
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const PointsAddInputSchema = {
|
|
3
|
+
storeCode: z.string().optional().describe("INTERNAL: Auto-configured from server settings. NEVER ask the user for this value. Only set if the user explicitly requests a different store."),
|
|
4
|
+
memberId: z.string().describe("The member ID (UUID) to add points to."),
|
|
5
|
+
points: z.number().describe("Number of points to add (positive number). " +
|
|
6
|
+
"BUSINESS IMPACT: Manual point additions bypass campaign rules and limits. Confirm amount and reason with user."),
|
|
7
|
+
walletCode: z.string().optional().describe("Wallet type code (e.g., 'default'). Uses default wallet if not specified."),
|
|
8
|
+
comment: z.string().optional().describe("Reason for adding points (max 500 chars)."),
|
|
9
|
+
expiresInDays: z.number().optional().describe("Days until these specific points expire (1-9999). " +
|
|
10
|
+
"BUSINESS DECISION: Custom expiry for these points. Omit to use wallet default expiry."),
|
|
11
|
+
lockedUntilDays: z.number().optional().describe("Days until points become available (1-9999)."),
|
|
12
|
+
};
|
|
13
|
+
export const PointsSpendInputSchema = {
|
|
14
|
+
storeCode: z.string().optional().describe("INTERNAL: Auto-configured from server settings. NEVER ask the user for this value. Only set if the user explicitly requests a different store."),
|
|
15
|
+
memberId: z.string().describe("The member ID (UUID) to spend points from."),
|
|
16
|
+
points: z.number().describe("Number of points to spend (positive number)."),
|
|
17
|
+
walletCode: z.string().optional().describe("Wallet type code (e.g., 'default'). Uses default wallet if not specified."),
|
|
18
|
+
comment: z.string().optional().describe("Reason for spending points (max 500 chars)."),
|
|
19
|
+
};
|
|
20
|
+
export const PointsTransferInputSchema = {
|
|
21
|
+
storeCode: z.string().optional().describe("INTERNAL: Auto-configured from server settings. NEVER ask the user for this value. Only set if the user explicitly requests a different store."),
|
|
22
|
+
senderId: z.string().describe("The sender member ID (UUID)."),
|
|
23
|
+
receiverId: z.string().describe("The receiver member ID (UUID)."),
|
|
24
|
+
points: z.number().describe("Number of points to transfer."),
|
|
25
|
+
};
|
|
26
|
+
export const PointsBalanceInputSchema = {
|
|
27
|
+
storeCode: z.string().optional().describe("INTERNAL: Auto-configured from server settings. NEVER ask the user for this value. Only set if the user explicitly requests a different store."),
|
|
28
|
+
memberId: z.string().describe("The member ID (UUID) to get balance for."),
|
|
29
|
+
walletCode: z.string().optional().describe("Wallet type code. Returns all wallets if not specified."),
|
|
30
|
+
};
|
|
31
|
+
export const PointsHistoryInputSchema = {
|
|
32
|
+
storeCode: z.string().optional().describe("INTERNAL: Auto-configured from server settings. NEVER ask the user for this value. Only set if the user explicitly requests a different store."),
|
|
33
|
+
memberId: z.string().describe("The member ID (UUID) to get history for."),
|
|
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
|
+
type: z.enum(["adding", "spending", "p2p_spending", "p2p_adding", "blocked", "expired"]).optional().describe("Filter by transfer type."),
|
|
38
|
+
};
|
|
39
|
+
export const PointsHistogramInputSchema = {
|
|
40
|
+
storeCode: z.string().optional().describe("INTERNAL: Auto-configured from server settings. NEVER ask the user for this value. Only set if the user explicitly requests a different store."),
|
|
41
|
+
memberId: z.string().describe("The member ID (UUID) to get histogram for."),
|
|
42
|
+
pointType: z.enum(["spent", "earned", "expired", "pending"]).describe("Filter by point type (required). One of: spent, earned, expired, pending."),
|
|
43
|
+
walletCode: z.string().optional().describe("Wallet type code. Uses default if not specified."),
|
|
44
|
+
interval: z.enum(["day", "week", "month"]).optional().describe("Time interval for aggregation (default: month)."),
|
|
45
|
+
dateFrom: z.string().optional().describe("Start date for histogram (ISO format: YYYY-MM-DD)."),
|
|
46
|
+
dateTo: z.string().optional().describe("End date for histogram (ISO format: YYYY-MM-DD)."),
|
|
47
|
+
};
|
|
@@ -7,7 +7,7 @@ export const ReferralCreateInputSchema = {
|
|
|
7
7
|
storeCode: z
|
|
8
8
|
.string()
|
|
9
9
|
.optional()
|
|
10
|
-
.describe("
|
|
10
|
+
.describe("INTERNAL: Auto-configured from server settings. NEVER ask the user for this value. Only set if the user explicitly requests a different store."),
|
|
11
11
|
memberId: z
|
|
12
12
|
.string()
|
|
13
13
|
.uuid()
|
|
@@ -25,7 +25,7 @@ export const ReferralListInputSchema = {
|
|
|
25
25
|
storeCode: z
|
|
26
26
|
.string()
|
|
27
27
|
.optional()
|
|
28
|
-
.describe("
|
|
28
|
+
.describe("INTERNAL: Auto-configured from server settings. NEVER ask the user for this value. Only set if the user explicitly requests a different store."),
|
|
29
29
|
referralId: z.string().uuid().optional().describe("Filter by specific referral ID"),
|
|
30
30
|
referrerId: z.string().uuid().optional().describe("Filter by referrer member ID"),
|
|
31
31
|
referrerName: z.string().max(255).optional().describe("Filter by referrer name"),
|
|
@@ -44,7 +44,7 @@ export const ReferralDeleteInputSchema = {
|
|
|
44
44
|
storeCode: z
|
|
45
45
|
.string()
|
|
46
46
|
.optional()
|
|
47
|
-
.describe("
|
|
47
|
+
.describe("INTERNAL: Auto-configured from server settings. NEVER ask the user for this value. Only set if the user explicitly requests a different store."),
|
|
48
48
|
memberId: z
|
|
49
49
|
.string()
|
|
50
50
|
.uuid()
|
|
@@ -46,16 +46,22 @@ export async function rewardList(input) {
|
|
|
46
46
|
}
|
|
47
47
|
export async function rewardCreate(input) {
|
|
48
48
|
const storeCode = getStoreCode(input.storeCode);
|
|
49
|
-
// API requires: translations (name only), reward (type), activity, visibility
|
|
50
|
-
// NOTE: usageLimit is NOT supported at creation time - API rejects it as "extra fields"
|
|
51
|
-
// Use reward_update after creation to set usageLimit
|
|
49
|
+
// API requires: translations (name only), reward (type), activity, visibility, usageLimit
|
|
52
50
|
// NOTE: description is NOT supported by the API at creation time
|
|
51
|
+
// CRITICAL: usageLimit shape depends on reward TYPE:
|
|
52
|
+
// - material/fortune_wheel: require BOTH perUser AND general
|
|
53
|
+
// - static_coupon/dynamic_coupon/conversion_coupon: require ONLY perUser (general is rejected as "extra fields")
|
|
54
|
+
const isCouponType = ["static_coupon", "dynamic_coupon", "conversion_coupon"].includes(input.reward);
|
|
55
|
+
const usageLimit = { perUser: input.usageLimitPerUser ?? 0 };
|
|
56
|
+
if (!isCouponType) {
|
|
57
|
+
usageLimit.general = input.usageLimitGeneral ?? 0;
|
|
58
|
+
}
|
|
53
59
|
const payload = omitUndefined({
|
|
54
60
|
translations: input.translations,
|
|
55
61
|
reward: input.reward,
|
|
56
62
|
activity: input.activity,
|
|
57
63
|
visibility: input.visibility,
|
|
58
|
-
|
|
64
|
+
usageLimit,
|
|
59
65
|
costInPoints: input.costInPoints,
|
|
60
66
|
usageInstruction: input.usageInstruction,
|
|
61
67
|
active: input.active,
|
|
@@ -76,6 +82,31 @@ export async function rewardCreate(input) {
|
|
|
76
82
|
};
|
|
77
83
|
}
|
|
78
84
|
catch (error) {
|
|
85
|
+
// Check for invalid reward type
|
|
86
|
+
const axiosError = error;
|
|
87
|
+
const apiErrors = axiosError.response?.data?.errors || [];
|
|
88
|
+
const rewardTypeError = apiErrors.find(e => e.path === "reward" && e.message.includes("selected choice is invalid"));
|
|
89
|
+
if (rewardTypeError) {
|
|
90
|
+
throw new OpenLoyaltyError({
|
|
91
|
+
code: "INVALID_REWARD_TYPE",
|
|
92
|
+
message: `Reward type '${input.reward}' is not valid`,
|
|
93
|
+
hint: "Valid reward types: 'material' (physical goods), 'static_coupon' (fixed discount code), " +
|
|
94
|
+
"'dynamic_coupon' (variable value coupon), 'conversion_coupon' (points-to-coupon conversion), " +
|
|
95
|
+
"'fortune_wheel' (gamified reward). NOTE: 'discount_code' is NOT a valid type - use 'static_coupon' instead.",
|
|
96
|
+
relatedTool: "ol_reward_create",
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
// Detect missing couponValue for coupon-type rewards
|
|
100
|
+
const allErrorMessages = apiErrors.map(e => `${e.path || ""}: ${e.message}`).join(" ").toLowerCase();
|
|
101
|
+
if ((allErrorMessages.includes("coupon") || allErrorMessages.includes("couponvalue")) &&
|
|
102
|
+
["static_coupon", "dynamic_coupon", "conversion_coupon"].includes(input.reward)) {
|
|
103
|
+
throw new OpenLoyaltyError({
|
|
104
|
+
code: "MISSING_COUPON_VALUE",
|
|
105
|
+
message: `Reward type '${input.reward}' requires couponValue`,
|
|
106
|
+
hint: `For coupon-type rewards, you MUST provide couponValue (e.g., couponValue: 10 for a $10 coupon). Add couponValue to your request and retry.`,
|
|
107
|
+
relatedTool: "ol_reward_create",
|
|
108
|
+
});
|
|
109
|
+
}
|
|
79
110
|
throw formatApiError(error, "ol_reward_create");
|
|
80
111
|
}
|
|
81
112
|
}
|
|
@@ -164,9 +195,35 @@ export async function rewardUpdate(input) {
|
|
|
164
195
|
payload.levels = input.levels;
|
|
165
196
|
if (input.segments !== undefined)
|
|
166
197
|
payload.segments = input.segments;
|
|
167
|
-
// usageLimit
|
|
198
|
+
// usageLimit handling depends on reward type:
|
|
199
|
+
// - material/fortune_wheel: require BOTH perUser AND general
|
|
200
|
+
// - coupon types: only accept perUser (general is rejected as "extra fields")
|
|
201
|
+
const existingRewardType = existing.reward;
|
|
202
|
+
const isCouponType = ["static_coupon", "dynamic_coupon", "conversion_coupon"].includes(existingRewardType || "");
|
|
203
|
+
const existingUsageLimit = existing.usageLimit;
|
|
168
204
|
if (input.usageLimitPerUser !== undefined) {
|
|
169
|
-
|
|
205
|
+
// User explicitly setting usageLimitPerUser
|
|
206
|
+
if (isCouponType) {
|
|
207
|
+
payload.usageLimit = { perUser: input.usageLimitPerUser };
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
payload.usageLimit = {
|
|
211
|
+
perUser: input.usageLimitPerUser,
|
|
212
|
+
general: existingUsageLimit?.general ?? 0,
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
else if (existingUsageLimit) {
|
|
217
|
+
// Preserve existing usageLimit (API requires it on PUT for material type)
|
|
218
|
+
if (isCouponType) {
|
|
219
|
+
payload.usageLimit = { perUser: existingUsageLimit.perUser ?? 0 };
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
payload.usageLimit = {
|
|
223
|
+
perUser: existingUsageLimit.perUser ?? 0,
|
|
224
|
+
general: existingUsageLimit.general ?? 0,
|
|
225
|
+
};
|
|
226
|
+
}
|
|
170
227
|
}
|
|
171
228
|
try {
|
|
172
229
|
await apiPut(`/${storeCode}/reward/${input.rewardId}`, { reward: payload });
|
|
@@ -230,6 +287,22 @@ export async function rewardBuy(input) {
|
|
|
230
287
|
relatedTool: "ol_reward_buy",
|
|
231
288
|
});
|
|
232
289
|
}
|
|
290
|
+
if (allMessages.includes("not active") || allMessages.includes("inactive") || allMessages.includes("reward is not active")) {
|
|
291
|
+
throw new OpenLoyaltyError({
|
|
292
|
+
code: "REWARD_NOT_ACTIVE",
|
|
293
|
+
message: "This reward is not active and cannot be purchased",
|
|
294
|
+
hint: `Use ol_reward_activate(rewardId: "${input.rewardId}") to activate the reward first, or use ol_reward_get(rewardId: "${input.rewardId}") to check its status.`,
|
|
295
|
+
relatedTool: "ol_reward_buy",
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
if (allMessages.includes("usage limit") || allMessages.includes("limit reached") || allMessages.includes("limit exceeded")) {
|
|
299
|
+
throw new OpenLoyaltyError({
|
|
300
|
+
code: "USAGE_LIMIT_REACHED",
|
|
301
|
+
message: "The usage limit for this reward has been reached",
|
|
302
|
+
hint: `Use ol_reward_get(rewardId: "${input.rewardId}") to check usageLimit settings. To increase limits, use ol_reward_update(rewardId: "${input.rewardId}", usageLimitPerUser: N).`,
|
|
303
|
+
relatedTool: "ol_reward_buy",
|
|
304
|
+
});
|
|
305
|
+
}
|
|
233
306
|
throw formatApiError(error, "ol_reward_buy");
|
|
234
307
|
}
|
|
235
308
|
}
|
|
@@ -68,6 +68,8 @@ export declare const rewardToolDefinitions: readonly [{
|
|
|
68
68
|
from: string;
|
|
69
69
|
to: string;
|
|
70
70
|
}>;
|
|
71
|
+
usageLimitPerUser: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
72
|
+
usageLimitGeneral: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
71
73
|
costInPoints: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
72
74
|
usageInstruction: import("zod").ZodOptional<import("zod").ZodString>;
|
|
73
75
|
active: import("zod").ZodOptional<import("zod").ZodBoolean>;
|
|
@@ -20,15 +20,13 @@ export const rewardToolDefinitions = [
|
|
|
20
20
|
name: "ol_reward_create",
|
|
21
21
|
title: "Create New Reward",
|
|
22
22
|
description: "Create a new reward that members can redeem with points. " +
|
|
23
|
-
"
|
|
24
|
-
"1.
|
|
25
|
-
"2.
|
|
26
|
-
"3.
|
|
27
|
-
"4.
|
|
28
|
-
"
|
|
29
|
-
"For
|
|
30
|
-
"For tier targeting: set target='level' and levels=['tier-uuid-1', 'tier-uuid-2']. " +
|
|
31
|
-
"⚠️ usageLimit is NOT supported at creation - use reward_update after creation to set limits.",
|
|
23
|
+
"KEY DECISIONS (confirm with user if not specified): " +
|
|
24
|
+
"1. Reward type -- material (physical item), static_coupon (discount code), dynamic_coupon, conversion_coupon, fortune_wheel " +
|
|
25
|
+
"2. Cost in points -- how many points to redeem? (this is the program's exchange rate) " +
|
|
26
|
+
"3. Usage limits -- how many redemptions per member? How many total? (0 = unlimited, creates uncapped liability) " +
|
|
27
|
+
"4. Targeting -- all members, or restricted to specific tiers/segments? " +
|
|
28
|
+
"REQUIRED: translations.en.name, reward type, activity period, visibility period. " +
|
|
29
|
+
"For static_coupon: couponValue is also required.",
|
|
32
30
|
readOnly: false,
|
|
33
31
|
inputSchema: RewardCreateInputSchema,
|
|
34
32
|
handler: rewardCreate,
|
|
@@ -45,7 +43,9 @@ export const rewardToolDefinitions = [
|
|
|
45
43
|
name: "ol_reward_update",
|
|
46
44
|
title: "Update Reward",
|
|
47
45
|
description: "Update reward configuration. Cannot change reward type after creation. " +
|
|
48
|
-
"
|
|
46
|
+
"Uses GET-then-PUT pattern (fetches existing reward, merges changes, sends full object). " +
|
|
47
|
+
"usageLimitPerUser can be set here or at creation time. " +
|
|
48
|
+
"For material rewards, usageLimit.general is preserved from existing data on update.",
|
|
49
49
|
readOnly: false,
|
|
50
50
|
inputSchema: RewardUpdateInputSchema,
|
|
51
51
|
handler: rewardUpdate,
|
|
@@ -55,6 +55,8 @@ export declare const RewardCreateInputSchema: {
|
|
|
55
55
|
from: string;
|
|
56
56
|
to: string;
|
|
57
57
|
}>;
|
|
58
|
+
usageLimitPerUser: z.ZodOptional<z.ZodNumber>;
|
|
59
|
+
usageLimitGeneral: z.ZodOptional<z.ZodNumber>;
|
|
58
60
|
costInPoints: z.ZodOptional<z.ZodNumber>;
|
|
59
61
|
usageInstruction: z.ZodOptional<z.ZodString>;
|
|
60
62
|
active: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
export const RewardListInputSchema = {
|
|
3
|
-
storeCode: z.string().optional().describe("
|
|
3
|
+
storeCode: z.string().optional().describe("INTERNAL: Auto-configured from server settings. NEVER ask the user for this value. Only set if the user explicitly requests a different store."),
|
|
4
4
|
page: z.number().optional().describe("Page number (default: 1)."),
|
|
5
5
|
perPage: z.number().optional().describe("Items per page (default: 10)."),
|
|
6
6
|
active: z.boolean().optional().describe("Filter by active status."),
|
|
@@ -26,49 +26,68 @@ const RewardVisibilityInputSchema = z.object({
|
|
|
26
26
|
from: z.string().describe("Visibility start datetime (format: 'YYYY-MM-DD HH:mm'). REQUIRED."),
|
|
27
27
|
to: z.string().describe("Visibility end datetime (format: 'YYYY-MM-DD HH:mm'). REQUIRED."),
|
|
28
28
|
});
|
|
29
|
-
// NOTE: usageLimit
|
|
30
|
-
//
|
|
29
|
+
// NOTE: usageLimit shape depends on reward TYPE:
|
|
30
|
+
// - material/fortune_wheel: require BOTH perUser AND general
|
|
31
|
+
// - coupon types (static_coupon, dynamic_coupon, conversion_coupon): only accept perUser
|
|
32
|
+
// Handler automatically sends the correct shape based on reward type.
|
|
31
33
|
export const RewardCreateInputSchema = {
|
|
32
|
-
storeCode: z.string().optional().describe("
|
|
34
|
+
storeCode: z.string().optional().describe("INTERNAL: Auto-configured from server settings. NEVER ask the user for this value. Only set if the user explicitly requests a different store."),
|
|
33
35
|
translations: RewardTranslationsInputSchema.describe("Reward name translations. At least 'en' key with { name } is REQUIRED."),
|
|
34
|
-
reward: z.enum(["static_coupon", "dynamic_coupon", "conversion_coupon", "material", "fortune_wheel"]).describe("Reward type
|
|
35
|
-
"
|
|
36
|
+
reward: z.enum(["static_coupon", "dynamic_coupon", "conversion_coupon", "material", "fortune_wheel"]).describe("Reward fulfillment type. " +
|
|
37
|
+
"'material' = physical goods/experiences, 'static_coupon' = fixed discount code (requires couponValue), " +
|
|
38
|
+
"'dynamic_coupon' = variable value coupon, 'conversion_coupon' = points-to-credit (requires unitsConversion), " +
|
|
39
|
+
"'fortune_wheel' = gamified spin-to-win. " +
|
|
40
|
+
"BUSINESS DECISION: Each type has different cost structures and operational requirements. " +
|
|
41
|
+
"NOTE: 'discount_code' is NOT valid -- use 'static_coupon'."),
|
|
36
42
|
activity: RewardActivityInputSchema.describe("Activity period when reward can be purchased. Use datetime format 'YYYY-MM-DD HH:mm'. REQUIRED."),
|
|
37
43
|
visibility: RewardVisibilityInputSchema.describe("Visibility period when reward is shown. Use datetime format 'YYYY-MM-DD HH:mm'. REQUIRED."),
|
|
38
|
-
|
|
39
|
-
|
|
44
|
+
usageLimitPerUser: z.number().optional().describe("Max redemptions per member (0 = unlimited). " +
|
|
45
|
+
"BUSINESS IMPACT: Unlimited allows a single member to exhaust entire reward stock. " +
|
|
46
|
+
"Typical values: 1 (exclusive/one-time), 3-5 (promotional), 10+ (evergreen). " +
|
|
47
|
+
"BUSINESS DECISION: Confirm with user -- this directly controls reward budget exposure."),
|
|
48
|
+
usageLimitGeneral: z.number().optional().describe("Max total redemptions across all members (0 = unlimited). " +
|
|
49
|
+
"ONLY for 'material' and 'fortune_wheel' types -- API rejects this for coupon types. " +
|
|
50
|
+
"BUSINESS IMPACT: This is the total inventory cap. Running out unexpectedly damages member trust."),
|
|
51
|
+
costInPoints: z.number().optional().describe("Points required to redeem this reward. " +
|
|
52
|
+
"BUSINESS IMPACT: This is the program's points-to-value exchange rate. " +
|
|
53
|
+
"Too low = members drain value too fast. Too high = rewards feel unattainable. " +
|
|
54
|
+
"Typical values: if earn rate is 10 pts/$1 spent, a $10 reward should cost 500-2000 points."),
|
|
40
55
|
usageInstruction: z.string().optional().describe("Instructions for using the reward."),
|
|
41
56
|
active: z.boolean().optional().describe("Whether reward is active (default: false)."),
|
|
42
|
-
categories: z.array(z.string()).optional().describe("Array of category UUIDs."),
|
|
43
|
-
levels: z.array(z.string()).optional().describe("Array of tier level UUIDs that can see/redeem."),
|
|
44
|
-
segments: z.array(z.string()).optional().describe("Array of segment UUIDs that can see/redeem."),
|
|
45
|
-
target: z.enum(["level", "segment"]).nullable().optional().describe("
|
|
46
|
-
|
|
47
|
-
|
|
57
|
+
categories: z.array(z.string()).optional().describe("Array of category UUIDs. Use ol_reward_category_list() to find valid categoryId values."),
|
|
58
|
+
levels: z.array(z.string()).optional().describe("Array of tier level UUIDs that can see/redeem. Use ol_tierset_get_tiers(tierSetId) to find valid levelId values."),
|
|
59
|
+
segments: z.array(z.string()).optional().describe("Array of segment UUIDs that can see/redeem. Use ol_segment_list() to find valid segmentId values."),
|
|
60
|
+
target: z.enum(["level", "segment"]).nullable().optional().describe("Targeting: 'level' = specific tiers, 'segment' = specific segments, null = all members. " +
|
|
61
|
+
"BUSINESS DECISION: Untargeted rewards reach everyone but dilute exclusivity. " +
|
|
62
|
+
"Tier-targeted rewards drive tier progression motivation."),
|
|
63
|
+
couponValue: z.number().optional().describe("Coupon value (required for static_coupon). " +
|
|
64
|
+
"BUSINESS DECISION: Dollar/percentage value of the discount. Direct revenue impact."),
|
|
65
|
+
couponValueType: z.enum(["money", "percentage"]).optional().describe("Coupon value type: 'money' or 'percentage' (lowercase). " +
|
|
66
|
+
"BUSINESS DECISION: Money vs percentage completely changes the economics."),
|
|
48
67
|
daysValid: z.number().optional().describe("Days the coupon remains valid after purchase."),
|
|
49
68
|
};
|
|
50
69
|
export const RewardGetInputSchema = {
|
|
51
|
-
storeCode: z.string().optional().describe("
|
|
70
|
+
storeCode: z.string().optional().describe("INTERNAL: Auto-configured from server settings. NEVER ask the user for this value. Only set if the user explicitly requests a different store."),
|
|
52
71
|
rewardId: z.string().describe("The reward ID (UUID) to retrieve."),
|
|
53
72
|
};
|
|
54
73
|
export const RewardUpdateInputSchema = {
|
|
55
|
-
storeCode: z.string().optional().describe("
|
|
74
|
+
storeCode: z.string().optional().describe("INTERNAL: Auto-configured from server settings. NEVER ask the user for this value. Only set if the user explicitly requests a different store."),
|
|
56
75
|
rewardId: z.string().describe("The reward ID (UUID) to update."),
|
|
57
76
|
name: z.string().optional().describe("Reward name."),
|
|
58
77
|
costInPoints: z.number().optional().describe("Points required to redeem."),
|
|
59
78
|
description: z.string().optional().describe("Reward description."),
|
|
60
79
|
active: z.boolean().optional().describe("Whether reward is active."),
|
|
61
|
-
categories: z.array(z.string()).optional().describe("Array of category UUIDs."),
|
|
62
|
-
levels: z.array(z.string()).optional().describe("Array of tier level UUIDs."),
|
|
63
|
-
segments: z.array(z.string()).optional().describe("Array of segment UUIDs."),
|
|
80
|
+
categories: z.array(z.string()).optional().describe("Array of category UUIDs. Use ol_reward_category_list() to find valid categoryId values."),
|
|
81
|
+
levels: z.array(z.string()).optional().describe("Array of tier level UUIDs. Use ol_tierset_get_tiers(tierSetId) to find valid levelId values."),
|
|
82
|
+
segments: z.array(z.string()).optional().describe("Array of segment UUIDs. Use ol_segment_list() to find valid segmentId values."),
|
|
64
83
|
usageLimitPerUser: z.number().optional().describe("Maximum redemptions per member. Set this after creation to limit usage."),
|
|
65
84
|
};
|
|
66
85
|
export const RewardIdInputSchema = {
|
|
67
|
-
storeCode: z.string().optional().describe("
|
|
86
|
+
storeCode: z.string().optional().describe("INTERNAL: Auto-configured from server settings. NEVER ask the user for this value. Only set if the user explicitly requests a different store."),
|
|
68
87
|
rewardId: z.string().describe("The reward ID (UUID)."),
|
|
69
88
|
};
|
|
70
89
|
export const RewardBuyInputSchema = {
|
|
71
|
-
storeCode: z.string().optional().describe("
|
|
90
|
+
storeCode: z.string().optional().describe("INTERNAL: Auto-configured from server settings. NEVER ask the user for this value. Only set if the user explicitly requests a different store."),
|
|
72
91
|
rewardId: z.string().describe("The reward ID (UUID) to purchase."),
|
|
73
92
|
memberId: z.string().describe("The member ID (UUID) purchasing the reward."),
|
|
74
93
|
quantity: z.number().optional().describe("Number of rewards to purchase (1-32, default: 1)."),
|
|
@@ -76,12 +95,12 @@ export const RewardBuyInputSchema = {
|
|
|
76
95
|
withoutPoints: z.boolean().optional().describe("Admin only: skip points deduction."),
|
|
77
96
|
};
|
|
78
97
|
export const RewardRedeemInputSchema = {
|
|
79
|
-
storeCode: z.string().optional().describe("
|
|
98
|
+
storeCode: z.string().optional().describe("INTERNAL: Auto-configured from server settings. NEVER ask the user for this value. Only set if the user explicitly requests a different store."),
|
|
80
99
|
memberId: z.string().describe("The member ID (UUID) redeeming the coupon."),
|
|
81
100
|
couponCode: z.string().describe("The coupon code to redeem."),
|
|
82
101
|
};
|
|
83
102
|
export const RewardCategoryListInputSchema = {
|
|
84
|
-
storeCode: z.string().optional().describe("
|
|
103
|
+
storeCode: z.string().optional().describe("INTERNAL: Auto-configured from server settings. NEVER ask the user for this value. Only set if the user explicitly requests a different store."),
|
|
85
104
|
page: z.number().optional().describe("Page number (default: 1)."),
|
|
86
105
|
perPage: z.number().optional().describe("Items per page (default: 10)."),
|
|
87
106
|
active: z.boolean().optional().describe("Filter by active status."),
|
|
@@ -18,11 +18,13 @@ export const segmentToolDefinitions = [
|
|
|
18
18
|
{
|
|
19
19
|
name: "ol_segment_create",
|
|
20
20
|
title: "Create Segment",
|
|
21
|
-
description: "Create segment to group members. " +
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
21
|
+
description: "Create a segment to group members by behavior or attributes for campaign targeting and analytics. " +
|
|
22
|
+
"KEY DECISIONS (confirm with user if not specified): " +
|
|
23
|
+
"1. Criteria type -- what defines this segment? transaction_count, purchase_in_period, average_transaction_value, bought_skus, bought_labels, etc. " +
|
|
24
|
+
"2. Threshold values -- min/max boundaries? (e.g., min=5 transactions captures frequent buyers; min=2 captures nearly everyone) " +
|
|
25
|
+
"3. Intended use -- campaign targeting (activate immediately) or analytics only (can stay inactive)? " +
|
|
26
|
+
"REQUIRED: name, parts array with criteria. Parts use OR logic, criteria within parts use AND logic. " +
|
|
27
|
+
"NOTE: 'tier' and 'points_balance' types are REJECTED by the API despite being documented.",
|
|
26
28
|
readOnly: false,
|
|
27
29
|
inputSchema: SegmentCreateInputSchema,
|
|
28
30
|
handler: segmentCreate,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
// Input Schemas
|
|
3
3
|
export const SegmentListInputSchema = {
|
|
4
|
-
storeCode: z.string().optional().describe("
|
|
4
|
+
storeCode: z.string().optional().describe("INTERNAL: Auto-configured from server settings. NEVER ask the user for this value. Only set if the user explicitly requests a different store."),
|
|
5
5
|
page: z.number().optional().describe("Page number (default: 1)."),
|
|
6
6
|
perPage: z.number().optional().describe("Items per page (default: 10)."),
|
|
7
7
|
active: z.boolean().optional().describe("Filter by active status."),
|
|
@@ -18,8 +18,8 @@ const SegmentCriterionInputSchema = z.object({
|
|
|
18
18
|
days: z.number().optional().describe("Days for time-based criteria."),
|
|
19
19
|
fromDate: z.string().optional().describe("Start date (ISO format)."),
|
|
20
20
|
toDate: z.string().optional().describe("End date (ISO format)."),
|
|
21
|
-
min: z.number().optional().describe("Minimum value."),
|
|
22
|
-
max: z.number().optional().describe("Maximum value."),
|
|
21
|
+
min: z.number().optional().describe("Minimum value. BUSINESS IMPACT: Too low a threshold (e.g., min=2 transactions) captures most members -- segment becomes too broad, wasting campaign budget."),
|
|
22
|
+
max: z.number().optional().describe("Maximum value. BUSINESS IMPACT: Too narrow a range (e.g., max=3 with min=3) captures very few members -- limited campaign impact."),
|
|
23
23
|
posIds: z.array(z.string()).optional().describe("POS IDs."),
|
|
24
24
|
skus: z.array(z.string()).optional().describe("SKU codes."),
|
|
25
25
|
makers: z.array(z.string()).optional().describe("Maker/brand names."),
|
|
@@ -37,18 +37,18 @@ const SegmentPartInputSchema = z.object({
|
|
|
37
37
|
criteria: z.array(SegmentCriterionInputSchema).describe("Criteria for this part (AND logic)."),
|
|
38
38
|
});
|
|
39
39
|
export const SegmentCreateInputSchema = {
|
|
40
|
-
storeCode: z.string().optional().describe("
|
|
40
|
+
storeCode: z.string().optional().describe("INTERNAL: Auto-configured from server settings. NEVER ask the user for this value. Only set if the user explicitly requests a different store."),
|
|
41
41
|
name: z.string().describe("Segment name (required)."),
|
|
42
42
|
description: z.string().optional().describe("Segment description."),
|
|
43
43
|
active: z.boolean().optional().describe("Whether segment is active (default: false)."),
|
|
44
44
|
parts: z.array(SegmentPartInputSchema).describe("Segment parts. Parts use OR logic (ANY part matches), criteria within parts use AND logic (ALL criteria must match)."),
|
|
45
45
|
};
|
|
46
46
|
export const SegmentGetInputSchema = {
|
|
47
|
-
storeCode: z.string().optional().describe("
|
|
47
|
+
storeCode: z.string().optional().describe("INTERNAL: Auto-configured from server settings. NEVER ask the user for this value. Only set if the user explicitly requests a different store."),
|
|
48
48
|
segmentId: z.string().describe("The segment ID (UUID) to retrieve."),
|
|
49
49
|
};
|
|
50
50
|
export const SegmentUpdateInputSchema = {
|
|
51
|
-
storeCode: z.string().optional().describe("
|
|
51
|
+
storeCode: z.string().optional().describe("INTERNAL: Auto-configured from server settings. NEVER ask the user for this value. Only set if the user explicitly requests a different store."),
|
|
52
52
|
segmentId: z.string().describe("The segment ID (UUID) to update."),
|
|
53
53
|
name: z.string().describe("Segment name."),
|
|
54
54
|
description: z.string().optional().describe("Segment description."),
|
|
@@ -56,24 +56,24 @@ export const SegmentUpdateInputSchema = {
|
|
|
56
56
|
parts: z.array(SegmentPartInputSchema).describe("Segment parts."),
|
|
57
57
|
};
|
|
58
58
|
export const SegmentDeleteInputSchema = {
|
|
59
|
-
storeCode: z.string().optional().describe("
|
|
59
|
+
storeCode: z.string().optional().describe("INTERNAL: Auto-configured from server settings. NEVER ask the user for this value. Only set if the user explicitly requests a different store."),
|
|
60
60
|
segmentId: z.string().describe("The segment ID (UUID) to delete."),
|
|
61
61
|
};
|
|
62
62
|
export const SegmentGetMembersInputSchema = {
|
|
63
|
-
storeCode: z.string().optional().describe("
|
|
63
|
+
storeCode: z.string().optional().describe("INTERNAL: Auto-configured from server settings. NEVER ask the user for this value. Only set if the user explicitly requests a different store."),
|
|
64
64
|
segmentId: z.string().describe("The segment ID (UUID) to get members for."),
|
|
65
65
|
page: z.number().optional().describe("Page number (default: 1)."),
|
|
66
66
|
perPage: z.number().optional().describe("Items per page (default: 25)."),
|
|
67
67
|
};
|
|
68
68
|
export const SegmentActivateInputSchema = {
|
|
69
|
-
storeCode: z.string().optional().describe("
|
|
69
|
+
storeCode: z.string().optional().describe("INTERNAL: Auto-configured from server settings. NEVER ask the user for this value. Only set if the user explicitly requests a different store."),
|
|
70
70
|
segmentId: z.string().describe("The segment ID (UUID) to activate."),
|
|
71
71
|
};
|
|
72
72
|
export const SegmentDeactivateInputSchema = {
|
|
73
|
-
storeCode: z.string().optional().describe("
|
|
73
|
+
storeCode: z.string().optional().describe("INTERNAL: Auto-configured from server settings. NEVER ask the user for this value. Only set if the user explicitly requests a different store."),
|
|
74
74
|
segmentId: z.string().describe("The segment ID (UUID) to deactivate."),
|
|
75
75
|
};
|
|
76
76
|
export const SegmentGetResourcesInputSchema = {
|
|
77
|
-
storeCode: z.string().optional().describe("
|
|
77
|
+
storeCode: z.string().optional().describe("INTERNAL: Auto-configured from server settings. NEVER ask the user for this value. Only set if the user explicitly requests a different store."),
|
|
78
78
|
segmentId: z.string().describe("The segment ID (UUID) to get associated resources for."),
|
|
79
79
|
};
|