Compare commits

...
Author SHA1 Message Date
devops 4afc63bdc6 docs(adr): nota de implementacion 2 -- hallazgos del gate en vivo de Fase 2 2026-08-26 17:12:10 -05:00
devops 41c7ad25e7 Merge fix/adr0006-etapa2-fase2-currency-code-search into main
Build and Push Medusa / Escaneo de Secretos (Gitleaks) (push) Successful in 18s
Build and Push Medusa / Construir y publicar Medusa (push) Successful in 11m17s
2026-08-26 16:52:06 -05:00
devops 2056e6c766 Fase 2 fix: /store/search resuelve currency_code, no solo region_id
Confirmado en vivo: pasar solo region_id a QueryContext no alcanza --
"Method calculatePrices requires currency_code in the pricing
context" persistia. A diferencia de /store/products nativo (resuelto
por el middleware setPricingContext), esta ruta propia no pasa por esa
cadena, asi que resuelve la moneda real de la region con un
query.graph adicional antes de pedir calculated_price -- no asume COP
fijo por si el catalogo suma otra region/moneda despues.
2026-08-26 16:52:04 -05:00
gitea-actions f2377be69c chore(gitops): deploy Medusa v1.0.167 [skip ci] 2026-08-26 21:44:33 +00:00
devops d6b84e4480 Merge fix/adr0006-etapa2-fase2-region-id-search into main
Build and Push Medusa / Escaneo de Secretos (Gitleaks) (push) Successful in 24s
Build and Push Medusa / Construir y publicar Medusa (push) Successful in 12m49s
2026-08-26 16:31:24 -05:00
devops f8f540af6a Fase 2 fix: /store/search acepta region_id para calculated_price
Mismo error encontrado en el gate de verificacion, ahora en la ruta
propia en vez del job de sync: "Method calculatePrices requires
currency_code in the pricing context" -- query.graph necesita
region_id/currency_code en el contexto para resolver
variants.calculated_price. El storefront ya manda region_id contra
/store/products (medusa.ts, regionId()); esta ruta ahora acepta el
mismo query param y arma el contexto de pricing con QueryContext(),
igual que la ruta oficial /store/meilisearch/products del plugin.
2026-08-26 16:31:21 -05:00
gitea-actions 51eadd98dc chore(gitops): deploy Medusa v1.0.166 [skip ci] 2026-08-26 21:23:08 +00:00
devops fbf0aec892 Merge fix/adr0006-etapa2-fase2-precio-crudo-indexado into main
Build and Push Medusa / Escaneo de Secretos (Gitleaks) (push) Successful in 29s
Build and Push Medusa / Construir y publicar Medusa (push) Successful in 17m43s
2026-08-26 16:05:03 -05:00
devops e3eca46e0e Fase 2 fix: indexar precio crudo (variants.prices), no calculated_price
Encontrado en vivo (gate de verificacion de Fase 2): el job de sync
inicial del plugin fallaba en TODOS los productos con "Method
calculatePrices requires currency_code in the pricing context" --
variants.calculated_price necesita region_id/currency_code en el
contexto de query.graph, que el workflow interno del plugin
(sync-products.js) no provee. Las categorias si indexaron bien (21),
solo productos fallaba, por eso numberOfDocuments quedaba en 0 pese a
que el indice y sus settings se crearon correctamente.

variants.prices (lista cruda, sin resolver promociones/reglas de
precio) no requiere ese contexto y alcanza para el filtro/orden por
precio de la busqueda -- no necesitamos el precio final promocional
ahi, esa resolucion ya la hace la ruta /store/search via query.graph
con el contexto real al re-hidratar los productos.
2026-08-26 16:04:59 -05:00
gitea-actions 586313d6d7 chore(gitops): deploy Medusa v1.0.165 [skip ci] 2026-08-26 20:56:17 +00:00
devops 77a15c26b1 Merge fix/adr0006-etapa2-fase2-plugin-medusa into main
Build and Push Medusa / Escaneo de Secretos (Gitleaks) (push) Successful in 19s
Build and Push Medusa / Construir y publicar Medusa (push) Successful in 16m14s
2026-08-26 15:39:41 -05:00
gitea-actions 8cd43a2584 chore(gitops): deploy Docs Portal v1.0.164 [skip ci] 2026-08-26 20:06:30 +00:00
5 changed files with 92 additions and 10 deletions

No files matched your search

+19 -6
View File
@@ -47,7 +47,10 @@ async function meilisearchProductTransformer(
inventory_quantity?: number | null
manage_inventory?: boolean | null
allow_backorder?: boolean | null
calculated_price?: { calculated_amount?: number | null } | null
prices?: Array<{
amount?: number | null
currency_code?: string | null
}> | null
}>
| null
| undefined
@@ -63,6 +66,18 @@ async function meilisearchProductTransformer(
variant.manage_inventory === false ||
(variant.inventory_quantity ?? 0) > 0
// variants.calculated_price requiere currency_code/region_id en el
// contexto de pricing, que el workflow de sync interno del plugin no
// provee -- hace fallar TODO el job de indexado (confirmado en vivo:
// "Method calculatePrices requires currency_code in the pricing
// context"). variants.prices es la lista cruda de precios (sin
// resolver promociones/reglas), no necesita contexto -- alcanza para
// el filtro/orden por precio en la busqueda, que no necesita el
// precio final promocional.
const copPrice = variant?.prices?.find(
(price) => price.currency_code?.toLowerCase() === "cop",
)
return {
id: document.id,
name: document.title || "Producto ARI Shopping",
@@ -73,10 +88,7 @@ async function meilisearchProductTransformer(
brand: stringMetadata(metadata, "brand") || "ARI Shopping",
ageRange: stringMetadata(metadata, "ageRange") || "Todas",
tags: (tags || []).map((tag) => tag.value).filter(Boolean),
price:
typeof variant?.calculated_price?.calculated_amount === "number"
? variant.calculated_price.calculated_amount
: null,
price: typeof copPrice?.amount === "number" ? copPrice.amount : null,
available,
isNew: booleanMetadata(metadata, "isNew"),
featured: booleanMetadata(metadata, "featured"),
@@ -184,7 +196,8 @@ module.exports = defineConfig({
"variants.inventory_quantity",
"variants.manage_inventory",
"variants.allow_backorder",
"variants.calculated_price.calculated_amount",
"variants.prices.amount",
"variants.prices.currency_code",
],
indexSettings: {
// Tabla de ADR 0006 §3: Buscable / Filtrable-faceta / Ordenable.
@@ -1,5 +1,8 @@
import type { MedusaRequest, MedusaResponse } from "@medusajs/framework";
import { ContainerRegistrationKeys } from "@medusajs/framework/utils";
import {
ContainerRegistrationKeys,
QueryContext,
} from "@medusajs/framework/utils";
import {
MEILISEARCH_MODULE,
type MeiliSearchService,
@@ -76,6 +79,13 @@ export async function GET(req: MedusaRequest, res: MedusaResponse) {
const q = stringParam(req.query, "q") ?? "";
const limit = numberParam(req.query, "limit") ?? 24;
const offset = numberParam(req.query, "offset") ?? 0;
// calculated_price exige region_id/currency_code en el contexto de
// pricing o query.graph tira "Method calculatePrices requires
// currency_code in the pricing context" (mismo error que ya rompio el
// job de sync -- ver medusa-config.ts). El storefront ya manda
// region_id contra /store/products (medusa.ts, regionId()); esta ruta
// espera el mismo query param.
const regionId = stringParam(req.query, "region_id");
const filterParts: string[] = [];
for (const facet of ["category", "collection", "brand", "ageRange"]) {
@@ -139,10 +149,36 @@ export async function GET(req: MedusaRequest, res: MedusaResponse) {
return;
}
// calculatePrices exige currency_code en el contexto -- no alcanza con
// region_id solo (a diferencia de /store/products nativo, que lo
// resuelve el middleware setPricingContext; esta ruta no pasa por esa
// cadena). Resolvemos la moneda real de la region en vez de asumir COP
// fijo, por si el catalogo suma otra region/moneda mas adelante.
let currencyCode: string | undefined;
if (regionId) {
const { data: regions = [] } = await query.graph({
entity: "region",
fields: ["id", "currency_code"],
filters: { id: regionId },
});
currencyCode = regions[0]?.currency_code;
}
const { data: products = [] } = await query.graph({
entity: "product",
fields: PRODUCT_FIELDS,
filters: { id: productIds },
context:
regionId && currencyCode
? {
variants: {
calculated_price: QueryContext({
region_id: regionId,
currency_code: currencyCode,
}),
},
}
: {},
});
// Preserva el ranking de relevancia de Meilisearch -- query.graph no
@@ -295,3 +295,36 @@ desviaciones reales respecto al diseño de §4/§5 de este ADR:
Ninguna de las tres cambia la decisión ni sus consecuencias — cambian
el cómo, no el qué. Plan de implementación completo, fase por fase,
en la sesión que aprobó esta Etapa 2 (2026-08-26).
## Nota de implementación 2 (2026-08-26, gate en vivo de Fase 2)
Dos bugs reales encontrados y corregidos durante el gate de
verificación en vivo (crear/editar productos, categoría y colección
reales y confirmar que llegan a Meilisearch), ambos con la misma causa
raíz: `variants.calculated_price` de Medusa exige `region_id` **y**
`currency_code` resueltos en el contexto de pricing de la consulta, y
ninguno de los dos caminos nuevos de este ADR pasa por el middleware
nativo (`setPricingContext`) que se lo da gratis a `/store/products`:
1. El job de sync inicial del plugin (`sync-products.js`, corre una
vez al boot) hacía fallar el indexado de **todos** los productos
con `Method calculatePrices requires currency_code in the pricing
context` — las categorías sí indexaban bien (no llevan precio).
Arreglado indexando el precio crudo (`variants.prices`, sin
resolver promociones/reglas) en vez de `calculated_price` — alcanza
para el filtro/orden por precio de la búsqueda.
2. La ruta propia `/store/search` pegaba el mismo error al re-hidratar
productos vía `query.graph`. Pasar `region_id` solo no alcanzó;
hubo que resolver el `currency_code` real de la región con una
consulta adicional antes de armar el `QueryContext`.
Confirmado en vivo, con el fix aplicado: búsqueda por texto, facetas
sobre las 27 unidades del catálogo real, y precio calculado correcto
(`calculated_amount`/`currency_code`) en la respuesta de
`/store/search`. También confirmado en vivo que los tres eventos que
el ADR original marcaba como "verificar, no asumir" — `product.*`,
`product-category.*` y **`product-collection.updated`** (el que tenía
un reporte público de no disparar siempre) — sí sincronizan de forma
confiable en esta combinación exacta (Medusa 2.18.0 + plugin 1.4.1),
propagando un rename de categoría/colección al documento indexado en
menos de 10 segundos.
@@ -25,7 +25,7 @@ spec:
runAsNonRoot: false
containers:
- name: app
image: gitea.cruzcloud.net/devops/docs-portal:v1.0.162
image: gitea.cruzcloud.net/devops/docs-portal:v1.0.164
# El base saca TODAS las capabilities. Probado en vivo y
# revertido: con drop: ALL (aunque se agregue NET_BIND_SERVICE
# de vuelta) el propio entrypoint de nginx:1.27-alpine falla al
@@ -65,7 +65,7 @@ spec:
memory: 64Mi
- name: migrations
image: gitea.cruzcloud.net/devops/ecommerce-medusa:v1.0.127
image: gitea.cruzcloud.net/devops/ecommerce-medusa:v1.0.167
imagePullPolicy: IfNotPresent
command:
- node
@@ -86,7 +86,7 @@ spec:
containers:
- name: app
image: gitea.cruzcloud.net/devops/ecommerce-medusa:v1.0.127
image: gitea.cruzcloud.net/devops/ecommerce-medusa:v1.0.167
imagePullPolicy: IfNotPresent
envFrom:
- configMapRef: