Compare commits

...
2 Commits
Author SHA1 Message Date
devops a1d2f9db67 Merge pull request 'feat(ecommerce): revalidar el storefront al instante tras editar precios' (#9) from fix/medusa-price-instant-revalidate into main
Build and Push Medusa / Construir y publicar Medusa (push) Successful in 15m24s
Build and Push Frontend / Construir y Subir Imagen (push) Successful in 7m39s
2026-08-13 21:06:13 +00:00
devops d1a4a84d24 feat(ecommerce): revalidar el storefront al instante tras editar precios
Antes el precio actualizado en Medusa tardaba hasta ~60s (o más, con
varias réplicas del frontend sin cache handler compartido) en verse en
el front, por el revalidate:60 del fetch a /store/products.

Ahora:
- Nueva ruta app/api/revalidate en el storefront que llama a
  revalidateTag("medusa-products") al recibir un POST autenticado con
  el header x-revalidate-secret.
- Nuevo subscriber en el backend Medusa (product.updated,
  product-variant.updated/created/deleted) que llama a esa ruta usando
  STOREFRONT_URL (ya existe en commerce-config) y un REVALIDATE_SECRET
  compartido entre ambos servicios.
- secrets.template.yaml documenta la nueva clave REVALIDATE_SECRET en
  commerce-secrets y commerce-storefront (mismo valor en ambos).

Requiere reaplicar commerce-secrets y commerce-storefront con el script
actualizado en el repo scripts (fix/revalidate-secret-scripts) para que
el REVALIDATE_SECRET exista en el cluster.
2026-08-13 16:02:49 -05:00
3 changed files with 65 additions and 0 deletions
@@ -0,0 +1,44 @@
import type { SubscriberArgs, SubscriberConfig } from "@medusajs/framework";
import { ContainerRegistrationKeys } from "@medusajs/framework/utils";
export default async function revalidateStorefrontHandler({
container,
}: SubscriberArgs) {
const logger = container.resolve(ContainerRegistrationKeys.LOGGER);
const storefrontUrl = process.env.STOREFRONT_URL;
const secret = process.env.REVALIDATE_SECRET;
if (!storefrontUrl || !secret) {
logger.warn(
"STOREFRONT_URL o REVALIDATE_SECRET no configurados; se omite la revalidación del storefront.",
);
return;
}
try {
const response = await fetch(`${storefrontUrl}/api/revalidate`, {
method: "POST",
headers: { "x-revalidate-secret": secret },
});
if (!response.ok) {
logger.warn(
`Revalidación del storefront respondió HTTP ${response.status}.`,
);
}
} catch (error) {
logger.warn(
`No se pudo revalidar el storefront: ${(error as Error).message}`,
);
}
}
export const config: SubscriberConfig = {
event: [
"product.updated",
"product-variant.updated",
"product-variant.created",
"product-variant.deleted",
],
};
@@ -0,0 +1,13 @@
import { revalidateTag } from "next/cache";
export async function POST(request: Request) {
const secret = request.headers.get("x-revalidate-secret");
if (!secret || secret !== process.env.REVALIDATE_SECRET) {
return Response.json({ message: "Invalid secret" }, { status: 401 });
}
revalidateTag("medusa-products");
return Response.json({ revalidated: true, tag: "medusa-products" }, { status: 200 });
}
@@ -22,6 +22,11 @@ stringData:
JWT_SECRET: CAMBIAR
COOKIE_SECRET: CAMBIAR
# Debe ser el MISMO valor que REVALIDATE_SECRET en el Secret
# commerce-storefront: el subscriber de Medusa lo envía como header
# x-revalidate-secret al invocar POST /api/revalidate en el storefront.
REVALIDATE_SECRET: CAMBIAR
---
apiVersion: v1
kind: Secret
@@ -30,3 +35,6 @@ metadata:
type: Opaque
stringData:
MEDUSA_PUBLISHABLE_KEY: pk_CAMBIAR_DESPUES_DE_CREARLA_EN_MEDUSA
# Mismo valor que REVALIDATE_SECRET en commerce-secrets.
REVALIDATE_SECRET: CAMBIAR