@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.
Files changed (53) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/mcp-use.json +6 -3
  3. package/dist/scripts/profile-mercadolibre-billing.js +634 -0
  4. package/dist/scripts/profile-mercadolibre-billing.js.map +7 -0
  5. package/dist/src/config/__tests__/tiendanube-profile-store.test.js +50 -0
  6. package/dist/src/config/__tests__/tiendanube-profile-store.test.js.map +7 -0
  7. package/dist/src/config/tiendanube-profile-store.js +31 -0
  8. package/dist/src/config/tiendanube-profile-store.js.map +7 -0
  9. package/dist/src/google-ads/report-utils.js +78 -0
  10. package/dist/src/google-ads/report-utils.js.map +7 -0
  11. package/dist/src/search-console/search-console-utils.js +275 -0
  12. package/dist/src/search-console/search-console-utils.js.map +7 -0
  13. package/dist/src/services/mercadolibre/__tests__/mercadolibre-sales-report-ventas.test.js +358 -0
  14. package/dist/src/services/mercadolibre/__tests__/mercadolibre-sales-report-ventas.test.js.map +7 -0
  15. package/dist/src/services/mercadolibre/__tests__/mercadolibre-sales-report.test.js +96 -0
  16. package/dist/src/services/mercadolibre/__tests__/mercadolibre-sales-report.test.js.map +7 -0
  17. package/dist/src/services/mercadolibre/mercadolibre-claim-return-lookup.js +15 -0
  18. package/dist/src/services/mercadolibre/mercadolibre-claim-return-lookup.js.map +7 -0
  19. package/dist/src/services/mercadolibre/mercadolibre-observability.js +12 -0
  20. package/dist/src/services/mercadolibre/mercadolibre-observability.js.map +7 -0
  21. package/dist/src/services/mercadolibre/mercadolibre-sale-reference.js +7 -0
  22. package/dist/src/services/mercadolibre/mercadolibre-sale-reference.js.map +7 -0
  23. package/dist/src/services/mercadolibre/mercadolibre-sales-report.js +553 -0
  24. package/dist/src/services/mercadolibre/mercadolibre-sales-report.js.map +7 -0
  25. package/dist/src/services/vtex/__tests__/vtex-catalog-write-batch.test.js +165 -0
  26. package/dist/src/services/vtex/__tests__/vtex-catalog-write-batch.test.js.map +7 -0
  27. package/dist/src/tools/config/__tests__/list-profiles.test.js +144 -1
  28. package/dist/src/tools/config/__tests__/list-profiles.test.js.map +2 -2
  29. package/dist/src/tools/config/list-profiles.js +50 -6
  30. package/dist/src/tools/config/list-profiles.js.map +2 -2
  31. package/dist/src/tools/mercadolibre/__tests__/get-sales-report-foundation.test.js +417 -0
  32. package/dist/src/tools/mercadolibre/__tests__/get-sales-report-foundation.test.js.map +7 -0
  33. package/dist/src/tools/mercadolibre/get-sales-report.js +474 -0
  34. package/dist/src/tools/mercadolibre/get-sales-report.js.map +7 -0
  35. package/dist/src/tools/vtex/__tests__/catalog-admin-batch.test.js +233 -0
  36. package/dist/src/tools/vtex/__tests__/catalog-admin-batch.test.js.map +7 -0
  37. package/dist/src/tools/vtex/catalog-admin-batch.js +298 -0
  38. package/dist/src/tools/vtex/catalog-admin-batch.js.map +7 -0
  39. package/dist/tests/meli/meli-sales-report-buyers-mcp-e2e.test.js +137 -0
  40. package/dist/tests/meli/meli-sales-report-buyers-mcp-e2e.test.js.map +7 -0
  41. package/dist/tests/meli/meli-sales-report-mcp-e2e-server.js +24 -0
  42. package/dist/tests/meli/meli-sales-report-mcp-e2e-server.js.map +7 -0
  43. package/dist/tests/meli/meli-sales-report-mcp-e2e.test.js +207 -0
  44. package/dist/tests/meli/meli-sales-report-mcp-e2e.test.js.map +7 -0
  45. package/dist/tests/meli/meli-sales-report-public-mcp-e2e-server.js +10 -0
  46. package/dist/tests/meli/meli-sales-report-public-mcp-e2e-server.js.map +7 -0
  47. package/dist/tests/meli/meli-sales-report-public-registration.test.js +98 -0
  48. package/dist/tests/meli/meli-sales-report-public-registration.test.js.map +7 -0
  49. package/dist/tests/smoke/process-harness.js +89 -0
  50. package/dist/tests/smoke/process-harness.js.map +7 -0
  51. package/dist/tests/smoke/process-harness.test.js +39 -0
  52. package/dist/tests/smoke/process-harness.test.js.map +7 -0
  53. package/package.json +1 -1
@@ -8,6 +8,9 @@ import {
8
8
  import { listMercadoLibreConnections } from "../../config/mercadolibre-profile-store.js";
9
9
  import { listProfileMetaMappings } from "../../config/meta-store.js";
10
10
  import { listProfiles } from "../../config/profile-store.js";
11
+ import {
12
+ listTiendanubeConnections
13
+ } from "../../config/tiendanube-profile-store.js";
11
14
  import { listVtexConnections } from "../../config/vtex-profile-store.js";
12
15
  const listProfilesSchema = z.object({});
13
16
  const REQUIRED_GTM_SCOPES = [
@@ -19,6 +22,25 @@ const REQUIRED_GTM_SCOPES = [
19
22
  "https://www.googleapis.com/auth/tagmanager.publish",
20
23
  "https://www.googleapis.com/auth/tagmanager.readonly"
21
24
  ];
25
+ const TIENDANUBE_CAPABILITIES = {
26
+ connection_reporting: true,
27
+ operational_tools: "external_mcp",
28
+ provider_surface: "provisional"
29
+ };
30
+ function sanitizePublicStoreId(storeId) {
31
+ if (!storeId) return null;
32
+ const normalized = storeId.trim();
33
+ if (!normalized || normalized.length > 128 || /[\u0000-\u001f\u007f]/.test(normalized) || /\s/.test(normalized)) {
34
+ return null;
35
+ }
36
+ return normalized;
37
+ }
38
+ function getTiendanubeValidationStatus(connection) {
39
+ if (!connection) return "not_configured";
40
+ if (connection.status === "pending") return "pending";
41
+ if (!connection.lastValidatedAt) return "not_validated";
42
+ return connection.status === "active" ? "validated" : "failed";
43
+ }
22
44
  function getGtmStatus(configured, connection) {
23
45
  if (!configured) return "not_configured";
24
46
  if (!connection) return "error";
@@ -48,7 +70,8 @@ async function listProfilesHandler() {
48
70
  mercadolibreConnections,
49
71
  metaMappings,
50
72
  gtmMappingSummaries,
51
- googleOAuthConnection
73
+ googleOAuthConnection,
74
+ tiendanubeConnections
52
75
  ] = await Promise.all([
53
76
  listProfiles({ activeOnly: true }),
54
77
  listProfileGoogleServiceMappings(),
@@ -56,7 +79,8 @@ async function listProfilesHandler() {
56
79
  listMercadoLibreConnections(),
57
80
  listProfileMetaMappings(),
58
81
  listActiveProfileGtmMappingSummaries(),
59
- getGoogleOAuthConnection()
82
+ getGoogleOAuthConnection(),
83
+ listTiendanubeConnections()
60
84
  ]);
61
85
  const mappingsByProfileId = new Map(
62
86
  mappings.map((mapping) => [mapping.profileId, mapping])
@@ -79,6 +103,12 @@ async function listProfilesHandler() {
79
103
  summary.activeMappingCount
80
104
  ])
81
105
  );
106
+ const tiendanubeByProfileId = new Map(
107
+ tiendanubeConnections.map((connection) => [
108
+ connection.profileId,
109
+ connection
110
+ ])
111
+ );
82
112
  return object({
83
113
  total_profiles: profiles.length,
84
114
  profiles: profiles.map((profile) => {
@@ -86,6 +116,7 @@ async function listProfilesHandler() {
86
116
  const vtexConnection = vtexByProfileId.get(profile.id);
87
117
  const mercadolibreConnection = mercadolibreByProfileId.get(profile.id);
88
118
  const metaMapping = metaByProfileId.get(profile.id);
119
+ const tiendanubeConnection = tiendanubeByProfileId.get(profile.id);
89
120
  const metaConfigured = Boolean(
90
121
  metaMapping?.metaBusinessId && metaMapping.status === "active"
91
122
  );
@@ -133,15 +164,28 @@ async function listProfilesHandler() {
133
164
  configured: metaConfigured,
134
165
  status: metaConfigured ? metaMapping?.status ?? "not_configured" : "not_configured",
135
166
  raw_status: metaMapping?.status ?? null
167
+ },
168
+ tiendanube: {
169
+ available: true,
170
+ external_mcp: true,
171
+ configured: Boolean(tiendanubeConnection),
172
+ status: tiendanubeConnection?.status ?? "not_configured",
173
+ raw_status: tiendanubeConnection?.status ?? null,
174
+ validation_status: getTiendanubeValidationStatus(
175
+ tiendanubeConnection
176
+ ),
177
+ last_validated_at: tiendanubeConnection?.lastValidatedAt?.toISOString() ?? null,
178
+ store_id: sanitizePublicStoreId(
179
+ tiendanubeConnection?.storeId
180
+ ),
181
+ capabilities: TIENDANUBE_CAPABILITIES
136
182
  }
137
183
  }
138
184
  };
139
185
  })
140
186
  });
141
- } catch (err) {
142
- return error(
143
- err instanceof Error ? err.message : "Failed to list profiles"
144
- );
187
+ } catch {
188
+ return error("Failed to list profiles");
145
189
  }
146
190
  }
147
191
  export {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/tools/config/list-profiles.ts"],
4
- "sourcesContent": ["import { error, object } from \"mcp-use/server\";\nimport { z } from \"zod\";\nimport {\n\tgetGoogleOAuthConnection,\n\tlistActiveProfileGtmMappingSummaries,\n\tlistProfileGoogleServiceMappings,\n\ttype GoogleOAuthConnectionRecord,\n} from \"../../config/google-store.js\";\nimport { listMercadoLibreConnections } from \"../../config/mercadolibre-profile-store.js\";\nimport { listProfileMetaMappings } from \"../../config/meta-store.js\";\nimport { listProfiles } from \"../../config/profile-store.js\";\nimport { listVtexConnections } from \"../../config/vtex-profile-store.js\";\n\nexport const listProfilesSchema = z.object({});\n\ntype NormalizedServiceStatus =\n\t| \"active\"\n\t| \"disabled\"\n\t| \"expired\"\n\t| \"error\"\n\t| \"pending\"\n\t| \"not_configured\";\n\nconst REQUIRED_GTM_SCOPES = [\n\t\"https://www.googleapis.com/auth/tagmanager.manage.accounts\",\n\t\"https://www.googleapis.com/auth/tagmanager.edit.containers\",\n\t\"https://www.googleapis.com/auth/tagmanager.delete.containers\",\n\t\"https://www.googleapis.com/auth/tagmanager.edit.containerversions\",\n\t\"https://www.googleapis.com/auth/tagmanager.manage.users\",\n\t\"https://www.googleapis.com/auth/tagmanager.publish\",\n\t\"https://www.googleapis.com/auth/tagmanager.readonly\",\n] as const;\n\nfunction getGtmStatus(\n\tconfigured: boolean,\n\tconnection: GoogleOAuthConnectionRecord | null,\n): NormalizedServiceStatus {\n\tif (!configured) return \"not_configured\";\n\tif (!connection) return \"error\";\n\tif (connection.status !== \"active\") return connection.status;\n\tif (!connection.encryptedRefreshToken) return \"error\";\n\treturn REQUIRED_GTM_SCOPES.every((scope) => connection.scopes.includes(scope))\n\t\t? \"active\"\n\t\t: \"error\";\n}\n\nfunction normalizeVtexStatus(\n\tstatus: \"pending\" | \"valid\" | \"invalid\" | \"disabled\",\n): Exclude<NormalizedServiceStatus, \"expired\" | \"not_configured\"> {\n\tswitch (status) {\n\t\tcase \"valid\":\n\t\t\treturn \"active\";\n\t\tcase \"invalid\":\n\t\t\treturn \"error\";\n\t\tcase \"disabled\":\n\t\t\treturn \"disabled\";\n\t\tcase \"pending\":\n\t\tdefault:\n\t\t\treturn \"pending\";\n\t}\n}\n\nexport async function listProfilesHandler() {\n\ttry {\n\t\tconst [\n\t\t\tprofiles,\n\t\t\tmappings,\n\t\t\tvtexConnections,\n\t\t\tmercadolibreConnections,\n\t\t\tmetaMappings,\n\t\t\tgtmMappingSummaries,\n\t\t\tgoogleOAuthConnection,\n\t\t] = await Promise.all([\n\t\t\tlistProfiles({ activeOnly: true }),\n\t\t\tlistProfileGoogleServiceMappings(),\n\t\t\tlistVtexConnections(),\n\t\t\tlistMercadoLibreConnections(),\n\t\t\tlistProfileMetaMappings(),\n\t\t\tlistActiveProfileGtmMappingSummaries(),\n\t\t\tgetGoogleOAuthConnection(),\n\t\t]);\n\t\tconst mappingsByProfileId = new Map(\n\t\t\tmappings.map((mapping) => [mapping.profileId, mapping]),\n\t\t);\n\t\tconst vtexByProfileId = new Map(\n\t\t\tvtexConnections.map((connection) => [connection.profileId, connection]),\n\t\t);\n\t\tconst mercadolibreByProfileId = new Map(\n\t\t\tmercadolibreConnections.map((connection) => [\n\t\t\t\tconnection.profileId,\n\t\t\t\tconnection,\n\t\t\t]),\n\t\t);\n\t\tconst metaByProfileId = new Map(\n\t\t\tmetaMappings.map((mapping) => [mapping.profileId, mapping]),\n\t\t);\n\t\tconst gtmMappingCountByProfileId = new Map(\n\t\t\tgtmMappingSummaries.map((summary) => [\n\t\t\t\tsummary.profileId,\n\t\t\t\tsummary.activeMappingCount,\n\t\t\t]),\n\t\t);\n\t\treturn object({\n\t\t\ttotal_profiles: profiles.length,\n\t\t\tprofiles: profiles.map((profile) => {\n\t\t\t\tconst mapping = mappingsByProfileId.get(profile.id);\n\t\t\t\tconst vtexConnection = vtexByProfileId.get(profile.id);\n\t\t\t\tconst mercadolibreConnection = mercadolibreByProfileId.get(profile.id);\n\t\t\t\tconst metaMapping = metaByProfileId.get(profile.id);\n\t\t\t\tconst metaConfigured = Boolean(\n\t\t\t\t\tmetaMapping?.metaBusinessId && metaMapping.status === \"active\",\n\t\t\t\t);\n\t\t\t\tconst gtmConfigured =\n\t\t\t\t\t(gtmMappingCountByProfileId.get(profile.id) ?? 0) > 0;\n\t\t\t\treturn {\n\t\t\t\t\tprofile_id: profile.id,\n\t\t\t\t\tname: profile.name,\n\t\t\t\t\tis_active: profile.isActive,\n\t\t\t\t\tcreated_at: profile.createdAt.toISOString(),\n\t\t\t\t\tupdated_at: profile.updatedAt.toISOString(),\n\t\t\t\t\tservices: {\n\t\t\t\t\t\tgoogle: {\n\t\t\t\t\t\t\tgoogle_ads: {\n\t\t\t\t\t\t\t\tconfigured: Boolean(mapping?.googleAdsCustomerId),\n\t\t\t\t\t\t\t\tstatus: mapping?.googleAdsCustomerId\n\t\t\t\t\t\t\t\t\t? mapping.googleAdsStatus\n\t\t\t\t\t\t\t\t\t: \"not_configured\",\n\t\t\t\t\t\t\t\traw_status: mapping?.googleAdsCustomerId\n\t\t\t\t\t\t\t\t\t? mapping.googleAdsStatus\n\t\t\t\t\t\t\t\t\t: null,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tga4: {\n\t\t\t\t\t\t\t\tconfigured: Boolean(mapping?.ga4PropertyId),\n\t\t\t\t\t\t\t\tstatus: mapping?.ga4PropertyId\n\t\t\t\t\t\t\t\t\t? mapping.ga4Status\n\t\t\t\t\t\t\t\t\t: \"not_configured\",\n\t\t\t\t\t\t\t\traw_status: mapping?.ga4PropertyId ? mapping.ga4Status : null,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tsearch_console: {\n\t\t\t\t\t\t\t\tconfigured: Boolean(mapping?.searchConsoleSiteUrl),\n\t\t\t\t\t\t\t\tstatus: mapping?.searchConsoleSiteUrl\n\t\t\t\t\t\t\t\t\t? mapping.searchConsoleStatus\n\t\t\t\t\t\t\t\t\t: \"not_configured\",\n\t\t\t\t\t\t\t\traw_status: mapping?.searchConsoleSiteUrl\n\t\t\t\t\t\t\t\t\t? mapping.searchConsoleStatus\n\t\t\t\t\t\t\t\t\t: null,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tgtm: {\n\t\t\t\t\t\t\t\tconfigured: gtmConfigured,\n\t\t\t\t\t\t\t\tstatus: getGtmStatus(gtmConfigured, googleOAuthConnection),\n\t\t\t\t\t\t\t\traw_status: gtmConfigured\n\t\t\t\t\t\t\t\t\t? (googleOAuthConnection?.status ?? null)\n\t\t\t\t\t\t\t\t\t: null,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tvtex: {\n\t\t\t\t\t\t\tconfigured: Boolean(vtexConnection),\n\t\t\t\t\t\t\tstatus: vtexConnection\n\t\t\t\t\t\t\t\t? normalizeVtexStatus(vtexConnection.status)\n\t\t\t\t\t\t\t\t: \"not_configured\",\n\t\t\t\t\t\t\traw_status: vtexConnection ? vtexConnection.status : null,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmercadolibre: {\n\t\t\t\t\t\t\tconfigured: Boolean(mercadolibreConnection),\n\t\t\t\t\t\t\tstatus: mercadolibreConnection\n\t\t\t\t\t\t\t\t? mercadolibreConnection.status\n\t\t\t\t\t\t\t\t: \"not_configured\",\n\t\t\t\t\t\t\traw_status: mercadolibreConnection\n\t\t\t\t\t\t\t\t? mercadolibreConnection.status\n\t\t\t\t\t\t\t\t: null,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmeta: {\n\t\t\t\t\t\t\tconfigured: metaConfigured,\n\t\t\t\t\t\t\tstatus: metaConfigured\n\t\t\t\t\t\t\t\t? (metaMapping?.status ?? \"not_configured\")\n\t\t\t\t\t\t\t\t: \"not_configured\",\n\t\t\t\t\t\t\traw_status: metaMapping?.status ?? null,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}),\n\t\t});\n\t} catch (err) {\n\t\treturn error(\n\t\t\terr instanceof Error ? err.message : \"Failed to list profiles\",\n\t\t);\n\t}\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { error, object } from \"mcp-use/server\";\nimport { z } from \"zod\";\nimport {\n\tgetGoogleOAuthConnection,\n\tlistActiveProfileGtmMappingSummaries,\n\tlistProfileGoogleServiceMappings,\n\ttype GoogleOAuthConnectionRecord,\n} from \"../../config/google-store.js\";\nimport { listMercadoLibreConnections } from \"../../config/mercadolibre-profile-store.js\";\nimport { listProfileMetaMappings } from \"../../config/meta-store.js\";\nimport { listProfiles } from \"../../config/profile-store.js\";\nimport {\n listTiendanubeConnections,\n type TiendanubeConnectionRecord,\n} from \"../../config/tiendanube-profile-store.js\";\nimport { listVtexConnections } from \"../../config/vtex-profile-store.js\";\n\nexport const listProfilesSchema = z.object({});\n\ntype NormalizedServiceStatus =\n\t| \"active\"\n\t| \"disabled\"\n\t| \"expired\"\n\t| \"error\"\n\t| \"pending\"\n\t| \"not_configured\";\n\nconst REQUIRED_GTM_SCOPES = [\n\t\"https://www.googleapis.com/auth/tagmanager.manage.accounts\",\n\t\"https://www.googleapis.com/auth/tagmanager.edit.containers\",\n\t\"https://www.googleapis.com/auth/tagmanager.delete.containers\",\n\t\"https://www.googleapis.com/auth/tagmanager.edit.containerversions\",\n\t\"https://www.googleapis.com/auth/tagmanager.manage.users\",\n\t\"https://www.googleapis.com/auth/tagmanager.publish\",\n\t\"https://www.googleapis.com/auth/tagmanager.readonly\",\n] as const;\n\nconst TIENDANUBE_CAPABILITIES = {\n\tconnection_reporting: true,\n\toperational_tools: \"external_mcp\",\n\tprovider_surface: \"provisional\",\n} as const;\n\ntype TiendanubeValidationStatus =\n\t| \"validated\"\n\t| \"failed\"\n\t| \"pending\"\n\t| \"not_validated\"\n\t| \"not_configured\";\n\nfunction sanitizePublicStoreId(storeId: string | undefined): string | null {\n\tif (!storeId) return null;\n\n\tconst normalized = storeId.trim();\n\tif (\n\t\t!normalized ||\n\t\tnormalized.length > 128 ||\n\t\t/[\\u0000-\\u001f\\u007f]/.test(normalized) ||\n\t\t/\\s/.test(normalized)\n\t) {\n\t\treturn null;\n\t}\n\n\treturn normalized;\n}\n\nfunction getTiendanubeValidationStatus(\n\tconnection: TiendanubeConnectionRecord | undefined,\n): TiendanubeValidationStatus {\n\tif (!connection) return \"not_configured\";\n\tif (connection.status === \"pending\") return \"pending\";\n\tif (!connection.lastValidatedAt) return \"not_validated\";\n\treturn connection.status === \"active\" ? \"validated\" : \"failed\";\n}\n\nfunction getGtmStatus(\n\tconfigured: boolean,\n\tconnection: GoogleOAuthConnectionRecord | null,\n): NormalizedServiceStatus {\n\tif (!configured) return \"not_configured\";\n\tif (!connection) return \"error\";\n\tif (connection.status !== \"active\") return connection.status;\n\tif (!connection.encryptedRefreshToken) return \"error\";\n\treturn REQUIRED_GTM_SCOPES.every((scope) => connection.scopes.includes(scope))\n\t\t? \"active\"\n\t\t: \"error\";\n}\n\nfunction normalizeVtexStatus(\n\tstatus: \"pending\" | \"valid\" | \"invalid\" | \"disabled\",\n): Exclude<NormalizedServiceStatus, \"expired\" | \"not_configured\"> {\n\tswitch (status) {\n\t\tcase \"valid\":\n\t\t\treturn \"active\";\n\t\tcase \"invalid\":\n\t\t\treturn \"error\";\n\t\tcase \"disabled\":\n\t\t\treturn \"disabled\";\n\t\tcase \"pending\":\n\t\tdefault:\n\t\t\treturn \"pending\";\n\t}\n}\n\nexport async function listProfilesHandler() {\n\ttry {\n\t\tconst [\n\t\t\tprofiles,\n\t\t\tmappings,\n\t\t\tvtexConnections,\n\t\t\tmercadolibreConnections,\n\t\t\tmetaMappings,\n\t\t\tgtmMappingSummaries,\n\t\t\tgoogleOAuthConnection,\n\t\t\ttiendanubeConnections,\n\t\t] = await Promise.all([\n\t\t\tlistProfiles({ activeOnly: true }),\n\t\t\tlistProfileGoogleServiceMappings(),\n\t\t\tlistVtexConnections(),\n\t\t\tlistMercadoLibreConnections(),\n\t\t\tlistProfileMetaMappings(),\n\t\t\tlistActiveProfileGtmMappingSummaries(),\n\t\t\tgetGoogleOAuthConnection(),\n\t\t\tlistTiendanubeConnections(),\n\t\t]);\n\t\tconst mappingsByProfileId = new Map(\n\t\t\tmappings.map((mapping) => [mapping.profileId, mapping]),\n\t\t);\n\t\tconst vtexByProfileId = new Map(\n\t\t\tvtexConnections.map((connection) => [connection.profileId, connection]),\n\t\t);\n\t\tconst mercadolibreByProfileId = new Map(\n\t\t\tmercadolibreConnections.map((connection) => [\n\t\t\t\tconnection.profileId,\n\t\t\t\tconnection,\n\t\t\t]),\n\t\t);\n\t\tconst metaByProfileId = new Map(\n\t\t\tmetaMappings.map((mapping) => [mapping.profileId, mapping]),\n\t\t);\n\t\tconst gtmMappingCountByProfileId = new Map(\n\t\t\tgtmMappingSummaries.map((summary) => [\n\t\t\t\tsummary.profileId,\n\t\t\t\tsummary.activeMappingCount,\n\t\t\t]),\n\t\t);\n\t\tconst tiendanubeByProfileId = new Map(\n\t\t\ttiendanubeConnections.map((connection) => [\n\t\t\t\tconnection.profileId,\n\t\t\t\tconnection,\n\t\t\t]),\n\t\t);\n\t\treturn object({\n\t\t\ttotal_profiles: profiles.length,\n\t\t\tprofiles: profiles.map((profile) => {\n\t\t\t\tconst mapping = mappingsByProfileId.get(profile.id);\n\t\t\t\tconst vtexConnection = vtexByProfileId.get(profile.id);\n\t\t\t\tconst mercadolibreConnection = mercadolibreByProfileId.get(profile.id);\n\t\t\t\tconst metaMapping = metaByProfileId.get(profile.id);\n\t\t\t\tconst tiendanubeConnection = tiendanubeByProfileId.get(profile.id);\n\t\t\t\tconst metaConfigured = Boolean(\n\t\t\t\t\tmetaMapping?.metaBusinessId && metaMapping.status === \"active\",\n\t\t\t\t);\n\t\t\t\tconst gtmConfigured =\n\t\t\t\t\t(gtmMappingCountByProfileId.get(profile.id) ?? 0) > 0;\n\t\t\t\treturn {\n\t\t\t\t\tprofile_id: profile.id,\n\t\t\t\t\tname: profile.name,\n\t\t\t\t\tis_active: profile.isActive,\n\t\t\t\t\tcreated_at: profile.createdAt.toISOString(),\n\t\t\t\t\tupdated_at: profile.updatedAt.toISOString(),\n\t\t\t\t\tservices: {\n\t\t\t\t\t\tgoogle: {\n\t\t\t\t\t\t\tgoogle_ads: {\n\t\t\t\t\t\t\t\tconfigured: Boolean(mapping?.googleAdsCustomerId),\n\t\t\t\t\t\t\t\tstatus: mapping?.googleAdsCustomerId\n\t\t\t\t\t\t\t\t\t? mapping.googleAdsStatus\n\t\t\t\t\t\t\t\t\t: \"not_configured\",\n\t\t\t\t\t\t\t\traw_status: mapping?.googleAdsCustomerId\n\t\t\t\t\t\t\t\t\t? mapping.googleAdsStatus\n\t\t\t\t\t\t\t\t\t: null,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tga4: {\n\t\t\t\t\t\t\t\tconfigured: Boolean(mapping?.ga4PropertyId),\n\t\t\t\t\t\t\t\tstatus: mapping?.ga4PropertyId\n\t\t\t\t\t\t\t\t\t? mapping.ga4Status\n\t\t\t\t\t\t\t\t\t: \"not_configured\",\n\t\t\t\t\t\t\t\traw_status: mapping?.ga4PropertyId ? mapping.ga4Status : null,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tsearch_console: {\n\t\t\t\t\t\t\t\tconfigured: Boolean(mapping?.searchConsoleSiteUrl),\n\t\t\t\t\t\t\t\tstatus: mapping?.searchConsoleSiteUrl\n\t\t\t\t\t\t\t\t\t? mapping.searchConsoleStatus\n\t\t\t\t\t\t\t\t\t: \"not_configured\",\n\t\t\t\t\t\t\t\traw_status: mapping?.searchConsoleSiteUrl\n\t\t\t\t\t\t\t\t\t? mapping.searchConsoleStatus\n\t\t\t\t\t\t\t\t\t: null,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tgtm: {\n\t\t\t\t\t\t\t\tconfigured: gtmConfigured,\n\t\t\t\t\t\t\t\tstatus: getGtmStatus(gtmConfigured, googleOAuthConnection),\n\t\t\t\t\t\t\t\traw_status: gtmConfigured\n\t\t\t\t\t\t\t\t\t? (googleOAuthConnection?.status ?? null)\n\t\t\t\t\t\t\t\t\t: null,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tvtex: {\n\t\t\t\t\t\t\tconfigured: Boolean(vtexConnection),\n\t\t\t\t\t\t\tstatus: vtexConnection\n\t\t\t\t\t\t\t\t? normalizeVtexStatus(vtexConnection.status)\n\t\t\t\t\t\t\t\t: \"not_configured\",\n\t\t\t\t\t\t\traw_status: vtexConnection ? vtexConnection.status : null,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmercadolibre: {\n\t\t\t\t\t\t\tconfigured: Boolean(mercadolibreConnection),\n\t\t\t\t\t\t\tstatus: mercadolibreConnection\n\t\t\t\t\t\t\t\t? mercadolibreConnection.status\n\t\t\t\t\t\t\t\t: \"not_configured\",\n\t\t\t\t\t\t\traw_status: mercadolibreConnection\n\t\t\t\t\t\t\t\t? mercadolibreConnection.status\n\t\t\t\t\t\t\t\t: null,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmeta: {\n\t\t\t\t\t\t\tconfigured: metaConfigured,\n\t\t\t\t\t\t\tstatus: metaConfigured\n\t\t\t\t\t\t\t\t? (metaMapping?.status ?? \"not_configured\")\n\t\t\t\t\t\t\t\t: \"not_configured\",\n\t\t\t\t\t\t\traw_status: metaMapping?.status ?? null,\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttiendanube: {\n\t\t\t\t\t\t\tavailable: true,\n\t\t\t\t\t\t\texternal_mcp: true,\n\t\t\t\t\t\t\tconfigured: Boolean(tiendanubeConnection),\n\t\t\t\t\t\t\tstatus: tiendanubeConnection?.status ?? \"not_configured\",\n\t\t\t\t\t\t\traw_status: tiendanubeConnection?.status ?? null,\n\t\t\t\t\t\t\tvalidation_status: getTiendanubeValidationStatus(\n\t\t\t\t\t\t\t\ttiendanubeConnection,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\tlast_validated_at:\n\t\t\t\t\t\t\t\ttiendanubeConnection?.lastValidatedAt?.toISOString() ?? null,\n\t\t\t\t\t\t\tstore_id: sanitizePublicStoreId(\n\t\t\t\t\t\t\t\ttiendanubeConnection?.storeId,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\tcapabilities: TIENDANUBE_CAPABILITIES,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}),\n\t\t});\n\t} catch {\n\t\treturn error(\"Failed to list profiles\");\n\t}\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,417 @@
1
+ import { afterEach, beforeEach, describe, expect, it } from "vitest";
2
+ import {
3
+ buildSalesReportDateBoundaries,
4
+ buildSalesReportMetadata,
5
+ createSalesReportPerformanceTracker,
6
+ decodeSalesReportCursor,
7
+ encodeSalesReportCursor,
8
+ getSalesReportOperationSaleTimestamp,
9
+ isSalesReportOperationAfterCursor,
10
+ meliGetSalesReportSchema,
11
+ sortSalesReportOperations
12
+ } from "../get-sales-report.js";
13
+ import {
14
+ buildOrderUniversePagePlan,
15
+ groupMercadoLibreOrders
16
+ } from "../../../services/mercadolibre/mercadolibre-sales-report.js";
17
+ const TEST_KEY = "11".repeat(32);
18
+ function order(orderId, saleDate) {
19
+ return {
20
+ order_id: orderId,
21
+ ventas: {
22
+ fecha_de_venta: saleDate,
23
+ estado: null,
24
+ descripcion_del_estado: null,
25
+ pertenece_a_un_kit: null,
26
+ unidades: null,
27
+ ingresos_por_productos_ars: null,
28
+ orden_de_compra: null
29
+ },
30
+ publicidad: { venta_por_publicidad: null },
31
+ publicaciones: {
32
+ sku: null,
33
+ numero_de_publicacion: null,
34
+ canal_de_venta: null,
35
+ titulo_de_la_publicacion: null,
36
+ variante: null,
37
+ precio_unitario_de_venta_de_la_publicacion_ars: null,
38
+ tiene_cuotas_agregadas: null
39
+ },
40
+ facturacion_al_comprador: {
41
+ factura_adjunta: null,
42
+ datos_personales_o_de_empresa: null,
43
+ tipo_y_numero_de_documento: null,
44
+ direccion: null,
45
+ condicion_fiscal_iva: null,
46
+ numero_iibb: null
47
+ },
48
+ compradores: {
49
+ comprador: null,
50
+ negocio: null,
51
+ dni: null,
52
+ domicilio: null,
53
+ ciudad: null,
54
+ estado: null,
55
+ codigo_postal: null,
56
+ pais: null
57
+ },
58
+ envios: {
59
+ forma_de_entrega: null,
60
+ fecha_en_camino: null,
61
+ fecha_entregado: null,
62
+ transportista: null,
63
+ numero_de_seguimiento: null,
64
+ url_de_seguimiento: null
65
+ },
66
+ devoluciones: {
67
+ unidades: null,
68
+ forma_de_entrega: null,
69
+ fecha_en_camino: null,
70
+ fecha_entregado: null,
71
+ transportista: null,
72
+ numero_de_seguimiento: null,
73
+ url_de_seguimiento: null,
74
+ revisado_por_mercado_libre: null,
75
+ fecha_de_revision: null,
76
+ dinero_a_favor: null,
77
+ resultado: null,
78
+ destino: null,
79
+ motivo_del_resultado: null
80
+ },
81
+ reclamos: {
82
+ unidades: null,
83
+ reclamo_abierto: null,
84
+ reclamo_cerrado: null,
85
+ con_mediacion: null
86
+ }
87
+ };
88
+ }
89
+ function operation(packId, orderId, saleDate) {
90
+ return {
91
+ pack_id: packId,
92
+ ventas: {
93
+ paquete_de_varios_productos: packId !== null,
94
+ cargo_por_venta: null,
95
+ costo_fijo: null,
96
+ costo_por_ofrecer_cuotas: null,
97
+ ingresos_por_envio_ars: null,
98
+ costos_de_envio_ars: null,
99
+ costo_de_envio_por_cambio_de_producto: null,
100
+ costo_de_envio_basado_en_medidas_y_peso_declarados: null,
101
+ cargo_por_diferencias_en_medidas_y_peso_del_paquete: null,
102
+ impuestos: null,
103
+ descuentos_y_bonificaciones: null,
104
+ anulaciones_y_reembolsos_ars: null,
105
+ total_ars: null,
106
+ periodos_de_facturacion: []
107
+ },
108
+ ordenes: [order(orderId, saleDate)]
109
+ };
110
+ }
111
+ describe("meli_get_sales_report Phase 0 foundation", () => {
112
+ const originalKey = process.env.DB_ENCRYPTION_KEY;
113
+ beforeEach(() => {
114
+ process.env.DB_ENCRYPTION_KEY = TEST_KEY;
115
+ });
116
+ afterEach(() => {
117
+ if (originalKey === void 0) delete process.env.DB_ENCRYPTION_KEY;
118
+ else process.env.DB_ENCRYPTION_KEY = originalKey;
119
+ });
120
+ it("tracks monotonic stage and total durations deterministically", async () => {
121
+ let currentTime = 100;
122
+ const tracker = createSalesReportPerformanceTracker(() => currentTime);
123
+ const stageStartedAt = tracker.start();
124
+ currentTime = 104.6;
125
+ expect(tracker.finish("seleccion", stageStartedAt)).toBe(5);
126
+ await tracker.measure("postventa", async () => {
127
+ currentTime = 111.2;
128
+ });
129
+ currentTime = 115;
130
+ expect(tracker.duration("seleccion")).toBe(5);
131
+ expect(tracker.duration("postventa")).toBe(7);
132
+ expect(tracker.duration("ausente")).toBe(0);
133
+ expect(tracker.total()).toBe(15);
134
+ });
135
+ it("validates input and applies the default and maximum limits", () => {
136
+ expect(
137
+ meliGetSalesReportSchema.parse({
138
+ profileId: "triplim",
139
+ startDate: "2026-06-01",
140
+ endDate: "2026-06-30"
141
+ }).limit ?? 200
142
+ ).toBe(200);
143
+ expect(
144
+ meliGetSalesReportSchema.parse({
145
+ profileId: "triplim",
146
+ startDate: "2026-06-01",
147
+ endDate: "2026-06-30",
148
+ limit: 1e3
149
+ }).limit
150
+ ).toBe(1e3);
151
+ expect(
152
+ () => meliGetSalesReportSchema.parse({
153
+ profileId: "triplim",
154
+ startDate: "2026-02-30",
155
+ endDate: "2026-06-30"
156
+ })
157
+ ).toThrow();
158
+ expect(
159
+ () => meliGetSalesReportSchema.parse({
160
+ profileId: "triplim",
161
+ startDate: "2026-06-01",
162
+ endDate: "2026-06-30",
163
+ billingPeriod: "2026-06"
164
+ })
165
+ ).toThrow();
166
+ expect(
167
+ () => meliGetSalesReportSchema.parse({
168
+ profileId: "triplim",
169
+ startDate: "2026-06-01",
170
+ endDate: "2026-06-30",
171
+ limit: 1001
172
+ })
173
+ ).toThrow();
174
+ });
175
+ it("accepts strict range and explicit-order modes with trimmed stable duplicates", () => {
176
+ expect(meliGetSalesReportSchema.parse({
177
+ profileId: "triplim",
178
+ startDate: "2026-06-01",
179
+ endDate: "2026-06-30"
180
+ })).toEqual(expect.objectContaining({ startDate: "2026-06-01", endDate: "2026-06-30" }));
181
+ expect(meliGetSalesReportSchema.parse({
182
+ profileId: "triplim",
183
+ orderIds: [" order-b ", "order-a", "order-b"]
184
+ }).orderIds).toEqual(["order-b", "order-a", "order-b"]);
185
+ });
186
+ it.each([
187
+ { profileId: "triplim", orderIds: [], label: "empty list" },
188
+ { profileId: "triplim", orderIds: Array.from({ length: 101 }, (_, index) => `order-${index}`), label: "more than 100 IDs" },
189
+ { profileId: "triplim", orderIds: [" "], label: "empty item" },
190
+ { profileId: "triplim", orderIds: ["order-1"], startDate: "2026-06-01", endDate: "2026-06-30", label: "dates in explicit mode" },
191
+ { profileId: "triplim", orderIds: ["order-1"], limit: 1, label: "limit in explicit mode" },
192
+ { profileId: "triplim", orderIds: ["order-1"], cursor: "cursor", label: "cursor in explicit mode" },
193
+ { profileId: "triplim", startDate: "2026-06-01", label: "incomplete range" }
194
+ ])("rejects $label", ({ label: _label, ...input }) => {
195
+ expect(() => meliGetSalesReportSchema.parse(input)).toThrow();
196
+ });
197
+ it("rejects reversed sales dates", () => {
198
+ expect(
199
+ () => meliGetSalesReportSchema.parse({
200
+ profileId: "triplim",
201
+ startDate: "2026-07-01",
202
+ endDate: "2026-06-30"
203
+ })
204
+ ).toThrow("endDate must be on or after startDate");
205
+ });
206
+ it("builds inclusive Buenos Aires timezone boundaries", () => {
207
+ expect(buildSalesReportDateBoundaries("2026-06-01", "2026-06-30")).toEqual({
208
+ timeZone: "America/Argentina/Buenos_Aires",
209
+ from: "2026-06-01T00:00:00.000-03:00",
210
+ to: "2026-06-30T23:59:59.999-03:00"
211
+ });
212
+ });
213
+ it("uses the historical Buenos Aires offset for date boundaries", () => {
214
+ expect(buildSalesReportDateBoundaries("2008-01-01", "2008-01-31")).toEqual({
215
+ timeZone: "America/Argentina/Buenos_Aires",
216
+ from: "2008-01-01T00:00:00.000-02:00",
217
+ to: "2008-01-31T23:59:59.999-02:00"
218
+ });
219
+ });
220
+ it("orders operations by sale date and then operation key descending without mutation", () => {
221
+ const original = [
222
+ operation(null, "200", "2026-06-30T20:00:00-03:00"),
223
+ operation("300", "201", "2026-06-30T20:00:00-03:00"),
224
+ operation(null, "999", "2026-06-29T20:00:00-03:00")
225
+ ];
226
+ const sorted = sortSalesReportOperations(original);
227
+ expect(sorted.map((item) => item.pack_id ?? item.ordenes[0].order_id)).toEqual([
228
+ "300",
229
+ "200",
230
+ "999"
231
+ ]);
232
+ expect(original[0].ordenes[0].order_id).toBe("200");
233
+ });
234
+ it("chooses the latest sale by instant when timestamps have mixed offsets", () => {
235
+ const packed = operation("300", "201", "2026-06-02T00:30:00-03:00");
236
+ packed.ordenes.push(order("202", "2026-06-02T00:00:00-04:00"));
237
+ expect(getSalesReportOperationSaleTimestamp(packed)).toBe("2026-06-02T00:00:00-04:00");
238
+ });
239
+ it("round-trips a self-contained cursor and rejects scope changes", () => {
240
+ const scope = { profileId: "triplim", startDate: "2026-06-01", endDate: "2026-06-30" };
241
+ const cursor = encodeSalesReportCursor({
242
+ ...scope,
243
+ lastSaleTimestamp: "2026-06-20T10:00:00-03:00",
244
+ lastOperationKey: "200001"
245
+ });
246
+ expect(decodeSalesReportCursor(cursor, scope)).toEqual({
247
+ version: 1,
248
+ ...scope,
249
+ lastSaleTimestamp: "2026-06-20T10:00:00-03:00",
250
+ lastOperationKey: "200001"
251
+ });
252
+ expect(
253
+ () => decodeSalesReportCursor(cursor, { ...scope, profileId: "another-profile" })
254
+ ).toThrow("does not match the requested report scope");
255
+ });
256
+ it("rejects cursor tampering", () => {
257
+ const scope = { profileId: "triplim", startDate: "2026-06-01", endDate: "2026-06-30" };
258
+ const cursor = encodeSalesReportCursor({
259
+ ...scope,
260
+ lastSaleTimestamp: "2026-06-20T10:00:00-03:00",
261
+ lastOperationKey: "200001"
262
+ });
263
+ const [payload, signature] = cursor.split(".");
264
+ const tampered = `${payload.slice(0, -1)}${payload.endsWith("A") ? "B" : "A"}.${signature}`;
265
+ expect(() => decodeSalesReportCursor(tampered, scope)).toThrow("Invalid sales report cursor");
266
+ });
267
+ it("keeps cursor continuation ordered by instants across offsets", () => {
268
+ const candidate = operation("300", "201", "2026-06-02T00:30:00-03:00");
269
+ expect(isSalesReportOperationAfterCursor(candidate, {
270
+ lastSaleTimestamp: "2026-06-02T00:00:00-04:00",
271
+ lastOperationKey: "200"
272
+ })).toBe(true);
273
+ });
274
+ it("preserves null values while metadata marks unavailable fields", () => {
275
+ const item = operation(null, "200", "2026-06-30T20:00:00-03:00");
276
+ const metadata = buildSalesReportMetadata({
277
+ profileId: "triplim",
278
+ startDate: "2026-06-01",
279
+ endDate: "2026-06-30",
280
+ currencies: ["ARS"],
281
+ itemsReturned: 1,
282
+ requestedLimit: 200,
283
+ packsReturned: 0,
284
+ ordersReturned: 1,
285
+ partialSections: ["facturacion_al_comprador"],
286
+ sourceCoverage: [
287
+ { fuente: "orders", estado: "complete", solicitados: 1, obtenidos: 1, incidentes: 0 },
288
+ { fuente: "billing", estado: "unavailable", solicitados: 1, obtenidos: 0, incidentes: 1 }
289
+ ],
290
+ fieldProvenance: [
291
+ {
292
+ campo: "facturacion_al_comprador.factura_adjunta",
293
+ fuente: "billing",
294
+ estado: "unavailable",
295
+ detalle: "Billing source was unavailable for this order."
296
+ }
297
+ ],
298
+ scopedIncidents: [
299
+ {
300
+ fuente: "billing",
301
+ alcance: "order",
302
+ identificadores: ["200"],
303
+ mensaje: "Billing request failed.",
304
+ reintentable: true
305
+ }
306
+ ],
307
+ unsupportedFields: ["facturacion_al_comprador.factura_adjunta"],
308
+ hasMore: false
309
+ });
310
+ expect(item.ordenes[0].facturacion_al_comprador.factura_adjunta).toBeNull();
311
+ expect(metadata.cobertura_completa).toBe(false);
312
+ expect(metadata.campos_no_disponibles).toContain(
313
+ "facturacion_al_comprador.factura_adjunta"
314
+ );
315
+ expect(metadata).not.toHaveProperty("procedencia_de_campos");
316
+ expect(metadata.cobertura_por_fuente).toContainEqual(
317
+ expect.objectContaining({ fuente: "billing", estado: "unavailable" })
318
+ );
319
+ expect(metadata.incidentes_acotados).toContainEqual(
320
+ expect.objectContaining({ fuente: "billing", identificadores: ["200"] })
321
+ );
322
+ expect(metadata.cursor_siguiente).toBeNull();
323
+ expect(metadata.guia_de_continuacion).toBeNull();
324
+ expect(metadata.motivo_del_corte).toBeNull();
325
+ });
326
+ it("provides explicit guidance when more operations remain", () => {
327
+ const metadata = buildSalesReportMetadata({
328
+ profileId: "triplim",
329
+ startDate: "2026-06-01",
330
+ endDate: "2026-06-30",
331
+ itemsReturned: 1,
332
+ requestedLimit: 1,
333
+ packsReturned: 0,
334
+ ordersReturned: 1,
335
+ hasMore: true,
336
+ nextCursor: "opaque-cursor"
337
+ });
338
+ expect(metadata.guia_de_continuacion).toContain("cursor_siguiente");
339
+ expect(metadata.guia_de_continuacion).not.toContain("opaque-cursor");
340
+ });
341
+ it("marks explicit selection metadata as non-paginated and date-independent", () => {
342
+ const metadata = buildSalesReportMetadata({
343
+ profileId: "triplim",
344
+ startDate: null,
345
+ endDate: null,
346
+ selectionMode: "ordenes_explicitas",
347
+ explicitSelection: {
348
+ ids_solicitados: ["b", "a", "b", "missing"],
349
+ ids_unicos: ["b", "a", "missing"],
350
+ cantidad_solicitada: 4,
351
+ cantidad_unica: 3,
352
+ cantidad_duplicada: 1,
353
+ ids_resueltos: ["b", "a"],
354
+ cantidad_resuelta: 2,
355
+ ids_no_disponibles: ["missing"],
356
+ cantidad_no_disponible: 1
357
+ },
358
+ itemsReturned: 2,
359
+ requestedLimit: null,
360
+ packsReturned: 0,
361
+ ordersReturned: 2,
362
+ scopedIncidents: [{ fuente: "orders", alcance: "order_selection", identificadores: ["missing"], mensaje: "Unavailable.", reintentable: false }],
363
+ hasMore: false
364
+ });
365
+ expect(metadata).toEqual(expect.objectContaining({
366
+ modo_seleccion: "ordenes_explicitas",
367
+ fecha_desde: null,
368
+ fecha_hasta: null,
369
+ limite_solicitado: null,
370
+ tiene_mas: false,
371
+ cursor_siguiente: null,
372
+ guia_de_continuacion: null,
373
+ cobertura_completa: false
374
+ }));
375
+ expect(metadata.seleccion_explicita).toEqual(expect.objectContaining({ cantidad_duplicada: 1, ids_resueltos: ["b", "a"] }));
376
+ expect(metadata).not.toHaveProperty("procedencia_de_campos");
377
+ });
378
+ it("derives unavailable field metadata from provenance", () => {
379
+ const metadata = buildSalesReportMetadata({
380
+ profileId: "triplim",
381
+ startDate: "2026-06-01",
382
+ endDate: "2026-06-30",
383
+ itemsReturned: 1,
384
+ requestedLimit: 200,
385
+ packsReturned: 0,
386
+ ordersReturned: 1,
387
+ fieldProvenance: [
388
+ {
389
+ campo: "ventas.total_ars",
390
+ fuente: "billing",
391
+ estado: "unavailable",
392
+ detalle: "Billing was unavailable."
393
+ }
394
+ ],
395
+ hasMore: false
396
+ });
397
+ expect(metadata.cobertura_completa).toBe(false);
398
+ expect(metadata.campos_no_disponibles).toEqual(["ventas.total_ars"]);
399
+ expect(metadata).not.toHaveProperty("procedencia_de_campos");
400
+ });
401
+ it("plans bounded remaining pages from effective seed paging", () => {
402
+ expect(buildOrderUniversePagePlan({ total: 121, limit: 50, offset: 0 }, 100)).toEqual([50, 100]);
403
+ expect(buildOrderUniversePagePlan({ total: 201, limit: 50, offset: 0 }, 200)).toEqual([50, 100, 150, 200]);
404
+ expect(buildOrderUniversePagePlan({ total: 1e3, limit: 50, offset: 0 }, 150, 2)).toEqual([50, 100]);
405
+ });
406
+ it("groups packs without splitting them and preserves explicit nulls", () => {
407
+ const first = { id: 1, pack_id: 9, date_created: "2026-06-30T10:00:00-03:00", total_amount: null };
408
+ const second = { id: 2, pack_id: 9, date_created: "2026-06-30T11:00:00-03:00" };
409
+ const standalone = { id: 3, date_created: "2026-06-29T11:00:00-03:00" };
410
+ expect(groupMercadoLibreOrders([first, second, standalone]).map((item) => [item.pack_id, item.ordenes.map((order2) => order2.order_id)])).toEqual([
411
+ ["9", ["1", "2"]],
412
+ [null, ["3"]]
413
+ ]);
414
+ expect(groupMercadoLibreOrders([first])[0].ordenes[0].ventas.ingresos_por_productos_ars).toBeNull();
415
+ });
416
+ });
417
+ //# sourceMappingURL=get-sales-report-foundation.test.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/tools/mercadolibre/__tests__/get-sales-report-foundation.test.ts"],
4
+ "sourcesContent": ["import { afterEach, beforeEach, describe, expect, it } from \"vitest\";\n\nimport {\n buildSalesReportDateBoundaries,\n buildSalesReportMetadata,\n createSalesReportPerformanceTracker,\n decodeSalesReportCursor,\n encodeSalesReportCursor,\n getSalesReportOperationSaleTimestamp,\n isSalesReportOperationAfterCursor,\n meliGetSalesReportSchema,\n sortSalesReportOperations,\n type SalesReportOperation,\n type SalesReportOrder,\n} from \"../get-sales-report.js\";\nimport {\n buildOrderUniversePagePlan,\n groupMercadoLibreOrders,\n} from \"../../../services/mercadolibre/mercadolibre-sales-report.js\";\n\nconst TEST_KEY = \"11\".repeat(32);\n\nfunction order(orderId: string, saleDate: string): SalesReportOrder {\n return {\n order_id: orderId,\n ventas: {\n fecha_de_venta: saleDate,\n estado: null,\n descripcion_del_estado: null,\n pertenece_a_un_kit: null,\n unidades: null,\n ingresos_por_productos_ars: null,\n orden_de_compra: null,\n },\n publicidad: { venta_por_publicidad: null },\n publicaciones: {\n sku: null,\n numero_de_publicacion: null,\n canal_de_venta: null,\n titulo_de_la_publicacion: null,\n variante: null,\n precio_unitario_de_venta_de_la_publicacion_ars: null,\n tiene_cuotas_agregadas: null,\n },\n facturacion_al_comprador: {\n factura_adjunta: null,\n datos_personales_o_de_empresa: null,\n tipo_y_numero_de_documento: null,\n direccion: null,\n condicion_fiscal_iva: null,\n numero_iibb: null,\n },\n compradores: {\n comprador: null,\n negocio: null,\n dni: null,\n domicilio: null,\n ciudad: null,\n estado: null,\n codigo_postal: null,\n pais: null,\n },\n envios: {\n forma_de_entrega: null,\n fecha_en_camino: null,\n fecha_entregado: null,\n transportista: null,\n numero_de_seguimiento: null,\n url_de_seguimiento: null,\n },\n devoluciones: {\n unidades: null,\n forma_de_entrega: null,\n fecha_en_camino: null,\n fecha_entregado: null,\n transportista: null,\n numero_de_seguimiento: null,\n url_de_seguimiento: null,\n revisado_por_mercado_libre: null,\n fecha_de_revision: null,\n dinero_a_favor: null,\n resultado: null,\n destino: null,\n motivo_del_resultado: null,\n },\n reclamos: {\n unidades: null,\n reclamo_abierto: null,\n reclamo_cerrado: null,\n con_mediacion: null,\n },\n };\n}\n\nfunction operation(packId: string | null, orderId: string, saleDate: string): SalesReportOperation {\n return {\n pack_id: packId,\n ventas: {\n paquete_de_varios_productos: packId !== null,\n cargo_por_venta: null,\n costo_fijo: null,\n costo_por_ofrecer_cuotas: null,\n ingresos_por_envio_ars: null,\n costos_de_envio_ars: null,\n costo_de_envio_por_cambio_de_producto: null,\n costo_de_envio_basado_en_medidas_y_peso_declarados: null,\n cargo_por_diferencias_en_medidas_y_peso_del_paquete: null,\n impuestos: null,\n descuentos_y_bonificaciones: null,\n anulaciones_y_reembolsos_ars: null,\n total_ars: null,\n periodos_de_facturacion: [],\n },\n ordenes: [order(orderId, saleDate)],\n };\n}\n\ndescribe(\"meli_get_sales_report Phase 0 foundation\", () => {\n const originalKey = process.env.DB_ENCRYPTION_KEY;\n\n beforeEach(() => {\n process.env.DB_ENCRYPTION_KEY = TEST_KEY;\n });\n\n afterEach(() => {\n if (originalKey === undefined) delete process.env.DB_ENCRYPTION_KEY;\n else process.env.DB_ENCRYPTION_KEY = originalKey;\n });\n\n it(\"tracks monotonic stage and total durations deterministically\", async () => {\n let currentTime = 100;\n const tracker = createSalesReportPerformanceTracker(() => currentTime);\n const stageStartedAt = tracker.start();\n currentTime = 104.6;\n expect(tracker.finish(\"seleccion\", stageStartedAt)).toBe(5);\n\n await tracker.measure(\"postventa\", async () => {\n currentTime = 111.2;\n });\n currentTime = 115;\n\n expect(tracker.duration(\"seleccion\")).toBe(5);\n expect(tracker.duration(\"postventa\")).toBe(7);\n expect(tracker.duration(\"ausente\")).toBe(0);\n expect(tracker.total()).toBe(15);\n });\n\n it(\"validates input and applies the default and maximum limits\", () => {\n expect(\n meliGetSalesReportSchema.parse({\n profileId: \"triplim\",\n startDate: \"2026-06-01\",\n endDate: \"2026-06-30\",\n }).limit ?? 200\n ).toBe(200);\n expect(\n meliGetSalesReportSchema.parse({\n profileId: \"triplim\",\n startDate: \"2026-06-01\",\n endDate: \"2026-06-30\",\n limit: 1000,\n }).limit\n ).toBe(1000);\n expect(() =>\n meliGetSalesReportSchema.parse({\n profileId: \"triplim\",\n startDate: \"2026-02-30\",\n endDate: \"2026-06-30\",\n })\n ).toThrow();\n expect(() =>\n meliGetSalesReportSchema.parse({\n profileId: \"triplim\",\n startDate: \"2026-06-01\",\n endDate: \"2026-06-30\",\n billingPeriod: \"2026-06\",\n })\n ).toThrow();\n expect(() =>\n meliGetSalesReportSchema.parse({\n profileId: \"triplim\",\n startDate: \"2026-06-01\",\n endDate: \"2026-06-30\",\n limit: 1001,\n })\n ).toThrow();\n });\n\n it(\"accepts strict range and explicit-order modes with trimmed stable duplicates\", () => {\n expect(meliGetSalesReportSchema.parse({\n profileId: \"triplim\",\n startDate: \"2026-06-01\",\n endDate: \"2026-06-30\",\n })).toEqual(expect.objectContaining({ startDate: \"2026-06-01\", endDate: \"2026-06-30\" }));\n expect(meliGetSalesReportSchema.parse({\n profileId: \"triplim\",\n orderIds: [\" order-b \", \"order-a\", \"order-b\"],\n }).orderIds).toEqual([\"order-b\", \"order-a\", \"order-b\"]);\n });\n\n it.each([\n { profileId: \"triplim\", orderIds: [], label: \"empty list\" },\n { profileId: \"triplim\", orderIds: Array.from({ length: 101 }, (_, index) => `order-${index}`), label: \"more than 100 IDs\" },\n { profileId: \"triplim\", orderIds: [\" \"], label: \"empty item\" },\n { profileId: \"triplim\", orderIds: [\"order-1\"], startDate: \"2026-06-01\", endDate: \"2026-06-30\", label: \"dates in explicit mode\" },\n { profileId: \"triplim\", orderIds: [\"order-1\"], limit: 1, label: \"limit in explicit mode\" },\n { profileId: \"triplim\", orderIds: [\"order-1\"], cursor: \"cursor\", label: \"cursor in explicit mode\" },\n { profileId: \"triplim\", startDate: \"2026-06-01\", label: \"incomplete range\" },\n ])(\"rejects $label\", ({ label: _label, ...input }) => {\n expect(() => meliGetSalesReportSchema.parse(input)).toThrow();\n });\n\n it(\"rejects reversed sales dates\", () => {\n expect(() =>\n meliGetSalesReportSchema.parse({\n profileId: \"triplim\",\n startDate: \"2026-07-01\",\n endDate: \"2026-06-30\",\n })\n ).toThrow(\"endDate must be on or after startDate\");\n });\n\n it(\"builds inclusive Buenos Aires timezone boundaries\", () => {\n expect(buildSalesReportDateBoundaries(\"2026-06-01\", \"2026-06-30\")).toEqual({\n timeZone: \"America/Argentina/Buenos_Aires\",\n from: \"2026-06-01T00:00:00.000-03:00\",\n to: \"2026-06-30T23:59:59.999-03:00\",\n });\n });\n\n it(\"uses the historical Buenos Aires offset for date boundaries\", () => {\n expect(buildSalesReportDateBoundaries(\"2008-01-01\", \"2008-01-31\")).toEqual({\n timeZone: \"America/Argentina/Buenos_Aires\",\n from: \"2008-01-01T00:00:00.000-02:00\",\n to: \"2008-01-31T23:59:59.999-02:00\",\n });\n });\n\n it(\"orders operations by sale date and then operation key descending without mutation\", () => {\n const original = [\n operation(null, \"200\", \"2026-06-30T20:00:00-03:00\"),\n operation(\"300\", \"201\", \"2026-06-30T20:00:00-03:00\"),\n operation(null, \"999\", \"2026-06-29T20:00:00-03:00\"),\n ];\n\n const sorted = sortSalesReportOperations(original);\n expect(sorted.map((item) => item.pack_id ?? item.ordenes[0].order_id)).toEqual([\n \"300\",\n \"200\",\n \"999\",\n ]);\n expect(original[0].ordenes[0].order_id).toBe(\"200\");\n });\n\n it(\"chooses the latest sale by instant when timestamps have mixed offsets\", () => {\n const packed = operation(\"300\", \"201\", \"2026-06-02T00:30:00-03:00\");\n packed.ordenes.push(order(\"202\", \"2026-06-02T00:00:00-04:00\"));\n\n expect(getSalesReportOperationSaleTimestamp(packed)).toBe(\"2026-06-02T00:00:00-04:00\");\n });\n\n it(\"round-trips a self-contained cursor and rejects scope changes\", () => {\n const scope = { profileId: \"triplim\", startDate: \"2026-06-01\", endDate: \"2026-06-30\" };\n const cursor = encodeSalesReportCursor({\n ...scope,\n lastSaleTimestamp: \"2026-06-20T10:00:00-03:00\",\n lastOperationKey: \"200001\",\n });\n\n expect(decodeSalesReportCursor(cursor, scope)).toEqual({\n version: 1,\n ...scope,\n lastSaleTimestamp: \"2026-06-20T10:00:00-03:00\",\n lastOperationKey: \"200001\",\n });\n expect(() =>\n decodeSalesReportCursor(cursor, { ...scope, profileId: \"another-profile\" })\n ).toThrow(\"does not match the requested report scope\");\n });\n\n it(\"rejects cursor tampering\", () => {\n const scope = { profileId: \"triplim\", startDate: \"2026-06-01\", endDate: \"2026-06-30\" };\n const cursor = encodeSalesReportCursor({\n ...scope,\n lastSaleTimestamp: \"2026-06-20T10:00:00-03:00\",\n lastOperationKey: \"200001\",\n });\n const [payload, signature] = cursor.split(\".\");\n const tampered = `${payload.slice(0, -1)}${payload.endsWith(\"A\") ? \"B\" : \"A\"}.${signature}`;\n\n expect(() => decodeSalesReportCursor(tampered, scope)).toThrow(\"Invalid sales report cursor\");\n });\n\n it(\"keeps cursor continuation ordered by instants across offsets\", () => {\n const candidate = operation(\"300\", \"201\", \"2026-06-02T00:30:00-03:00\");\n expect(isSalesReportOperationAfterCursor(candidate, {\n lastSaleTimestamp: \"2026-06-02T00:00:00-04:00\",\n lastOperationKey: \"200\",\n })).toBe(true);\n });\n\n it(\"preserves null values while metadata marks unavailable fields\", () => {\n const item = operation(null, \"200\", \"2026-06-30T20:00:00-03:00\");\n const metadata = buildSalesReportMetadata({\n profileId: \"triplim\",\n startDate: \"2026-06-01\",\n endDate: \"2026-06-30\",\n currencies: [\"ARS\"],\n itemsReturned: 1,\n requestedLimit: 200,\n packsReturned: 0,\n ordersReturned: 1,\n partialSections: [\"facturacion_al_comprador\"],\n sourceCoverage: [\n { fuente: \"orders\", estado: \"complete\", solicitados: 1, obtenidos: 1, incidentes: 0 },\n { fuente: \"billing\", estado: \"unavailable\", solicitados: 1, obtenidos: 0, incidentes: 1 },\n ],\n fieldProvenance: [\n {\n campo: \"facturacion_al_comprador.factura_adjunta\",\n fuente: \"billing\",\n estado: \"unavailable\",\n detalle: \"Billing source was unavailable for this order.\",\n },\n ],\n scopedIncidents: [\n {\n fuente: \"billing\",\n alcance: \"order\",\n identificadores: [\"200\"],\n mensaje: \"Billing request failed.\",\n reintentable: true,\n },\n ],\n unsupportedFields: [\"facturacion_al_comprador.factura_adjunta\"],\n hasMore: false,\n });\n\n expect(item.ordenes[0].facturacion_al_comprador.factura_adjunta).toBeNull();\n expect(metadata.cobertura_completa).toBe(false);\n expect(metadata.campos_no_disponibles).toContain(\n \"facturacion_al_comprador.factura_adjunta\"\n );\n expect(metadata).not.toHaveProperty(\"procedencia_de_campos\");\n expect(metadata.cobertura_por_fuente).toContainEqual(\n expect.objectContaining({ fuente: \"billing\", estado: \"unavailable\" })\n );\n expect(metadata.incidentes_acotados).toContainEqual(\n expect.objectContaining({ fuente: \"billing\", identificadores: [\"200\"] })\n );\n expect(metadata.cursor_siguiente).toBeNull();\n expect(metadata.guia_de_continuacion).toBeNull();\n expect(metadata.motivo_del_corte).toBeNull();\n });\n\n it(\"provides explicit guidance when more operations remain\", () => {\n const metadata = buildSalesReportMetadata({\n profileId: \"triplim\",\n startDate: \"2026-06-01\",\n endDate: \"2026-06-30\",\n itemsReturned: 1,\n requestedLimit: 1,\n packsReturned: 0,\n ordersReturned: 1,\n hasMore: true,\n nextCursor: \"opaque-cursor\",\n });\n\n expect(metadata.guia_de_continuacion).toContain(\"cursor_siguiente\");\n expect(metadata.guia_de_continuacion).not.toContain(\"opaque-cursor\");\n });\n\n it(\"marks explicit selection metadata as non-paginated and date-independent\", () => {\n const metadata = buildSalesReportMetadata({\n profileId: \"triplim\",\n startDate: null,\n endDate: null,\n selectionMode: \"ordenes_explicitas\",\n explicitSelection: {\n ids_solicitados: [\"b\", \"a\", \"b\", \"missing\"],\n ids_unicos: [\"b\", \"a\", \"missing\"],\n cantidad_solicitada: 4,\n cantidad_unica: 3,\n cantidad_duplicada: 1,\n ids_resueltos: [\"b\", \"a\"],\n cantidad_resuelta: 2,\n ids_no_disponibles: [\"missing\"],\n cantidad_no_disponible: 1,\n },\n itemsReturned: 2,\n requestedLimit: null,\n packsReturned: 0,\n ordersReturned: 2,\n scopedIncidents: [{ fuente: \"orders\", alcance: \"order_selection\", identificadores: [\"missing\"], mensaje: \"Unavailable.\", reintentable: false }],\n hasMore: false,\n });\n expect(metadata).toEqual(expect.objectContaining({\n modo_seleccion: \"ordenes_explicitas\",\n fecha_desde: null,\n fecha_hasta: null,\n limite_solicitado: null,\n tiene_mas: false,\n cursor_siguiente: null,\n guia_de_continuacion: null,\n cobertura_completa: false,\n }));\n expect(metadata.seleccion_explicita).toEqual(expect.objectContaining({ cantidad_duplicada: 1, ids_resueltos: [\"b\", \"a\"] }));\n expect(metadata).not.toHaveProperty(\"procedencia_de_campos\");\n });\n\n it(\"derives unavailable field metadata from provenance\", () => {\n const metadata = buildSalesReportMetadata({\n profileId: \"triplim\",\n startDate: \"2026-06-01\",\n endDate: \"2026-06-30\",\n itemsReturned: 1,\n requestedLimit: 200,\n packsReturned: 0,\n ordersReturned: 1,\n fieldProvenance: [\n {\n campo: \"ventas.total_ars\",\n fuente: \"billing\",\n estado: \"unavailable\",\n detalle: \"Billing was unavailable.\",\n },\n ],\n hasMore: false,\n });\n\n expect(metadata.cobertura_completa).toBe(false);\n expect(metadata.campos_no_disponibles).toEqual([\"ventas.total_ars\"]);\n expect(metadata).not.toHaveProperty(\"procedencia_de_campos\");\n });\n\n it(\"plans bounded remaining pages from effective seed paging\", () => {\n expect(buildOrderUniversePagePlan({ total: 121, limit: 50, offset: 0 }, 100)).toEqual([50, 100]);\n expect(buildOrderUniversePagePlan({ total: 201, limit: 50, offset: 0 }, 200)).toEqual([50, 100, 150, 200]);\n expect(buildOrderUniversePagePlan({ total: 1000, limit: 50, offset: 0 }, 150, 2)).toEqual([50, 100]);\n });\n\n it(\"groups packs without splitting them and preserves explicit nulls\", () => {\n const first = { id: 1, pack_id: 9, date_created: \"2026-06-30T10:00:00-03:00\", total_amount: null };\n const second = { id: 2, pack_id: 9, date_created: \"2026-06-30T11:00:00-03:00\" };\n const standalone = { id: 3, date_created: \"2026-06-29T11:00:00-03:00\" };\n\n expect(groupMercadoLibreOrders([first, second, standalone]).map((item) => [item.pack_id, item.ordenes.map((order) => order.order_id)])).toEqual([\n [\"9\", [\"1\", \"2\"]],\n [null, [\"3\"]],\n ]);\n expect(groupMercadoLibreOrders([first])[0].ordenes[0].ventas.ingresos_por_productos_ars).toBeNull();\n });\n});\n"],
5
+ "mappings": "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",
6
+ "names": ["order"]
7
+ }