@yoryoboy/bi-mcp 1.19.0 → 1.20.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/dist/.tsbuildinfo +1 -1
- package/dist/mcp-use.json +6 -3
- package/dist/scripts/profile-mercadolibre-billing.js +634 -0
- package/dist/scripts/profile-mercadolibre-billing.js.map +7 -0
- package/dist/src/config/__tests__/tiendanube-profile-store.test.js +50 -0
- package/dist/src/config/__tests__/tiendanube-profile-store.test.js.map +7 -0
- package/dist/src/config/tiendanube-profile-store.js +31 -0
- package/dist/src/config/tiendanube-profile-store.js.map +7 -0
- package/dist/src/google-ads/report-utils.js +78 -0
- package/dist/src/google-ads/report-utils.js.map +7 -0
- package/dist/src/search-console/search-console-utils.js +275 -0
- package/dist/src/search-console/search-console-utils.js.map +7 -0
- package/dist/src/services/mercadolibre/__tests__/mercadolibre-sales-report-ventas.test.js +358 -0
- package/dist/src/services/mercadolibre/__tests__/mercadolibre-sales-report-ventas.test.js.map +7 -0
- package/dist/src/services/mercadolibre/__tests__/mercadolibre-sales-report.test.js +96 -0
- package/dist/src/services/mercadolibre/__tests__/mercadolibre-sales-report.test.js.map +7 -0
- package/dist/src/services/mercadolibre/mercadolibre-claim-return-lookup.js +15 -0
- package/dist/src/services/mercadolibre/mercadolibre-claim-return-lookup.js.map +7 -0
- package/dist/src/services/mercadolibre/mercadolibre-observability.js +12 -0
- package/dist/src/services/mercadolibre/mercadolibre-observability.js.map +7 -0
- package/dist/src/services/mercadolibre/mercadolibre-sale-reference.js +7 -0
- package/dist/src/services/mercadolibre/mercadolibre-sale-reference.js.map +7 -0
- package/dist/src/services/mercadolibre/mercadolibre-sales-report.js +553 -0
- package/dist/src/services/mercadolibre/mercadolibre-sales-report.js.map +7 -0
- package/dist/src/services/vtex/__tests__/vtex-catalog-write-batch.test.js +165 -0
- package/dist/src/services/vtex/__tests__/vtex-catalog-write-batch.test.js.map +7 -0
- package/dist/src/tools/config/__tests__/list-profiles.test.js +144 -1
- package/dist/src/tools/config/__tests__/list-profiles.test.js.map +2 -2
- package/dist/src/tools/config/list-profiles.js +50 -6
- package/dist/src/tools/config/list-profiles.js.map +2 -2
- package/dist/src/tools/mercadolibre/__tests__/get-sales-report-foundation.test.js +417 -0
- package/dist/src/tools/mercadolibre/__tests__/get-sales-report-foundation.test.js.map +7 -0
- package/dist/src/tools/mercadolibre/get-sales-report.js +474 -0
- package/dist/src/tools/mercadolibre/get-sales-report.js.map +7 -0
- package/dist/src/tools/vtex/__tests__/catalog-admin-batch.test.js +233 -0
- package/dist/src/tools/vtex/__tests__/catalog-admin-batch.test.js.map +7 -0
- package/dist/src/tools/vtex/catalog-admin-batch.js +298 -0
- package/dist/src/tools/vtex/catalog-admin-batch.js.map +7 -0
- package/dist/tests/meli/meli-sales-report-buyers-mcp-e2e.test.js +137 -0
- package/dist/tests/meli/meli-sales-report-buyers-mcp-e2e.test.js.map +7 -0
- package/dist/tests/meli/meli-sales-report-mcp-e2e-server.js +24 -0
- package/dist/tests/meli/meli-sales-report-mcp-e2e-server.js.map +7 -0
- package/dist/tests/meli/meli-sales-report-mcp-e2e.test.js +207 -0
- package/dist/tests/meli/meli-sales-report-mcp-e2e.test.js.map +7 -0
- package/dist/tests/meli/meli-sales-report-public-mcp-e2e-server.js +10 -0
- package/dist/tests/meli/meli-sales-report-public-mcp-e2e-server.js.map +7 -0
- package/dist/tests/meli/meli-sales-report-public-registration.test.js +98 -0
- package/dist/tests/meli/meli-sales-report-public-registration.test.js.map +7 -0
- package/dist/tests/smoke/process-harness.js +89 -0
- package/dist/tests/smoke/process-harness.js.map +7 -0
- package/dist/tests/smoke/process-harness.test.js +39 -0
- package/dist/tests/smoke/process-harness.test.js.map +7 -0
- package/package.json +1 -1
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
const resolveVtexProfileOrSelectionMock = vi.fn();
|
|
3
|
+
const planCatalogBatchMock = vi.fn();
|
|
4
|
+
const executeCatalogBatchMock = vi.fn();
|
|
5
|
+
vi.mock("../profile-resolution.js", () => ({
|
|
6
|
+
resolveVtexProfileOrSelection: resolveVtexProfileOrSelectionMock
|
|
7
|
+
}));
|
|
8
|
+
vi.mock("../../../services/vtex/vtex-catalog-write.js", () => ({
|
|
9
|
+
planCatalogBatch: planCatalogBatchMock,
|
|
10
|
+
executeCatalogBatch: executeCatalogBatchMock
|
|
11
|
+
}));
|
|
12
|
+
const moduleUnderTest = await import("../catalog-admin-batch.js");
|
|
13
|
+
function getStructured(result) {
|
|
14
|
+
if (result && typeof result === "object" && "structuredContent" in result) {
|
|
15
|
+
return result.structuredContent;
|
|
16
|
+
}
|
|
17
|
+
return result;
|
|
18
|
+
}
|
|
19
|
+
describe("catalog-admin-batch", () => {
|
|
20
|
+
beforeEach(() => {
|
|
21
|
+
vi.clearAllMocks();
|
|
22
|
+
resolveVtexProfileOrSelectionMock.mockResolvedValue({
|
|
23
|
+
ok: true,
|
|
24
|
+
value: { profileId: "profile-1" }
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
it("auto-applies medium-risk batch after safe preflight", async () => {
|
|
28
|
+
planCatalogBatchMock.mockResolvedValue({
|
|
29
|
+
preflight: {
|
|
30
|
+
entities: 2,
|
|
31
|
+
entityTypes: ["product", "sku"],
|
|
32
|
+
destructive: false,
|
|
33
|
+
hasDeleteOrReplaceAll: false,
|
|
34
|
+
dependencyFailureCount: 0,
|
|
35
|
+
multiEntityCriticalReassignment: false
|
|
36
|
+
},
|
|
37
|
+
warnings: [],
|
|
38
|
+
impactedEntityTypes: ["product", "sku"],
|
|
39
|
+
before: [{ operation_index: 0, snapshot: { id: "10" } }],
|
|
40
|
+
after: [{ operation_index: 0, snapshot: { id: "10", updated: true } }]
|
|
41
|
+
});
|
|
42
|
+
executeCatalogBatchMock.mockResolvedValue({
|
|
43
|
+
successful: [
|
|
44
|
+
{
|
|
45
|
+
operation_index: 0,
|
|
46
|
+
operation_type: "update_product_basic_fields",
|
|
47
|
+
resource_id: "10",
|
|
48
|
+
result: { ok: true }
|
|
49
|
+
}
|
|
50
|
+
],
|
|
51
|
+
failed: []
|
|
52
|
+
});
|
|
53
|
+
const result = await moduleUnderTest.catalogAdminBatchHandler({
|
|
54
|
+
profileId: "profile-1",
|
|
55
|
+
mode: "apply",
|
|
56
|
+
requestedRiskLevel: "medium",
|
|
57
|
+
operations: [
|
|
58
|
+
{
|
|
59
|
+
type: "update_product_basic_fields",
|
|
60
|
+
productId: "10",
|
|
61
|
+
updates: { name: "Updated" }
|
|
62
|
+
}
|
|
63
|
+
]
|
|
64
|
+
});
|
|
65
|
+
expect(planCatalogBatchMock).toHaveBeenCalledWith("profile-1", [
|
|
66
|
+
{
|
|
67
|
+
type: "update_product_basic_fields",
|
|
68
|
+
productId: "10",
|
|
69
|
+
updates: { name: "Updated" }
|
|
70
|
+
}
|
|
71
|
+
]);
|
|
72
|
+
expect(executeCatalogBatchMock).toHaveBeenCalledTimes(1);
|
|
73
|
+
const structured = getStructured(result);
|
|
74
|
+
expect(structured).toMatchObject({
|
|
75
|
+
success: true,
|
|
76
|
+
operation: "catalog_admin_batch",
|
|
77
|
+
requested_risk_level: "medium",
|
|
78
|
+
risk_level: "medium",
|
|
79
|
+
details: {
|
|
80
|
+
mode: "apply",
|
|
81
|
+
execution: {
|
|
82
|
+
successful_count: 1,
|
|
83
|
+
failed_count: 0
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
it("escalates medium-risk requests to high and returns preview token", async () => {
|
|
89
|
+
planCatalogBatchMock.mockResolvedValue({
|
|
90
|
+
preflight: {
|
|
91
|
+
entities: 12,
|
|
92
|
+
entityTypes: ["product"],
|
|
93
|
+
destructive: false,
|
|
94
|
+
hasDeleteOrReplaceAll: false,
|
|
95
|
+
dependencyFailureCount: 0,
|
|
96
|
+
multiEntityCriticalReassignment: false
|
|
97
|
+
},
|
|
98
|
+
warnings: [],
|
|
99
|
+
impactedEntityTypes: ["product"],
|
|
100
|
+
before: [],
|
|
101
|
+
after: []
|
|
102
|
+
});
|
|
103
|
+
const result = await moduleUnderTest.catalogAdminBatchHandler({
|
|
104
|
+
profileId: "profile-1",
|
|
105
|
+
mode: "preview",
|
|
106
|
+
requestedRiskLevel: "medium",
|
|
107
|
+
operations: [
|
|
108
|
+
{
|
|
109
|
+
type: "update_product_basic_fields",
|
|
110
|
+
productId: "10",
|
|
111
|
+
updates: { name: "Updated" }
|
|
112
|
+
}
|
|
113
|
+
]
|
|
114
|
+
});
|
|
115
|
+
expect(executeCatalogBatchMock).not.toHaveBeenCalled();
|
|
116
|
+
const structured = getStructured(result);
|
|
117
|
+
expect(structured).toMatchObject({
|
|
118
|
+
success: true,
|
|
119
|
+
operation: "catalog_admin_batch",
|
|
120
|
+
requested_risk_level: "medium",
|
|
121
|
+
risk_level: "high",
|
|
122
|
+
escalated: true
|
|
123
|
+
});
|
|
124
|
+
expect(structured.confirmation_requirements).toMatchObject({ required: true });
|
|
125
|
+
expect(structured.details?.preview_id).toEqual(
|
|
126
|
+
expect.any(String)
|
|
127
|
+
);
|
|
128
|
+
});
|
|
129
|
+
it("blocks high-risk apply without preview id and explicit confirmation", async () => {
|
|
130
|
+
planCatalogBatchMock.mockResolvedValue({
|
|
131
|
+
preflight: {
|
|
132
|
+
entities: 1,
|
|
133
|
+
entityTypes: ["sku"],
|
|
134
|
+
destructive: true,
|
|
135
|
+
hasDeleteOrReplaceAll: true,
|
|
136
|
+
dependencyFailureCount: 0,
|
|
137
|
+
multiEntityCriticalReassignment: false
|
|
138
|
+
},
|
|
139
|
+
warnings: ["destructive_operation_detected"],
|
|
140
|
+
impactedEntityTypes: ["sku"],
|
|
141
|
+
before: [],
|
|
142
|
+
after: []
|
|
143
|
+
});
|
|
144
|
+
const missingPreviewIdResult = await moduleUnderTest.catalogAdminBatchHandler({
|
|
145
|
+
profileId: "profile-1",
|
|
146
|
+
mode: "apply",
|
|
147
|
+
requestedRiskLevel: "high",
|
|
148
|
+
operations: [
|
|
149
|
+
{
|
|
150
|
+
type: "replace_sku_eans",
|
|
151
|
+
skuId: "22",
|
|
152
|
+
eans: ["7790011223344"]
|
|
153
|
+
}
|
|
154
|
+
],
|
|
155
|
+
confirmed: true
|
|
156
|
+
});
|
|
157
|
+
expect(getStructured(missingPreviewIdResult)).toMatchObject({
|
|
158
|
+
success: false,
|
|
159
|
+
error_code: "INVALID_OPERATION"
|
|
160
|
+
});
|
|
161
|
+
const expectedPreviewId = getStructured(missingPreviewIdResult).details?.expected_preview_id;
|
|
162
|
+
const missingConfirmationResult = await moduleUnderTest.catalogAdminBatchHandler({
|
|
163
|
+
profileId: "profile-1",
|
|
164
|
+
mode: "apply",
|
|
165
|
+
requestedRiskLevel: "high",
|
|
166
|
+
previewId: expectedPreviewId,
|
|
167
|
+
operations: [
|
|
168
|
+
{
|
|
169
|
+
type: "replace_sku_eans",
|
|
170
|
+
skuId: "22",
|
|
171
|
+
eans: ["7790011223344"]
|
|
172
|
+
}
|
|
173
|
+
]
|
|
174
|
+
});
|
|
175
|
+
expect(getStructured(missingConfirmationResult)).toMatchObject({
|
|
176
|
+
success: false,
|
|
177
|
+
error_code: "EXPLICIT_CONFIRMATION_REQUIRED"
|
|
178
|
+
});
|
|
179
|
+
expect(executeCatalogBatchMock).not.toHaveBeenCalled();
|
|
180
|
+
});
|
|
181
|
+
it("adds partial-failure warnings when apply has failed operations", async () => {
|
|
182
|
+
planCatalogBatchMock.mockResolvedValue({
|
|
183
|
+
preflight: {
|
|
184
|
+
entities: 1,
|
|
185
|
+
entityTypes: ["sku"],
|
|
186
|
+
destructive: false,
|
|
187
|
+
hasDeleteOrReplaceAll: false,
|
|
188
|
+
dependencyFailureCount: 0,
|
|
189
|
+
multiEntityCriticalReassignment: false
|
|
190
|
+
},
|
|
191
|
+
warnings: [],
|
|
192
|
+
impactedEntityTypes: ["sku"],
|
|
193
|
+
before: [],
|
|
194
|
+
after: []
|
|
195
|
+
});
|
|
196
|
+
executeCatalogBatchMock.mockResolvedValue({
|
|
197
|
+
successful: [],
|
|
198
|
+
failed: [
|
|
199
|
+
{
|
|
200
|
+
operation_index: 0,
|
|
201
|
+
operation_type: "update_sku_basic_fields",
|
|
202
|
+
resource_id: "22",
|
|
203
|
+
message: "VTEX timeout"
|
|
204
|
+
}
|
|
205
|
+
]
|
|
206
|
+
});
|
|
207
|
+
const result = await moduleUnderTest.catalogAdminBatchHandler({
|
|
208
|
+
profileId: "profile-1",
|
|
209
|
+
mode: "apply",
|
|
210
|
+
requestedRiskLevel: "medium",
|
|
211
|
+
operations: [
|
|
212
|
+
{
|
|
213
|
+
type: "update_sku_basic_fields",
|
|
214
|
+
skuId: "22",
|
|
215
|
+
updates: { name: "SKU v2" }
|
|
216
|
+
}
|
|
217
|
+
]
|
|
218
|
+
});
|
|
219
|
+
const structured = getStructured(result);
|
|
220
|
+
expect(structured).toMatchObject({
|
|
221
|
+
success: true,
|
|
222
|
+
warnings: expect.arrayContaining(["partial_failures_detected"]),
|
|
223
|
+
details: {
|
|
224
|
+
mode: "apply",
|
|
225
|
+
execution: {
|
|
226
|
+
successful_count: 0,
|
|
227
|
+
failed_count: 1
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
});
|
|
233
|
+
//# sourceMappingURL=catalog-admin-batch.test.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/tools/vtex/__tests__/catalog-admin-batch.test.ts"],
|
|
4
|
+
"sourcesContent": ["import { beforeEach, describe, expect, it, vi } from \"vitest\";\n\nconst resolveVtexProfileOrSelectionMock = vi.fn();\n\nconst planCatalogBatchMock = vi.fn();\nconst executeCatalogBatchMock = vi.fn();\n\nvi.mock(\"../profile-resolution.js\", () => ({\n resolveVtexProfileOrSelection: resolveVtexProfileOrSelectionMock,\n}));\n\nvi.mock(\"../../../services/vtex/vtex-catalog-write.js\", () => ({\n planCatalogBatch: planCatalogBatchMock,\n executeCatalogBatch: executeCatalogBatchMock,\n}));\n\nconst moduleUnderTest = await import(\"../catalog-admin-batch.js\");\n\nfunction getStructured(result: unknown): Record<string, unknown> {\n if (result && typeof result === \"object\" && \"structuredContent\" in result) {\n return (result as { structuredContent: Record<string, unknown> }).structuredContent;\n }\n\n return result as Record<string, unknown>;\n}\n\ndescribe(\"catalog-admin-batch\", () => {\n beforeEach(() => {\n vi.clearAllMocks();\n resolveVtexProfileOrSelectionMock.mockResolvedValue({\n ok: true,\n value: { profileId: \"profile-1\" },\n });\n });\n\n it(\"auto-applies medium-risk batch after safe preflight\", async () => {\n planCatalogBatchMock.mockResolvedValue({\n preflight: {\n entities: 2,\n entityTypes: [\"product\", \"sku\"],\n destructive: false,\n hasDeleteOrReplaceAll: false,\n dependencyFailureCount: 0,\n multiEntityCriticalReassignment: false,\n },\n warnings: [],\n impactedEntityTypes: [\"product\", \"sku\"],\n before: [{ operation_index: 0, snapshot: { id: \"10\" } }],\n after: [{ operation_index: 0, snapshot: { id: \"10\", updated: true } }],\n });\n\n executeCatalogBatchMock.mockResolvedValue({\n successful: [\n {\n operation_index: 0,\n operation_type: \"update_product_basic_fields\",\n resource_id: \"10\",\n result: { ok: true },\n },\n ],\n failed: [],\n });\n\n const result = await moduleUnderTest.catalogAdminBatchHandler({\n profileId: \"profile-1\",\n mode: \"apply\",\n requestedRiskLevel: \"medium\",\n operations: [\n {\n type: \"update_product_basic_fields\",\n productId: \"10\",\n updates: { name: \"Updated\" },\n },\n ],\n });\n\n expect(planCatalogBatchMock).toHaveBeenCalledWith(\"profile-1\", [\n {\n type: \"update_product_basic_fields\",\n productId: \"10\",\n updates: { name: \"Updated\" },\n },\n ]);\n expect(executeCatalogBatchMock).toHaveBeenCalledTimes(1);\n const structured = getStructured(result);\n\n expect(structured).toMatchObject({\n success: true,\n operation: \"catalog_admin_batch\",\n requested_risk_level: \"medium\",\n risk_level: \"medium\",\n details: {\n mode: \"apply\",\n execution: {\n successful_count: 1,\n failed_count: 0,\n },\n },\n });\n });\n\n it(\"escalates medium-risk requests to high and returns preview token\", async () => {\n planCatalogBatchMock.mockResolvedValue({\n preflight: {\n entities: 12,\n entityTypes: [\"product\"],\n destructive: false,\n hasDeleteOrReplaceAll: false,\n dependencyFailureCount: 0,\n multiEntityCriticalReassignment: false,\n },\n warnings: [],\n impactedEntityTypes: [\"product\"],\n before: [],\n after: [],\n });\n\n const result = await moduleUnderTest.catalogAdminBatchHandler({\n profileId: \"profile-1\",\n mode: \"preview\",\n requestedRiskLevel: \"medium\",\n operations: [\n {\n type: \"update_product_basic_fields\",\n productId: \"10\",\n updates: { name: \"Updated\" },\n },\n ],\n });\n\n expect(executeCatalogBatchMock).not.toHaveBeenCalled();\n const structured = getStructured(result);\n\n expect(structured).toMatchObject({\n success: true,\n operation: \"catalog_admin_batch\",\n requested_risk_level: \"medium\",\n risk_level: \"high\",\n escalated: true,\n });\n expect(structured.confirmation_requirements).toMatchObject({ required: true });\n expect((structured.details as { preview_id?: string } | undefined)?.preview_id).toEqual(\n expect.any(String)\n );\n });\n\n it(\"blocks high-risk apply without preview id and explicit confirmation\", async () => {\n planCatalogBatchMock.mockResolvedValue({\n preflight: {\n entities: 1,\n entityTypes: [\"sku\"],\n destructive: true,\n hasDeleteOrReplaceAll: true,\n dependencyFailureCount: 0,\n multiEntityCriticalReassignment: false,\n },\n warnings: [\"destructive_operation_detected\"],\n impactedEntityTypes: [\"sku\"],\n before: [],\n after: [],\n });\n\n const missingPreviewIdResult = await moduleUnderTest.catalogAdminBatchHandler({\n profileId: \"profile-1\",\n mode: \"apply\",\n requestedRiskLevel: \"high\",\n operations: [\n {\n type: \"replace_sku_eans\",\n skuId: \"22\",\n eans: [\"7790011223344\"],\n },\n ],\n confirmed: true,\n });\n\n expect(getStructured(missingPreviewIdResult)).toMatchObject({\n success: false,\n error_code: \"INVALID_OPERATION\",\n });\n\n const expectedPreviewId = (\n getStructured(missingPreviewIdResult).details as { expected_preview_id?: string } | undefined\n )?.expected_preview_id;\n\n const missingConfirmationResult = await moduleUnderTest.catalogAdminBatchHandler({\n profileId: \"profile-1\",\n mode: \"apply\",\n requestedRiskLevel: \"high\",\n previewId: expectedPreviewId,\n operations: [\n {\n type: \"replace_sku_eans\",\n skuId: \"22\",\n eans: [\"7790011223344\"],\n },\n ],\n });\n\n expect(getStructured(missingConfirmationResult)).toMatchObject({\n success: false,\n error_code: \"EXPLICIT_CONFIRMATION_REQUIRED\",\n });\n expect(executeCatalogBatchMock).not.toHaveBeenCalled();\n });\n\n it(\"adds partial-failure warnings when apply has failed operations\", async () => {\n planCatalogBatchMock.mockResolvedValue({\n preflight: {\n entities: 1,\n entityTypes: [\"sku\"],\n destructive: false,\n hasDeleteOrReplaceAll: false,\n dependencyFailureCount: 0,\n multiEntityCriticalReassignment: false,\n },\n warnings: [],\n impactedEntityTypes: [\"sku\"],\n before: [],\n after: [],\n });\n\n executeCatalogBatchMock.mockResolvedValue({\n successful: [],\n failed: [\n {\n operation_index: 0,\n operation_type: \"update_sku_basic_fields\",\n resource_id: \"22\",\n message: \"VTEX timeout\",\n },\n ],\n });\n\n const result = await moduleUnderTest.catalogAdminBatchHandler({\n profileId: \"profile-1\",\n mode: \"apply\",\n requestedRiskLevel: \"medium\",\n operations: [\n {\n type: \"update_sku_basic_fields\",\n skuId: \"22\",\n updates: { name: \"SKU v2\" },\n },\n ],\n });\n\n const structured = getStructured(result);\n\n expect(structured).toMatchObject({\n success: true,\n warnings: expect.arrayContaining([\"partial_failures_detected\"]),\n details: {\n mode: \"apply\",\n execution: {\n successful_count: 0,\n failed_count: 1,\n },\n },\n });\n });\n});\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,YAAY,UAAU,QAAQ,IAAI,UAAU;AAErD,MAAM,oCAAoC,GAAG,GAAG;AAEhD,MAAM,uBAAuB,GAAG,GAAG;AACnC,MAAM,0BAA0B,GAAG,GAAG;AAEtC,GAAG,KAAK,4BAA4B,OAAO;AAAA,EACzC,+BAA+B;AACjC,EAAE;AAEF,GAAG,KAAK,gDAAgD,OAAO;AAAA,EAC7D,kBAAkB;AAAA,EAClB,qBAAqB;AACvB,EAAE;AAEF,MAAM,kBAAkB,MAAM,OAAO,2BAA2B;AAEhE,SAAS,cAAc,QAA0C;AAC/D,MAAI,UAAU,OAAO,WAAW,YAAY,uBAAuB,QAAQ;AACzE,WAAQ,OAA0D;AAAA,EACpE;AAEA,SAAO;AACT;AAEA,SAAS,uBAAuB,MAAM;AACpC,aAAW,MAAM;AACf,OAAG,cAAc;AACjB,sCAAkC,kBAAkB;AAAA,MAClD,IAAI;AAAA,MACJ,OAAO,EAAE,WAAW,YAAY;AAAA,IAClC,CAAC;AAAA,EACH,CAAC;AAED,KAAG,uDAAuD,YAAY;AACpE,yBAAqB,kBAAkB;AAAA,MACrC,WAAW;AAAA,QACT,UAAU;AAAA,QACV,aAAa,CAAC,WAAW,KAAK;AAAA,QAC9B,aAAa;AAAA,QACb,uBAAuB;AAAA,QACvB,wBAAwB;AAAA,QACxB,iCAAiC;AAAA,MACnC;AAAA,MACA,UAAU,CAAC;AAAA,MACX,qBAAqB,CAAC,WAAW,KAAK;AAAA,MACtC,QAAQ,CAAC,EAAE,iBAAiB,GAAG,UAAU,EAAE,IAAI,KAAK,EAAE,CAAC;AAAA,MACvD,OAAO,CAAC,EAAE,iBAAiB,GAAG,UAAU,EAAE,IAAI,MAAM,SAAS,KAAK,EAAE,CAAC;AAAA,IACvE,CAAC;AAED,4BAAwB,kBAAkB;AAAA,MACxC,YAAY;AAAA,QACV;AAAA,UACE,iBAAiB;AAAA,UACjB,gBAAgB;AAAA,UAChB,aAAa;AAAA,UACb,QAAQ,EAAE,IAAI,KAAK;AAAA,QACrB;AAAA,MACF;AAAA,MACA,QAAQ,CAAC;AAAA,IACX,CAAC;AAED,UAAM,SAAS,MAAM,gBAAgB,yBAAyB;AAAA,MAC5D,WAAW;AAAA,MACX,MAAM;AAAA,MACN,oBAAoB;AAAA,MACpB,YAAY;AAAA,QACV;AAAA,UACE,MAAM;AAAA,UACN,WAAW;AAAA,UACX,SAAS,EAAE,MAAM,UAAU;AAAA,QAC7B;AAAA,MACF;AAAA,IACF,CAAC;AAED,WAAO,oBAAoB,EAAE,qBAAqB,aAAa;AAAA,MAC7D;AAAA,QACE,MAAM;AAAA,QACN,WAAW;AAAA,QACX,SAAS,EAAE,MAAM,UAAU;AAAA,MAC7B;AAAA,IACF,CAAC;AACD,WAAO,uBAAuB,EAAE,sBAAsB,CAAC;AACvD,UAAM,aAAa,cAAc,MAAM;AAEvC,WAAO,UAAU,EAAE,cAAc;AAAA,MAC/B,SAAS;AAAA,MACT,WAAW;AAAA,MACX,sBAAsB;AAAA,MACtB,YAAY;AAAA,MACZ,SAAS;AAAA,QACP,MAAM;AAAA,QACN,WAAW;AAAA,UACT,kBAAkB;AAAA,UAClB,cAAc;AAAA,QAChB;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AAED,KAAG,oEAAoE,YAAY;AACjF,yBAAqB,kBAAkB;AAAA,MACrC,WAAW;AAAA,QACT,UAAU;AAAA,QACV,aAAa,CAAC,SAAS;AAAA,QACvB,aAAa;AAAA,QACb,uBAAuB;AAAA,QACvB,wBAAwB;AAAA,QACxB,iCAAiC;AAAA,MACnC;AAAA,MACA,UAAU,CAAC;AAAA,MACX,qBAAqB,CAAC,SAAS;AAAA,MAC/B,QAAQ,CAAC;AAAA,MACT,OAAO,CAAC;AAAA,IACV,CAAC;AAED,UAAM,SAAS,MAAM,gBAAgB,yBAAyB;AAAA,MAC5D,WAAW;AAAA,MACX,MAAM;AAAA,MACN,oBAAoB;AAAA,MACpB,YAAY;AAAA,QACV;AAAA,UACE,MAAM;AAAA,UACN,WAAW;AAAA,UACX,SAAS,EAAE,MAAM,UAAU;AAAA,QAC7B;AAAA,MACF;AAAA,IACF,CAAC;AAED,WAAO,uBAAuB,EAAE,IAAI,iBAAiB;AACrD,UAAM,aAAa,cAAc,MAAM;AAEvC,WAAO,UAAU,EAAE,cAAc;AAAA,MAC/B,SAAS;AAAA,MACT,WAAW;AAAA,MACX,sBAAsB;AAAA,MACtB,YAAY;AAAA,MACZ,WAAW;AAAA,IACb,CAAC;AACD,WAAO,WAAW,yBAAyB,EAAE,cAAc,EAAE,UAAU,KAAK,CAAC;AAC7E,WAAQ,WAAW,SAAiD,UAAU,EAAE;AAAA,MAC9E,OAAO,IAAI,MAAM;AAAA,IACnB;AAAA,EACF,CAAC;AAED,KAAG,uEAAuE,YAAY;AACpF,yBAAqB,kBAAkB;AAAA,MACrC,WAAW;AAAA,QACT,UAAU;AAAA,QACV,aAAa,CAAC,KAAK;AAAA,QACnB,aAAa;AAAA,QACb,uBAAuB;AAAA,QACvB,wBAAwB;AAAA,QACxB,iCAAiC;AAAA,MACnC;AAAA,MACA,UAAU,CAAC,gCAAgC;AAAA,MAC3C,qBAAqB,CAAC,KAAK;AAAA,MAC3B,QAAQ,CAAC;AAAA,MACT,OAAO,CAAC;AAAA,IACV,CAAC;AAED,UAAM,yBAAyB,MAAM,gBAAgB,yBAAyB;AAAA,MAC5E,WAAW;AAAA,MACX,MAAM;AAAA,MACN,oBAAoB;AAAA,MACpB,YAAY;AAAA,QACV;AAAA,UACE,MAAM;AAAA,UACN,OAAO;AAAA,UACP,MAAM,CAAC,eAAe;AAAA,QACxB;AAAA,MACF;AAAA,MACA,WAAW;AAAA,IACb,CAAC;AAED,WAAO,cAAc,sBAAsB,CAAC,EAAE,cAAc;AAAA,MAC1D,SAAS;AAAA,MACT,YAAY;AAAA,IACd,CAAC;AAED,UAAM,oBACJ,cAAc,sBAAsB,EAAE,SACrC;AAEH,UAAM,4BAA4B,MAAM,gBAAgB,yBAAyB;AAAA,MAC/E,WAAW;AAAA,MACX,MAAM;AAAA,MACN,oBAAoB;AAAA,MACpB,WAAW;AAAA,MACX,YAAY;AAAA,QACV;AAAA,UACE,MAAM;AAAA,UACN,OAAO;AAAA,UACP,MAAM,CAAC,eAAe;AAAA,QACxB;AAAA,MACF;AAAA,IACF,CAAC;AAED,WAAO,cAAc,yBAAyB,CAAC,EAAE,cAAc;AAAA,MAC7D,SAAS;AAAA,MACT,YAAY;AAAA,IACd,CAAC;AACD,WAAO,uBAAuB,EAAE,IAAI,iBAAiB;AAAA,EACvD,CAAC;AAED,KAAG,kEAAkE,YAAY;AAC/E,yBAAqB,kBAAkB;AAAA,MACrC,WAAW;AAAA,QACT,UAAU;AAAA,QACV,aAAa,CAAC,KAAK;AAAA,QACnB,aAAa;AAAA,QACb,uBAAuB;AAAA,QACvB,wBAAwB;AAAA,QACxB,iCAAiC;AAAA,MACnC;AAAA,MACA,UAAU,CAAC;AAAA,MACX,qBAAqB,CAAC,KAAK;AAAA,MAC3B,QAAQ,CAAC;AAAA,MACT,OAAO,CAAC;AAAA,IACV,CAAC;AAED,4BAAwB,kBAAkB;AAAA,MACxC,YAAY,CAAC;AAAA,MACb,QAAQ;AAAA,QACN;AAAA,UACE,iBAAiB;AAAA,UACjB,gBAAgB;AAAA,UAChB,aAAa;AAAA,UACb,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF,CAAC;AAED,UAAM,SAAS,MAAM,gBAAgB,yBAAyB;AAAA,MAC5D,WAAW;AAAA,MACX,MAAM;AAAA,MACN,oBAAoB;AAAA,MACpB,YAAY;AAAA,QACV;AAAA,UACE,MAAM;AAAA,UACN,OAAO;AAAA,UACP,SAAS,EAAE,MAAM,SAAS;AAAA,QAC5B;AAAA,MACF;AAAA,IACF,CAAC;AAED,UAAM,aAAa,cAAc,MAAM;AAEvC,WAAO,UAAU,EAAE,cAAc;AAAA,MAC/B,SAAS;AAAA,MACT,UAAU,OAAO,gBAAgB,CAAC,2BAA2B,CAAC;AAAA,MAC9D,SAAS;AAAA,QACP,MAAM;AAAA,QACN,WAAW;AAAA,UACT,kBAAkB;AAAA,UAClB,cAAc;AAAA,QAChB;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AACH,CAAC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
import { object } from "mcp-use/server";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import {
|
|
4
|
+
executeCatalogBatch,
|
|
5
|
+
planCatalogBatch
|
|
6
|
+
} from "../../services/vtex/vtex-catalog-write.js";
|
|
7
|
+
import {
|
|
8
|
+
classifyVtexWriteRisk,
|
|
9
|
+
getPreviewRequirements
|
|
10
|
+
} from "../../services/vtex/vtex-write.js";
|
|
11
|
+
import {
|
|
12
|
+
buildBatchExecutionWarnings,
|
|
13
|
+
buildPreflightSummary,
|
|
14
|
+
buildPreviewResponse,
|
|
15
|
+
buildWriteSuccessResponse,
|
|
16
|
+
confirmationNoteSchemaField,
|
|
17
|
+
confirmationSchemaField,
|
|
18
|
+
createBatchPreviewId,
|
|
19
|
+
createBatchPreviewToken,
|
|
20
|
+
decodeBatchPreviewToken,
|
|
21
|
+
handleVtexWriteError,
|
|
22
|
+
requireExplicitConfirmation,
|
|
23
|
+
resolveVtexWriteProfile,
|
|
24
|
+
vtexProfileIdSchemaField
|
|
25
|
+
} from "./write-helpers.js";
|
|
26
|
+
const updateProductOperationSchema = z.object({
|
|
27
|
+
type: z.literal("update_product_basic_fields"),
|
|
28
|
+
productId: z.string().trim().min(1).describe("VTEX product identifier."),
|
|
29
|
+
updates: z.object({
|
|
30
|
+
name: z.string().optional(),
|
|
31
|
+
categoryId: z.number().int().positive().optional(),
|
|
32
|
+
brandId: z.number().int().positive().optional(),
|
|
33
|
+
description: z.string().optional(),
|
|
34
|
+
descriptionShort: z.string().optional(),
|
|
35
|
+
title: z.string().optional(),
|
|
36
|
+
linkId: z.string().optional(),
|
|
37
|
+
refId: z.string().optional(),
|
|
38
|
+
isVisible: z.boolean().optional(),
|
|
39
|
+
isActive: z.boolean().optional(),
|
|
40
|
+
keyWords: z.string().optional(),
|
|
41
|
+
releaseDate: z.string().optional(),
|
|
42
|
+
metaTagDescription: z.string().optional(),
|
|
43
|
+
showWithoutStock: z.boolean().optional()
|
|
44
|
+
}).refine((value) => Object.values(value).some((entry) => entry !== void 0), {
|
|
45
|
+
message: "At least one product field must be provided."
|
|
46
|
+
})
|
|
47
|
+
});
|
|
48
|
+
const updateSkuOperationSchema = z.object({
|
|
49
|
+
type: z.literal("update_sku_basic_fields"),
|
|
50
|
+
skuId: z.string().trim().min(1).describe("VTEX SKU identifier."),
|
|
51
|
+
updates: z.object({
|
|
52
|
+
name: z.string().optional(),
|
|
53
|
+
refId: z.string().optional(),
|
|
54
|
+
ean: z.string().optional(),
|
|
55
|
+
packagedHeight: z.number().nonnegative().optional(),
|
|
56
|
+
packagedLength: z.number().nonnegative().optional(),
|
|
57
|
+
packagedWidth: z.number().nonnegative().optional(),
|
|
58
|
+
packagedWeightKg: z.number().nonnegative().optional(),
|
|
59
|
+
height: z.number().nonnegative().optional(),
|
|
60
|
+
length: z.number().nonnegative().optional(),
|
|
61
|
+
width: z.number().nonnegative().optional(),
|
|
62
|
+
weightKg: z.number().nonnegative().optional(),
|
|
63
|
+
measurementUnit: z.string().optional(),
|
|
64
|
+
unitMultiplier: z.number().positive().optional(),
|
|
65
|
+
manufacturerCode: z.string().optional(),
|
|
66
|
+
commercialConditionId: z.number().int().positive().optional(),
|
|
67
|
+
isActive: z.boolean().optional(),
|
|
68
|
+
activateIfPossible: z.boolean().optional()
|
|
69
|
+
}).refine((value) => Object.values(value).some((entry) => entry !== void 0), {
|
|
70
|
+
message: "At least one SKU field must be provided."
|
|
71
|
+
})
|
|
72
|
+
});
|
|
73
|
+
const replaceSkuEansOperationSchema = z.object({
|
|
74
|
+
type: z.literal("replace_sku_eans"),
|
|
75
|
+
skuId: z.string().trim().min(1).describe("VTEX SKU identifier."),
|
|
76
|
+
eans: z.array(z.string().trim()).describe("Final list of EAN values to keep on the SKU.")
|
|
77
|
+
});
|
|
78
|
+
const catalogAdminBatchSchema = z.object({
|
|
79
|
+
profileId: vtexProfileIdSchemaField,
|
|
80
|
+
mode: z.enum(["preview", "apply"]).default("preview"),
|
|
81
|
+
requestedRiskLevel: z.enum(["medium", "high"]).default("medium").describe("Requested risk level. Medium may escalate to high after preflight."),
|
|
82
|
+
confirmed: confirmationSchemaField,
|
|
83
|
+
confirmationNote: confirmationNoteSchemaField,
|
|
84
|
+
previewId: z.string().trim().min(1).optional().describe("Preview identifier returned by preview mode for high-risk apply."),
|
|
85
|
+
previewToken: z.string().trim().min(1).optional().describe("Opaque preview token returned by preview mode. If provided, apply validates it."),
|
|
86
|
+
operations: z.array(
|
|
87
|
+
z.discriminatedUnion("type", [
|
|
88
|
+
updateProductOperationSchema,
|
|
89
|
+
updateSkuOperationSchema,
|
|
90
|
+
replaceSkuEansOperationSchema
|
|
91
|
+
])
|
|
92
|
+
).min(1).max(50).describe("Catalog write operations to execute in order.")
|
|
93
|
+
});
|
|
94
|
+
function buildInvalidApplyPayload(params) {
|
|
95
|
+
return object({
|
|
96
|
+
success: false,
|
|
97
|
+
error_code: "INVALID_OPERATION",
|
|
98
|
+
message: params.message,
|
|
99
|
+
operation: "catalog_admin_batch",
|
|
100
|
+
risk_level: params.effectiveRiskLevel,
|
|
101
|
+
confirmation_requirements: {
|
|
102
|
+
required: true,
|
|
103
|
+
reason: "explicit_confirmation_required",
|
|
104
|
+
preview_id: params.previewId
|
|
105
|
+
},
|
|
106
|
+
preview_requirements: getPreviewRequirements("high"),
|
|
107
|
+
details: params.details
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
function toBatchOperations(operations) {
|
|
111
|
+
return operations.map((operation) => {
|
|
112
|
+
if (operation.type === "update_product_basic_fields") {
|
|
113
|
+
return {
|
|
114
|
+
type: operation.type,
|
|
115
|
+
productId: operation.productId,
|
|
116
|
+
updates: operation.updates
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
if (operation.type === "update_sku_basic_fields") {
|
|
120
|
+
return {
|
|
121
|
+
type: operation.type,
|
|
122
|
+
skuId: operation.skuId,
|
|
123
|
+
updates: operation.updates
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
return {
|
|
127
|
+
type: operation.type,
|
|
128
|
+
skuId: operation.skuId,
|
|
129
|
+
eans: operation.eans
|
|
130
|
+
};
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
async function catalogAdminBatchHandler({
|
|
134
|
+
profileId,
|
|
135
|
+
mode,
|
|
136
|
+
requestedRiskLevel,
|
|
137
|
+
confirmed,
|
|
138
|
+
confirmationNote,
|
|
139
|
+
previewId,
|
|
140
|
+
previewToken,
|
|
141
|
+
operations
|
|
142
|
+
}) {
|
|
143
|
+
try {
|
|
144
|
+
const profileResolution = await resolveVtexWriteProfile(profileId);
|
|
145
|
+
if (!profileResolution.ok) {
|
|
146
|
+
return profileResolution.response;
|
|
147
|
+
}
|
|
148
|
+
const resolvedProfileId = profileResolution.value.profileId;
|
|
149
|
+
const normalizedOperations = toBatchOperations(operations);
|
|
150
|
+
const plan = await planCatalogBatch(resolvedProfileId, normalizedOperations);
|
|
151
|
+
const preflightSummary = buildPreflightSummary({
|
|
152
|
+
entities: plan.preflight.entities,
|
|
153
|
+
entityTypes: plan.preflight.entityTypes,
|
|
154
|
+
destructive: plan.preflight.destructive,
|
|
155
|
+
warnings: plan.warnings
|
|
156
|
+
});
|
|
157
|
+
const riskEvaluation = classifyVtexWriteRisk({
|
|
158
|
+
requestedRiskLevel,
|
|
159
|
+
preflight: plan.preflight
|
|
160
|
+
});
|
|
161
|
+
const effectiveRiskLevel = riskEvaluation.effective_risk_level;
|
|
162
|
+
const generatedPreviewId = createBatchPreviewId({
|
|
163
|
+
profileId: resolvedProfileId,
|
|
164
|
+
operation: "catalog_admin_batch",
|
|
165
|
+
requestedRiskLevel,
|
|
166
|
+
effectiveRiskLevel,
|
|
167
|
+
operations: normalizedOperations,
|
|
168
|
+
preflight: plan.preflight
|
|
169
|
+
});
|
|
170
|
+
const generatedPreviewToken = createBatchPreviewToken({
|
|
171
|
+
preview_id: generatedPreviewId,
|
|
172
|
+
profile_id: resolvedProfileId,
|
|
173
|
+
operation: "catalog_admin_batch",
|
|
174
|
+
requested_risk_level: requestedRiskLevel,
|
|
175
|
+
effective_risk_level: effectiveRiskLevel,
|
|
176
|
+
escalation_reasons: riskEvaluation.escalation_reasons,
|
|
177
|
+
operation_count: normalizedOperations.length
|
|
178
|
+
});
|
|
179
|
+
if (mode === "preview") {
|
|
180
|
+
return object(
|
|
181
|
+
buildPreviewResponse({
|
|
182
|
+
profileId: resolvedProfileId,
|
|
183
|
+
operation: "catalog_admin_batch",
|
|
184
|
+
requestedRiskLevel,
|
|
185
|
+
riskLevel: effectiveRiskLevel,
|
|
186
|
+
escalated: riskEvaluation.escalated,
|
|
187
|
+
escalationReasons: riskEvaluation.escalation_reasons,
|
|
188
|
+
previewId: generatedPreviewId,
|
|
189
|
+
message: effectiveRiskLevel === "high" ? "High-risk batch preview generated. Confirm explicitly before apply." : "Batch preflight preview generated.",
|
|
190
|
+
before: {
|
|
191
|
+
operations: plan.before
|
|
192
|
+
},
|
|
193
|
+
after: {
|
|
194
|
+
operations: plan.after
|
|
195
|
+
},
|
|
196
|
+
warnings: preflightSummary.warnings,
|
|
197
|
+
details: {
|
|
198
|
+
mode: "preview",
|
|
199
|
+
preview_id: generatedPreviewId,
|
|
200
|
+
preview_token: generatedPreviewToken,
|
|
201
|
+
operation_count: normalizedOperations.length,
|
|
202
|
+
preflight: preflightSummary
|
|
203
|
+
},
|
|
204
|
+
impactSummary: {
|
|
205
|
+
entities: preflightSummary.entities,
|
|
206
|
+
entity_types: plan.impactedEntityTypes,
|
|
207
|
+
destructive: preflightSummary.destructive
|
|
208
|
+
}
|
|
209
|
+
})
|
|
210
|
+
);
|
|
211
|
+
}
|
|
212
|
+
if (effectiveRiskLevel === "high") {
|
|
213
|
+
if (!previewId) {
|
|
214
|
+
return buildInvalidApplyPayload({
|
|
215
|
+
message: "High-risk batch apply requires previewId from preview mode.",
|
|
216
|
+
effectiveRiskLevel,
|
|
217
|
+
details: {
|
|
218
|
+
expected_preview_id: generatedPreviewId
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
if (previewId !== generatedPreviewId) {
|
|
223
|
+
return buildInvalidApplyPayload({
|
|
224
|
+
message: "previewId does not match current batch plan. Regenerate preview before apply.",
|
|
225
|
+
effectiveRiskLevel,
|
|
226
|
+
previewId,
|
|
227
|
+
details: {
|
|
228
|
+
expected_preview_id: generatedPreviewId,
|
|
229
|
+
received_preview_id: previewId
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
if (previewToken) {
|
|
234
|
+
const parsedToken = decodeBatchPreviewToken(previewToken);
|
|
235
|
+
if (!parsedToken || parsedToken.preview_id !== previewId || parsedToken.profile_id !== resolvedProfileId || parsedToken.operation !== "catalog_admin_batch" || parsedToken.operation_count !== normalizedOperations.length) {
|
|
236
|
+
return buildInvalidApplyPayload({
|
|
237
|
+
message: "Invalid previewToken for this batch apply request.",
|
|
238
|
+
effectiveRiskLevel,
|
|
239
|
+
previewId
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
const confirmationResponse = requireExplicitConfirmation(confirmed, "catalog_admin_batch", {
|
|
244
|
+
preview_id: previewId
|
|
245
|
+
});
|
|
246
|
+
if (confirmationResponse) {
|
|
247
|
+
return confirmationResponse;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
const execution = await executeCatalogBatch(resolvedProfileId, normalizedOperations);
|
|
251
|
+
const warnings = buildBatchExecutionWarnings({
|
|
252
|
+
existingWarnings: preflightSummary.warnings,
|
|
253
|
+
successfulCount: execution.successful.length,
|
|
254
|
+
failedCount: execution.failed.length
|
|
255
|
+
});
|
|
256
|
+
return buildWriteSuccessResponse({
|
|
257
|
+
profileId: resolvedProfileId,
|
|
258
|
+
operation: "catalog_admin_batch",
|
|
259
|
+
requestedRiskLevel,
|
|
260
|
+
riskLevel: effectiveRiskLevel,
|
|
261
|
+
escalated: riskEvaluation.escalated,
|
|
262
|
+
escalationReasons: riskEvaluation.escalation_reasons,
|
|
263
|
+
confirmed: effectiveRiskLevel === "high" ? true : void 0,
|
|
264
|
+
confirmationNote,
|
|
265
|
+
message: execution.failed.length > 0 ? "Batch applied with partial failures. Review failed operations before retry." : "Batch applied successfully.",
|
|
266
|
+
before: {
|
|
267
|
+
operations: plan.before
|
|
268
|
+
},
|
|
269
|
+
after: {
|
|
270
|
+
operations: execution.successful
|
|
271
|
+
},
|
|
272
|
+
warnings,
|
|
273
|
+
details: {
|
|
274
|
+
mode: "apply",
|
|
275
|
+
preview_id: generatedPreviewId,
|
|
276
|
+
preview_token: generatedPreviewToken,
|
|
277
|
+
preflight: preflightSummary,
|
|
278
|
+
execution: {
|
|
279
|
+
successful_count: execution.successful.length,
|
|
280
|
+
failed_count: execution.failed.length,
|
|
281
|
+
failures: execution.failed
|
|
282
|
+
}
|
|
283
|
+
},
|
|
284
|
+
impactSummary: {
|
|
285
|
+
entities: preflightSummary.entities,
|
|
286
|
+
entity_types: plan.impactedEntityTypes,
|
|
287
|
+
destructive: preflightSummary.destructive
|
|
288
|
+
}
|
|
289
|
+
});
|
|
290
|
+
} catch (err) {
|
|
291
|
+
return handleVtexWriteError(err, "Failed to execute VTEX catalog admin batch");
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
export {
|
|
295
|
+
catalogAdminBatchHandler,
|
|
296
|
+
catalogAdminBatchSchema
|
|
297
|
+
};
|
|
298
|
+
//# sourceMappingURL=catalog-admin-batch.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/tools/vtex/catalog-admin-batch.ts"],
|
|
4
|
+
"sourcesContent": ["import { object } from \"mcp-use/server\";\nimport { z } from \"zod\";\n\nimport {\n executeCatalogBatch,\n planCatalogBatch,\n type VtexCatalogBatchOperation,\n} from \"../../services/vtex/vtex-catalog-write.js\";\nimport {\n classifyVtexWriteRisk,\n getPreviewRequirements,\n type VtexWriteRiskLevel,\n} from \"../../services/vtex/vtex-write.js\";\nimport {\n buildBatchExecutionWarnings,\n buildPreflightSummary,\n buildPreviewResponse,\n buildWriteSuccessResponse,\n confirmationNoteSchemaField,\n confirmationSchemaField,\n createBatchPreviewId,\n createBatchPreviewToken,\n decodeBatchPreviewToken,\n handleVtexWriteError,\n requireExplicitConfirmation,\n resolveVtexWriteProfile,\n vtexProfileIdSchemaField,\n} from \"./write-helpers.js\";\n\nconst updateProductOperationSchema = z.object({\n type: z.literal(\"update_product_basic_fields\"),\n productId: z.string().trim().min(1).describe(\"VTEX product identifier.\"),\n updates: z\n .object({\n name: z.string().optional(),\n categoryId: z.number().int().positive().optional(),\n brandId: z.number().int().positive().optional(),\n description: z.string().optional(),\n descriptionShort: z.string().optional(),\n title: z.string().optional(),\n linkId: z.string().optional(),\n refId: z.string().optional(),\n isVisible: z.boolean().optional(),\n isActive: z.boolean().optional(),\n keyWords: z.string().optional(),\n releaseDate: z.string().optional(),\n metaTagDescription: z.string().optional(),\n showWithoutStock: z.boolean().optional(),\n })\n .refine((value) => Object.values(value).some((entry) => entry !== undefined), {\n message: \"At least one product field must be provided.\",\n }),\n});\n\nconst updateSkuOperationSchema = z.object({\n type: z.literal(\"update_sku_basic_fields\"),\n skuId: z.string().trim().min(1).describe(\"VTEX SKU identifier.\"),\n updates: z\n .object({\n name: z.string().optional(),\n refId: z.string().optional(),\n ean: z.string().optional(),\n packagedHeight: z.number().nonnegative().optional(),\n packagedLength: z.number().nonnegative().optional(),\n packagedWidth: z.number().nonnegative().optional(),\n packagedWeightKg: z.number().nonnegative().optional(),\n height: z.number().nonnegative().optional(),\n length: z.number().nonnegative().optional(),\n width: z.number().nonnegative().optional(),\n weightKg: z.number().nonnegative().optional(),\n measurementUnit: z.string().optional(),\n unitMultiplier: z.number().positive().optional(),\n manufacturerCode: z.string().optional(),\n commercialConditionId: z.number().int().positive().optional(),\n isActive: z.boolean().optional(),\n activateIfPossible: z.boolean().optional(),\n })\n .refine((value) => Object.values(value).some((entry) => entry !== undefined), {\n message: \"At least one SKU field must be provided.\",\n }),\n});\n\nconst replaceSkuEansOperationSchema = z.object({\n type: z.literal(\"replace_sku_eans\"),\n skuId: z.string().trim().min(1).describe(\"VTEX SKU identifier.\"),\n eans: z.array(z.string().trim()).describe(\"Final list of EAN values to keep on the SKU.\"),\n});\n\nexport const catalogAdminBatchSchema = z.object({\n profileId: vtexProfileIdSchemaField,\n mode: z.enum([\"preview\", \"apply\"]).default(\"preview\"),\n requestedRiskLevel: z\n .enum([\"medium\", \"high\"])\n .default(\"medium\")\n .describe(\"Requested risk level. Medium may escalate to high after preflight.\"),\n confirmed: confirmationSchemaField,\n confirmationNote: confirmationNoteSchemaField,\n previewId: z\n .string()\n .trim()\n .min(1)\n .optional()\n .describe(\"Preview identifier returned by preview mode for high-risk apply.\"),\n previewToken: z\n .string()\n .trim()\n .min(1)\n .optional()\n .describe(\"Opaque preview token returned by preview mode. If provided, apply validates it.\"),\n operations: z\n .array(\n z.discriminatedUnion(\"type\", [\n updateProductOperationSchema,\n updateSkuOperationSchema,\n replaceSkuEansOperationSchema,\n ])\n )\n .min(1)\n .max(50)\n .describe(\"Catalog write operations to execute in order.\"),\n});\n\nfunction buildInvalidApplyPayload(params: {\n message: string;\n effectiveRiskLevel: VtexWriteRiskLevel;\n previewId?: string;\n details?: Record<string, unknown>;\n}) {\n return object({\n success: false,\n error_code: \"INVALID_OPERATION\",\n message: params.message,\n operation: \"catalog_admin_batch\",\n risk_level: params.effectiveRiskLevel,\n confirmation_requirements: {\n required: true,\n reason: \"explicit_confirmation_required\",\n preview_id: params.previewId,\n },\n preview_requirements: getPreviewRequirements(\"high\"),\n details: params.details,\n });\n}\n\nfunction toBatchOperations(operations: z.infer<typeof catalogAdminBatchSchema>[\"operations\"]): VtexCatalogBatchOperation[] {\n return operations.map((operation) => {\n if (operation.type === \"update_product_basic_fields\") {\n return {\n type: operation.type,\n productId: operation.productId,\n updates: operation.updates,\n } as const;\n }\n\n if (operation.type === \"update_sku_basic_fields\") {\n return {\n type: operation.type,\n skuId: operation.skuId,\n updates: operation.updates,\n } as const;\n }\n\n return {\n type: operation.type,\n skuId: operation.skuId,\n eans: operation.eans,\n } as const;\n });\n}\n\nexport async function catalogAdminBatchHandler({\n profileId,\n mode,\n requestedRiskLevel,\n confirmed,\n confirmationNote,\n previewId,\n previewToken,\n operations,\n}: z.infer<typeof catalogAdminBatchSchema>) {\n try {\n const profileResolution = await resolveVtexWriteProfile(profileId);\n if (!profileResolution.ok) {\n return profileResolution.response;\n }\n\n const resolvedProfileId = profileResolution.value.profileId;\n const normalizedOperations = toBatchOperations(operations);\n const plan = await planCatalogBatch(resolvedProfileId, normalizedOperations);\n\n const preflightSummary = buildPreflightSummary({\n entities: plan.preflight.entities,\n entityTypes: plan.preflight.entityTypes,\n destructive: plan.preflight.destructive,\n warnings: plan.warnings,\n });\n\n const riskEvaluation = classifyVtexWriteRisk({\n requestedRiskLevel,\n preflight: plan.preflight,\n });\n\n const effectiveRiskLevel = riskEvaluation.effective_risk_level;\n const generatedPreviewId = createBatchPreviewId({\n profileId: resolvedProfileId,\n operation: \"catalog_admin_batch\",\n requestedRiskLevel,\n effectiveRiskLevel,\n operations: normalizedOperations,\n preflight: plan.preflight,\n });\n\n const generatedPreviewToken = createBatchPreviewToken({\n preview_id: generatedPreviewId,\n profile_id: resolvedProfileId,\n operation: \"catalog_admin_batch\",\n requested_risk_level: requestedRiskLevel,\n effective_risk_level: effectiveRiskLevel,\n escalation_reasons: riskEvaluation.escalation_reasons,\n operation_count: normalizedOperations.length,\n });\n\n if (mode === \"preview\") {\n return object(\n buildPreviewResponse({\n profileId: resolvedProfileId,\n operation: \"catalog_admin_batch\",\n requestedRiskLevel,\n riskLevel: effectiveRiskLevel,\n escalated: riskEvaluation.escalated,\n escalationReasons: riskEvaluation.escalation_reasons,\n previewId: generatedPreviewId,\n message:\n effectiveRiskLevel === \"high\"\n ? \"High-risk batch preview generated. Confirm explicitly before apply.\"\n : \"Batch preflight preview generated.\",\n before: {\n operations: plan.before,\n },\n after: {\n operations: plan.after,\n },\n warnings: preflightSummary.warnings,\n details: {\n mode: \"preview\",\n preview_id: generatedPreviewId,\n preview_token: generatedPreviewToken,\n operation_count: normalizedOperations.length,\n preflight: preflightSummary,\n },\n impactSummary: {\n entities: preflightSummary.entities,\n entity_types: plan.impactedEntityTypes,\n destructive: preflightSummary.destructive,\n },\n })\n );\n }\n\n if (effectiveRiskLevel === \"high\") {\n if (!previewId) {\n return buildInvalidApplyPayload({\n message: \"High-risk batch apply requires previewId from preview mode.\",\n effectiveRiskLevel,\n details: {\n expected_preview_id: generatedPreviewId,\n },\n });\n }\n\n if (previewId !== generatedPreviewId) {\n return buildInvalidApplyPayload({\n message: \"previewId does not match current batch plan. Regenerate preview before apply.\",\n effectiveRiskLevel,\n previewId,\n details: {\n expected_preview_id: generatedPreviewId,\n received_preview_id: previewId,\n },\n });\n }\n\n if (previewToken) {\n const parsedToken = decodeBatchPreviewToken(previewToken);\n if (\n !parsedToken ||\n parsedToken.preview_id !== previewId ||\n parsedToken.profile_id !== resolvedProfileId ||\n parsedToken.operation !== \"catalog_admin_batch\" ||\n parsedToken.operation_count !== normalizedOperations.length\n ) {\n return buildInvalidApplyPayload({\n message: \"Invalid previewToken for this batch apply request.\",\n effectiveRiskLevel,\n previewId,\n });\n }\n }\n\n const confirmationResponse = requireExplicitConfirmation(confirmed, \"catalog_admin_batch\", {\n preview_id: previewId,\n });\n\n if (confirmationResponse) {\n return confirmationResponse;\n }\n }\n\n const execution = await executeCatalogBatch(resolvedProfileId, normalizedOperations);\n const warnings = buildBatchExecutionWarnings({\n existingWarnings: preflightSummary.warnings,\n successfulCount: execution.successful.length,\n failedCount: execution.failed.length,\n });\n\n return buildWriteSuccessResponse({\n profileId: resolvedProfileId,\n operation: \"catalog_admin_batch\",\n requestedRiskLevel,\n riskLevel: effectiveRiskLevel,\n escalated: riskEvaluation.escalated,\n escalationReasons: riskEvaluation.escalation_reasons,\n confirmed: effectiveRiskLevel === \"high\" ? true : undefined,\n confirmationNote,\n message:\n execution.failed.length > 0\n ? \"Batch applied with partial failures. Review failed operations before retry.\"\n : \"Batch applied successfully.\",\n before: {\n operations: plan.before,\n },\n after: {\n operations: execution.successful,\n },\n warnings,\n details: {\n mode: \"apply\",\n preview_id: generatedPreviewId,\n preview_token: generatedPreviewToken,\n preflight: preflightSummary,\n execution: {\n successful_count: execution.successful.length,\n failed_count: execution.failed.length,\n failures: execution.failed,\n },\n },\n impactSummary: {\n entities: preflightSummary.entities,\n entity_types: plan.impactedEntityTypes,\n destructive: preflightSummary.destructive,\n },\n });\n } catch (err) {\n return handleVtexWriteError(err, \"Failed to execute VTEX catalog admin batch\");\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|