From 2daf920c01d3ffe7d943c102250e84baab27913b Mon Sep 17 00:00:00 2001 From: adevopg Date: Wed, 15 Jul 2026 08:31:57 +0000 Subject: [PATCH] =?UTF-8?q?store:=20nombres=20de=20=C3=ADtem=20en=20el=20i?= =?UTF-8?q?dioma=20de=20la=20web=20(desde=20home=5Fitem=5Fdata)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit El catálogo original solo tiene el nombre en español, así que /en/store venía mostrando los ítems en español. Ahora salen de `home_item_data` (extraída de los DB2 del cliente, commit 4ba9c42), que es el único sitio con el nombre en inglés. - getStoreCatalog(locale) hace LEFT JOIN con home_item_data y elige name_es o name_en. Si falta el nombre en ese idioma se cae al del catálogo, que siempre está, así que ningún ítem puede quedarse sin nombre. - La columna se elige de una lista cerrada ('en' -> name_en, resto -> name_es): nunca se interpola el locale crudo, que viene de la URL. - /api/store/catalog recibe el locale por query: la ruta no cuelga de [locale]. Verificado en los dos idiomas: 45327 sale "Grito de la sirena" en /es y "Siren's Cry" en /en. El árbol sigue devolviendo las 3068 filas y ninguna sin nombre (el JOIN no duplica: `entry` es clave primaria). Pendiente: los nombres de las CATEGORÍAS siguen solo en español (home_store_category.name), así que /en/store se ve a medias. No son datos del juego, así que los DB2 no ayudan: hay que traducir 218 nombres distintos. Co-Authored-By: Claude Opus 4.8 (1M context) --- web-next/app/api/store/catalog/route.ts | 8 ++++++-- web-next/components/StoreBrowser.tsx | 2 +- web-next/lib/store.ts | 20 +++++++++++++++++--- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/web-next/app/api/store/catalog/route.ts b/web-next/app/api/store/catalog/route.ts index 990de2d..235e972 100644 --- a/web-next/app/api/store/catalog/route.ts +++ b/web-next/app/api/store/catalog/route.ts @@ -2,11 +2,15 @@ import { getSession } from '@/lib/session' import { getStoreCatalog } from '@/lib/store' /** Árbol de la tienda (categorías + ítems). Se carga tras elegir personaje. */ -export async function GET() { +export async function GET(request: Request) { const session = await getSession() if (!session.accountId || !session.username) { return Response.json({ success: false, error: 'notAuthenticated' }, { status: 401 }) } - const catalog = await getStoreCatalog() + // El idioma lo manda el cliente: esta ruta no cuelga de [locale]. Decide en qué + // idioma salen los nombres de los ítems; getStoreCatalog solo distingue 'en' + // del resto, así que un valor inesperado cae en español. + const locale = new URL(request.url).searchParams.get('locale') ?? 'es' + const catalog = await getStoreCatalog(locale) return Response.json({ success: true, catalog }) } diff --git a/web-next/components/StoreBrowser.tsx b/web-next/components/StoreBrowser.tsx index d36c270..23a13d5 100644 --- a/web-next/components/StoreBrowser.tsx +++ b/web-next/components/StoreBrowser.tsx @@ -140,7 +140,7 @@ export function StoreBrowser({ if (!name || catalog) return setLoading(true) try { - const res = await fetch('/api/store/catalog', { credentials: 'same-origin' }) + const res = await fetch(`/api/store/catalog?locale=${encodeURIComponent(locale)}`, { credentials: 'same-origin' }) const data: { success?: boolean; catalog?: StoreCategory[] } = await res.json() setCatalog(data.success ? data.catalog ?? [] : []) } catch { diff --git a/web-next/lib/store.ts b/web-next/lib/store.ts index 6310eb3..54af645 100644 --- a/web-next/lib/store.ts +++ b/web-next/lib/store.ts @@ -54,8 +54,18 @@ interface ItemRow extends RowDataPacket { sort: number } -/** Árbol completo de la tienda (categorías anidadas con sus ítems en las hojas). */ -export async function getStoreCatalog(): Promise { +/** + * Árbol completo de la tienda (categorías anidadas con sus ítems en las hojas). + * + * El nombre del ítem sale de `home_item_data` (extraído de los DB2 del cliente + * 3.4.3, ver sql/db2/), que es el ÚNICO sitio con el nombre en inglés: el + * `home_store_item.name` del catálogo original es solo español. Si falta el + * nombre en ese idioma se cae al del catálogo, que siempre está. + */ +export async function getStoreCatalog(locale: string): Promise { + // Solo se interpola el nombre de la COLUMNA, y sale de una lista cerrada: + // nunca del locale crudo (que viene de la URL). + const nameCol = locale === 'en' ? 'name_en' : 'name_es' let cats: CatRow[] = [] let items: ItemRow[] = [] try { @@ -63,7 +73,11 @@ export async function getStoreCatalog(): Promise { 'SELECT code, parent_code, name, depth, sort FROM home_store_category ORDER BY sort', ) ;[items] = await db(DB.default).query( - 'SELECT id, category_code, item_id, name, icon, quantity, currency, price, preview, sort FROM home_store_item ORDER BY sort', + `SELECT i.id, i.category_code, i.item_id, COALESCE(NULLIF(d.${nameCol}, ''), i.name) AS name, + i.icon, i.quantity, i.currency, i.price, i.preview, i.sort + FROM home_store_item i + LEFT JOIN home_item_data d ON d.entry = i.item_id + ORDER BY i.sort`, ) } catch { return []