Compare commits

...
Author SHA1 Message Date
devops 584a42ea72 Merge pull request 'fix(ecommerce): detalle de producto en dynamic render, no SSG+ISR stale' (#8) from fix/product-detail-static-mock-price into main
Build and Push Frontend / Construir y Subir Imagen (push) Successful in 5m55s
2026-08-13 07:02:11 +00:00
devopsandClaude Sonnet 5 a6a92f75ea fix(ecommerce): render product detail dynamically instead of stale SSG+ISR
Product detail pages were generateStaticParams'd at Docker build time,
where MEDUSA_* env vars aren't set, so the static snapshot baked in the
mock catalog (price: null for all products). With revalidate=60 and no
shared ISR cache handler across the 2 frontend replicas, each pod healed
its own cache independently on next visit past staleness — so a product
could show "Consultar precio" on one pod and the real price on the other,
while the fully-dynamic catalog listing always hit Medusa fresh. Verified
against the live Medusa API that pricing/region data itself was correct
for the reported failing products.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01DXqBoNfYQNwFg65mbx2FWM
2026-08-13 01:59:44 -05:00
devops 0eea6234d6 chore: release v1.0.87 [skip ci] 2026-08-13 00:24:20 -05:00
gitea-actions 77bf6089fb chore(gitops): deploy Medusa v1.0.88 [skip ci] 2026-08-13 05:01:13 +00:00
devops 0134a4dd0b Merge pull request 'fix: desactivar cookie Secure en sesion admin de Medusa' (#7) from fix/medusa-admin-session-cookie into main
Build and Push Medusa / Construir y publicar Medusa (push) Successful in 18m10s
2026-08-13 04:08:03 +00:00
devops 3fe63591ec Merge pull request 'fix: forzar ISR en /product/[slug] para que no quede atascado en mock' (#6) from fix/product-page-static-mock-price into main
Build and Push Frontend / Construir y Subir Imagen (push) Successful in 7m12s
2026-08-13 04:04:40 +00:00
devops c6cf394c26 fix: desactivar cookie Secure en sesion admin de Medusa
Todos los Ingress del lab terminan en Traefik por HTTP plano (entrypoint
web, sin TLS); Cloudflare es quien atiende HTTPS de cara al navegador.
Con secure:true (default en produccion), express-session nunca emite
Set-Cookie porque no detecta la conexion como HTTPS, dejando el
dashboard admin con 401 en /admin/users/me pese a loguear bien.
2026-08-12 23:01:35 -05:00
4 changed files with 24 additions and 14 deletions
@@ -25,6 +25,16 @@ module.exports = defineConfig({
jwtSecret: required("JWT_SECRET"), jwtSecret: required("JWT_SECRET"),
cookieSecret: required("COOKIE_SECRET"), cookieSecret: required("COOKIE_SECRET"),
}, },
// Todos los Ingress del lab terminan en Traefik por HTTP plano
// (entrypoint "web", sin TLS); Cloudflare es quien atiende HTTPS de
// cara al navegador. Con `secure: true` (el default en producción),
// express-session nunca emite Set-Cookie porque no detecta la
// conexión como HTTPS, y el dashboard admin queda con 401 en
// /admin/users/me pese a loguear bien. La API con Bearer token no se
// ve afectada por esto.
cookieOptions: {
secure: false,
},
}, },
admin: { admin: {
+11 -11
View File
@@ -9,17 +9,17 @@ import { getProductBySlug, getProducts } from "@/lib/headless/client";
interface ProductPageProps { params: Promise<{ slug: string }> } interface ProductPageProps { params: Promise<{ slug: string }> }
// Sin esto, la página queda estática para siempre con los datos del build // generateStaticParams + revalidate quedaban aquí para pre-renderizar en
// (que usa el catálogo mock porque HEADLESS_PROVIDER/MEDUSA_* no existen en // build time, pero HEADLESS_PROVIDER/MEDUSA_* no existen en el contexto del
// el contexto del Docker build). El listado sí se refresca porque su ruta // Docker build: el snapshot estático quedaba congelado con el catálogo mock
// es dinámica por searchParams; esta ruta necesita el revalidate explícito // (todos los productos con price: null) hasta que ISR lo revalidara. Con
// para que el runtime (que sí tiene las env vars de Medusa) la regenere. // frontend-deploy corriendo 2 réplicas y sin cacheHandler compartido, cada
export const revalidate = 60; // pod revalida su propia caché de forma independiente, así que un producto
// podía mostrar "Consultar precio" en un pod y el precio real en el otro
export async function generateStaticParams() { // según cuál hubiera sido "calentado". force-dynamic elimina esa caché por
const products = await getProducts(); // pod y deja esta ruta en vivo contra Medusa, igual que el listado
return products.map((product) => ({ slug: product.slug })); // (dinámico por searchParams).
} export const dynamic = "force-dynamic";
export async function generateMetadata({ params }: ProductPageProps): Promise<Metadata> { export async function generateMetadata({ params }: ProductPageProps): Promise<Metadata> {
const { slug } = await params; const { slug } = await params;
+2 -2
View File
@@ -52,7 +52,7 @@ spec:
memory: 64Mi memory: 64Mi
- name: migrations - name: migrations
image: gitea.cruzcloud.net/devops/ecommerce-medusa:v1.0.85 image: gitea.cruzcloud.net/devops/ecommerce-medusa:v1.0.88
imagePullPolicy: IfNotPresent imagePullPolicy: IfNotPresent
command: command:
- npx - npx
@@ -73,7 +73,7 @@ spec:
containers: containers:
- name: medusa - name: medusa
image: gitea.cruzcloud.net/devops/ecommerce-medusa:v1.0.85 image: gitea.cruzcloud.net/devops/ecommerce-medusa:v1.0.88
imagePullPolicy: IfNotPresent imagePullPolicy: IfNotPresent
envFrom: envFrom:
- configMapRef: - configMapRef:
+1 -1
View File
@@ -16,7 +16,7 @@ spec:
- name: gitea-registry-secret - name: gitea-registry-secret
containers: containers:
- name: web - name: web
image: gitea.cruzcloud.net/devops/ecommerce-frontend:v1.0.86 image: gitea.cruzcloud.net/devops/ecommerce-frontend:v1.0.87
ports: ports:
- containerPort: 80 - containerPort: 80
env: env: