Compare commits

...
Author SHA1 Message Date
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
devops 7a09202c27 fix: forzar ISR en /product/[slug] para que no quede atascado en datos mock del build
generateStaticParams usa el catálogo mock en build time porque
HEADLESS_PROVIDER y MEDUSA_* no existen como build args del Dockerfile.
Sin un revalidate explícito, esa ruta queda estática para siempre con
price:null. El listado no sufre esto porque su ruta es dinámica por
searchParams.
2026-08-12 22:56:03 -05:00
devops a902dc0a26 chore: release v1.0.86 [skip ci] 2026-08-12 07:16:46 +00:00
devops 04dc6bd8bc Merge pull request 'fix: usar region_id en vez de currency_code para precios de Medusa' (#5) from fix/medusa-region-id-pricing into main
Build and Push Frontend / Construir y Subir Imagen (push) Successful in 9m9s
2026-08-12 07:03:28 +00:00
devops 60072cfcbe fix: usar region_id en vez de currency_code para precios de Medusa
El validador de /store/products (StoreGetProductsParams, .strict()) solo
acepta region_id/country_code/province/cart_id para resolver contexto de
precio -- currency_code como campo plano no existe y rompía con 400
"Unrecognized fields: 'currency_code'" en cada carga de /catalog.

country_code tampoco alcanza: probado en vivo, devuelve "Missing required
pricing context to calculate prices - region_id". Se necesita region_id
explícito.

Se agrega MEDUSA_REGION_ID (env var) apuntando a la región "Colombia"
(COP) creada vía Admin API, ya que no existía ninguna región configurada
en el backend.
2026-08-12 02:01:49 -05:00
devops c9b376c4e6 Merge pull request 'fix: conectar el frontend al catálogo real de Medusa' (#4) from fix/frontend-wire-medusa-catalog into main 2026-08-12 05:16:18 +00:00
5 changed files with 38 additions and 5 deletions
@@ -25,6 +25,16 @@ module.exports = defineConfig({
jwtSecret: required("JWT_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: {
@@ -9,6 +9,13 @@ import { getProductBySlug, getProducts } from "@/lib/headless/client";
interface ProductPageProps { params: Promise<{ slug: string }> }
// Sin esto, la página queda estática para siempre con los datos del build
// (que usa el catálogo mock porque HEADLESS_PROVIDER/MEDUSA_* no existen en
// el contexto del Docker build). El listado sí se refresca porque su ruta
// es dinámica por searchParams; esta ruta necesita el revalidate explícito
// para que el runtime (que sí tiene las env vars de Medusa) la regenere.
export const revalidate = 60;
export async function generateStaticParams() {
const products = await getProducts();
return products.map((product) => ({ slug: product.slug }));
+2 -2
View File
@@ -52,7 +52,7 @@ spec:
memory: 64Mi
- name: migrations
image: gitea.cruzcloud.net/devops/ecommerce-medusa:v1.0.85
image: gitea.cruzcloud.net/devops/ecommerce-medusa:v1.0.88
imagePullPolicy: IfNotPresent
command:
- npx
@@ -73,7 +73,7 @@ spec:
containers:
- name: medusa
image: gitea.cruzcloud.net/devops/ecommerce-medusa:v1.0.85
image: gitea.cruzcloud.net/devops/ecommerce-medusa:v1.0.88
imagePullPolicy: IfNotPresent
envFrom:
- configMapRef:
+3 -1
View File
@@ -16,7 +16,7 @@ spec:
- name: gitea-registry-secret
containers:
- name: web
image: gitea.cruzcloud.net/devops/ecommerce-frontend:v1.0.77
image: gitea.cruzcloud.net/devops/ecommerce-frontend:v1.0.87
ports:
- containerPort: 80
env:
@@ -24,6 +24,8 @@ spec:
value: medusa
- name: MEDUSA_BACKEND_URL
value: http://medusa-svc:9000
- name: MEDUSA_REGION_ID
value: reg_01KZT86WPAH7A7ZZRDSX3350V2
envFrom:
- secretRef:
name: commerce-storefront
@@ -258,6 +258,14 @@ function backendUrl(): string {
return value.replace(/\/$/, "");
}
function regionId(): string {
const value = process.env.MEDUSA_REGION_ID;
if (!value) {
throw new Error("MEDUSA_REGION_ID no está configurado.");
}
return value;
}
async function medusaFetch<T>(
path: string,
searchParams?: URLSearchParams,
@@ -515,7 +523,10 @@ async function fetchProducts(
): Promise<Product[]> {
const params = new URLSearchParams({
limit: String(limit),
currency_code: "cop",
// El validador de /store/products no acepta currency_code (400
// "Unrecognized fields"); el precio calculado solo se resuelve con
// region_id.
region_id: regionId(),
fields:
"+metadata,+images,+tags,+categories,+collection,+variants.inventory_quantity,+variants.calculated_price,+variants.options",
});
@@ -543,7 +554,10 @@ export const medusaCatalogProvider: CatalogProvider = {
const params = new URLSearchParams({
handle: slug,
limit: "1",
currency_code: "cop",
// El validador de /store/products no acepta currency_code (400
// "Unrecognized fields"); el precio calculado solo se resuelve con
// region_id.
region_id: regionId(),
fields:
"+metadata,+images,+tags,+categories,+collection,+variants.inventory_quantity,+variants.calculated_price,+variants.options",
});