From cccc70338db8ea95da299bca504b2caed14c9964 Mon Sep 17 00:00:00 2001 From: adevopg Date: Wed, 15 Jul 2026 14:49:19 +0000 Subject: [PATCH] Quitar el prefijo home_ de las 41 tablas del portal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit El prefijo venía del nombre de la app Django (`home`), jubilada y borrada hoy, así que ya no significaba nada: home_stripelog -> stripelog. La BD se sigue llamando django_wow por historia (renombrarla es otra operación). Comprobado antes de tocar nada: 0 colisiones con nombres existentes, 0 palabras reservadas (contrastado contra las 260 de MySQL), sin vistas ni triggers que dependieran de ellas. El RENAME va en una sola sentencia porque así es atómico, y MySQL reapunta solo las 4 claves ajenas entre estas tablas. 170 referencias actualizadas en 37 ficheros. Se dejó a propósito sql/drop_home_securitytoken_authuser_fk.sql sin tocar: es una migración ya aplicada y reescribirla sería falsear el historial. De paso salió un fallo previo: prices.ts consultaba `home_restoreitemprice`, una tabla que NO existe. El try/catch de priceFrom se comía el error y devolvía siempre el precio por defecto, así que el precio de restaurar objetos nunca fue configurable. Se deja documentado en el código; crear la tabla es otra decisión. Verificado tras aplicar: 0 tablas home_, las 51 siguen ahí, y el conteo exacto de filas cuadra con el volcado previo (store_item 3068, item_data 44873, stripelog 35, store_order 26, noticia 50). La web responde 200 en todas las rutas y la portada carga las noticias sin errores. Co-Authored-By: Claude Opus 4.8 (1M context) --- README.md | 6 +-- sql/rename_home_prefix.sql | 52 +++++++++++++++++++ sql/seed_news.sql | 6 +-- sql/seed_recruit_rewards.sql | 4 +- .../app/[locale]/content-creators/page.tsx | 2 +- web-next/app/[locale]/security-token/page.tsx | 2 +- web-next/lib/account.ts | 6 +-- web-next/lib/admin-gold.ts | 6 +-- web-next/lib/admin-news.ts | 8 +-- web-next/lib/admin-prices.ts | 12 ++--- web-next/lib/admin-promo.ts | 12 ++--- web-next/lib/admin-recruit.ts | 6 +-- web-next/lib/admin-votes.ts | 6 +-- web-next/lib/change-email.ts | 12 ++--- web-next/lib/character-services.ts | 4 +- web-next/lib/content-creator.ts | 4 +- web-next/lib/dpoints.ts | 28 +++++----- web-next/lib/home.ts | 4 +- web-next/lib/paid-services.ts | 4 +- web-next/lib/points-history.ts | 18 +++---- web-next/lib/prices.ts | 19 ++++--- web-next/lib/promo.ts | 8 +-- web-next/lib/quest-tracker.ts | 4 +- web-next/lib/recover.ts | 10 ++-- web-next/lib/recruit-claim.ts | 10 ++-- web-next/lib/register.ts | 8 +-- web-next/lib/restore-character.ts | 4 +- web-next/lib/restore-items.ts | 4 +- web-next/lib/security-history.ts | 8 +-- web-next/lib/security-token.ts | 10 ++-- web-next/lib/store-pricing.ts | 2 +- web-next/lib/store.ts | 38 +++++++------- web-next/lib/stripe.ts | 10 ++-- web-next/lib/sumup.ts | 12 ++--- web-next/lib/trade.ts | 18 +++---- web-next/lib/trans-history.ts | 6 +-- web-next/lib/transfer-character.ts | 2 +- web-next/lib/tx-concept.ts | 6 +-- web-next/lib/vote.ts | 16 +++--- 39 files changed, 226 insertions(+), 171 deletions(-) create mode 100644 sql/rename_home_prefix.sql diff --git a/README.md b/README.md index 3537579..d78248f 100644 --- a/README.md +++ b/README.md @@ -7,9 +7,9 @@ Portal web para un servidor de World of Warcraft 3.4.3 basado en AzerothCore. - **Bases de datos (MySQL):** `django_wow` (la del portal), `acore_auth`, `acore_characters`, `acore_world` y `acore_web` (el foro) -> La base del portal se sigue llamando `django_wow` y sus tablas `home_*` por motivos históricos: el -> portal era una app Django, jubilada el 2026-07-15. El código se borró (está en el historial de git), -> pero **las tablas son las mismas y siguen en uso**: Next las consulta con SQL directo, sin ORM. +> La base del portal se sigue llamando `django_wow` por motivos históricos: el portal era una app +> Django, jubilada el 2026-07-15. Sus tablas llevaban el prefijo `home_` (el nombre de la app) y se +> renombraron sin él (`home_stripelog` → `stripelog`). Next las consulta con SQL directo, sin ORM. --- diff --git a/sql/rename_home_prefix.sql b/sql/rename_home_prefix.sql new file mode 100644 index 0000000..284dcf4 --- /dev/null +++ b/sql/rename_home_prefix.sql @@ -0,0 +1,52 @@ +-- Quitar el prefijo `home_` de las tablas del portal (2026-07-15). APLICADO EN PROD. +-- +-- El prefijo venía del nombre de la app Django (`home`), jubilada y borrada ese +-- mismo día. La BD se sigue llamando `django_wow` por historia. +-- +-- Va en UNA sola sentencia a propósito: RENAME TABLE con varias tablas es +-- atómico, así que o cambian las 41 o no cambia ninguna. MySQL reajusta solo +-- las claves ajenas que apuntaban a los nombres viejos. +-- +-- Se comprobó antes: 0 colisiones, 0 palabras reservadas, sin vistas ni triggers. + +RENAME TABLE `home_accountactivation` TO `accountactivation`, + `home_api_points` TO `api_points`, + `home_category` TO `category`, + `home_changefactionprice` TO `changefactionprice`, + `home_changeraceprice` TO `changeraceprice`, + `home_claimedreward` TO `claimedreward`, + `home_clientecategoria` TO `clientecategoria`, + `home_contentcreator` TO `contentcreator`, + `home_customizeprice` TO `customizeprice`, + `home_downloadclientpage` TO `downloadclientpage`, + `home_goldprice` TO `goldprice`, + `home_guildrenamesettings` TO `guildrenamesettings`, + `home_item` TO `item`, + `home_item_data` TO `item_data`, + `home_itemsearchhistory` TO `itemsearchhistory`, + `home_levelupprice` TO `levelupprice`, + `home_loginattempt` TO `loginattempt`, + `home_maintenancemode` TO `maintenancemode`, + `home_noticia` TO `noticia`, + `home_passwordreset` TO `passwordreset`, + `home_pedido` TO `pedido`, + `home_promocode` TO `promocode`, + `home_promoredemption` TO `promoredemption`, + `home_questsearchhistory` TO `questsearchhistory`, + `home_recruitafriend` TO `recruitafriend`, + `home_recruitreward` TO `recruitreward`, + `home_renameprice` TO `renameprice`, + `home_restorehistory` TO `restorehistory`, + `home_revivehistory` TO `revivehistory`, + `home_securitytoken` TO `securitytoken`, + `home_serverselection` TO `serverselection`, + `home_sistemaoperativo` TO `sistemaoperativo`, + `home_store_category` TO `store_category`, + `home_store_item` TO `store_item`, + `home_store_order` TO `store_order`, + `home_stripelog` TO `stripelog`, + `home_tradecode` TO `tradecode`, + `home_transferprice` TO `transferprice`, + `home_unstuckhistory` TO `unstuckhistory`, + `home_votelog` TO `votelog`, + `home_votesite` TO `votesite`; diff --git a/sql/seed_news.sql b/sql/seed_news.sql index 7e61e23..1752ff5 100644 --- a/sql/seed_news.sql +++ b/sql/seed_news.sql @@ -1,4 +1,4 @@ --- Siembra de las 50 noticias reales de NovaWoW/UltimoWoW en django_wow.home_noticia. +-- Siembra de las 50 noticias reales de NovaWoW/UltimoWoW en django_wow.noticia. -- Aplicar: mysql django_wow < sql/seed_news.sql (BD por defecto del portal). -- fecha_publicacion = fecha del post a las 12:00 menos N segundos por índice -- (preserva el orden de la lista dentro de una misma fecha). enlace = NULL @@ -7,8 +7,8 @@ -- cualquier noticia añadida después (p. ej. desde /admin/news). Quita esa -- línea si solo quieres añadir estas sin borrar las existentes. SET NAMES utf8mb4; -DELETE FROM home_noticia; -INSERT INTO home_noticia (titulo, contenido, fecha_publicacion, enlace) VALUES +DELETE FROM noticia; +INSERT INTO noticia (titulo, contenido, fecha_publicacion, enlace) VALUES ('FESTIVAL DE FUEGO DEL SOLSTICIO DE VERANO 🌞','Ha comenzado el evento Festival de Fuego del Solsticio de Verano que finaliza el día 5 de Julio.
Dispones de una guía completa aquí.','2026-06-21 12:00:00',NULL), ('10.ª TEMPORADA DE ARENAS ⚔️','¡La 10.ª Temporada de Arenas ⚔️ ya está en marcha y una nueva batalla por la gloria ha comenzado!
Durante los próximos meses, los mejores combatientes del reino se enfrentarán en intensos encuentros para escalar posiciones y luchar por las recompensas más prestigiosas.

¡Forma equipo, entra en combate y demuestra de qué eres capaz!
Toda la información disponible aquí.','2026-06-08 11:59:59',NULL), ('RESULTADOS FINALES DE LA 8.ª TEMPORADA DE ARENAS ⚔️','El pasado 8 de diciembre de 2025 finalizó nuestra 8.ª Temporada de Arenas y ya se encuentran disponibles los resultados oficiales.
En la publicación podrás consultar el listado completo de equipos y jugadores clasificados.
Toda la información disponible aquí.','2026-06-08 11:59:58',NULL), diff --git a/sql/seed_recruit_rewards.sql b/sql/seed_recruit_rewards.sql index 2296f73..5e359ca 100644 --- a/sql/seed_recruit_rewards.sql +++ b/sql/seed_recruit_rewards.sql @@ -1,7 +1,7 @@ --- Recompensas de Recluta a un amigo (home_recruitreward) para el panel de /recruit. +-- Recompensas de Recluta a un amigo (recruitreward) para el panel de /recruit. -- Aplicar: mysql django_wow < sql/seed_recruit_rewards.sql SET NAMES utf8mb4; -INSERT INTO home_recruitreward (required_friends, reward_name, item_id, item_quantity, item_link, icon_class) VALUES +INSERT INTO recruitreward (required_friends, reward_name, item_id, item_quantity, item_link, icon_class) VALUES (1,'Medallón de oro',37297,1,'https://wotlk.ultimowow.com/?item=37297','q3 inv_jewelry_amulet_03'), (2,'Emblema de escarcha',49426,30,'https://wotlk.ultimowow.com/?item=49426','q4 inv_misc_frostemblem_01'), (4,'Zhebra presta',37719,1,'https://wotlk.ultimowow.com/?item=37719','q4 ability_mount_charger'), diff --git a/web-next/app/[locale]/content-creators/page.tsx b/web-next/app/[locale]/content-creators/page.tsx index 356e037..c5781c5 100644 --- a/web-next/app/[locale]/content-creators/page.tsx +++ b/web-next/app/[locale]/content-creators/page.tsx @@ -13,7 +13,7 @@ export async function generateMetadata({ params }: { params: Promise<{ locale: s /** * Creadores de contenido (el menú VIDEOS) — réplica del partial Django - * `partials/videos.html`. Enseña el primer creador de `home_contentcreator`, y + * `partials/videos.html`. Enseña el primer creador de `contentcreator`, y * si no hay ninguno, el mismo aviso que Django. */ export default async function ContentCreatorsPage({ params }: { params: Promise<{ locale: string }> }) { diff --git a/web-next/app/[locale]/security-token/page.tsx b/web-next/app/[locale]/security-token/page.tsx index fdf19a4..231b544 100644 --- a/web-next/app/[locale]/security-token/page.tsx +++ b/web-next/app/[locale]/security-token/page.tsx @@ -21,7 +21,7 @@ export default async function SecurityTokenPage({ params }: { params: Promise<{ let tokenDate: string | null = null try { const [rows] = await db(DB.default).query( - 'SELECT created_at FROM home_securitytoken WHERE user_id = ? ORDER BY created_at DESC LIMIT 1', + 'SELECT created_at FROM securitytoken WHERE user_id = ? ORDER BY created_at DESC LIMIT 1', [session.accountId ?? 0], ) if (rows[0]) tokenDate = new Date(rows[0].created_at).toISOString() diff --git a/web-next/lib/account.ts b/web-next/lib/account.ts index 24e5960..4ee59d7 100644 --- a/web-next/lib/account.ts +++ b/web-next/lib/account.ts @@ -62,7 +62,7 @@ export async function getAccountDashboard(session: SessionData, locale = 'es'): let vp = 0 try { const [p] = await db(DB.default).query( - 'SELECT dp, vp FROM home_api_points WHERE accountID = ?', + 'SELECT dp, vp FROM api_points WHERE accountID = ?', [accountId], ) if (p[0]) { @@ -80,7 +80,7 @@ export async function getAccountDashboard(session: SessionData, locale = 'es'): let donatedPD = 0 try { const [d] = await db(DB.default).query( - "SELECT COALESCE(SUM(amount), 0) AS total FROM home_stripelog WHERE account_id = ? AND fulfilled = 1 AND mode IN ('sumup', 'test', 'live')", + "SELECT COALESCE(SUM(amount), 0) AS total FROM stripelog WHERE account_id = ? AND fulfilled = 1 AND mode IN ('sumup', 'test', 'live')", [accountId], ) donatedPD = Math.round(Number(d[0]?.total ?? 0) * PD_PER_UNIT) @@ -154,7 +154,7 @@ export async function getAccountDashboard(session: SessionData, locale = 'es'): let securityTokenDate: string | null = null try { const [s] = await db(DB.default).query( - 'SELECT created_at FROM home_securitytoken WHERE user_id = ? ORDER BY created_at DESC LIMIT 1', + 'SELECT created_at FROM securitytoken WHERE user_id = ? ORDER BY created_at DESC LIMIT 1', [accountId], ) if (s[0]) securityTokenDate = new Date(s[0].created_at).toISOString() diff --git a/web-next/lib/admin-gold.ts b/web-next/lib/admin-gold.ts index 1e67d36..457f0c7 100644 --- a/web-next/lib/admin-gold.ts +++ b/web-next/lib/admin-gold.ts @@ -9,19 +9,19 @@ export interface GoldOption { export async function listGoldOptions(): Promise { const [rows] = await db(DB.default).query( - 'SELECT id, gold_amount, price FROM home_goldprice ORDER BY gold_amount', + 'SELECT id, gold_amount, price FROM goldprice ORDER BY gold_amount', ) return rows.map((r) => ({ id: r.id, gold_amount: r.gold_amount, price: Number(r.price) })) } export async function createGoldOption(goldAmount: number, price: number): Promise { const [res] = await db(DB.default).query( - 'INSERT INTO home_goldprice (gold_amount, price) VALUES (?, ?)', + 'INSERT INTO goldprice (gold_amount, price) VALUES (?, ?)', [goldAmount, price], ) return res.insertId } export async function deleteGoldOption(id: number): Promise { - await db(DB.default).query('DELETE FROM home_goldprice WHERE id = ?', [id]) + await db(DB.default).query('DELETE FROM goldprice WHERE id = ?', [id]) } diff --git a/web-next/lib/admin-news.ts b/web-next/lib/admin-news.ts index 59c45dc..8cde994 100644 --- a/web-next/lib/admin-news.ts +++ b/web-next/lib/admin-news.ts @@ -13,7 +13,7 @@ export interface NewsItem { export async function listNews(): Promise { const [rows] = await db(DB.default).query( - 'SELECT id, titulo, titulo_en, contenido, contenido_en, fecha_publicacion, enlace FROM home_noticia ORDER BY fecha_publicacion DESC', + 'SELECT id, titulo, titulo_en, contenido, contenido_en, fecha_publicacion, enlace FROM noticia ORDER BY fecha_publicacion DESC', ) return rows.map((r) => ({ id: r.id, @@ -34,7 +34,7 @@ export async function createNews( contenidoEn: string | null, ): Promise { const [res] = await db(DB.default).query( - 'INSERT INTO home_noticia (titulo, titulo_en, contenido, contenido_en, fecha_publicacion, enlace) VALUES (?, ?, ?, ?, NOW(), ?)', + 'INSERT INTO noticia (titulo, titulo_en, contenido, contenido_en, fecha_publicacion, enlace) VALUES (?, ?, ?, ?, NOW(), ?)', [titulo, tituloEn || null, contenido, contenidoEn || null, enlace || null], ) return res.insertId @@ -50,11 +50,11 @@ export async function updateNews( contenidoEn: string | null, ): Promise { await db(DB.default).query( - 'UPDATE home_noticia SET titulo = ?, titulo_en = ?, contenido = ?, contenido_en = ?, enlace = ? WHERE id = ?', + 'UPDATE noticia SET titulo = ?, titulo_en = ?, contenido = ?, contenido_en = ?, enlace = ? WHERE id = ?', [titulo, tituloEn || null, contenido, contenidoEn || null, enlace || null, id], ) } export async function deleteNews(id: number): Promise { - await db(DB.default).query('DELETE FROM home_noticia WHERE id = ?', [id]) + await db(DB.default).query('DELETE FROM noticia WHERE id = ?', [id]) } diff --git a/web-next/lib/admin-prices.ts b/web-next/lib/admin-prices.ts index d67c49d..7c87e1b 100644 --- a/web-next/lib/admin-prices.ts +++ b/web-next/lib/admin-prices.ts @@ -3,12 +3,12 @@ import { db, DB } from './db' // Servicios con precio único (una fila) -> tabla django_wow. export const PRICE_TABLES: Record = { - rename: 'home_renameprice', - customize: 'home_customizeprice', - 'change-race': 'home_changeraceprice', - 'change-faction': 'home_changefactionprice', - 'level-up': 'home_levelupprice', - transfer: 'home_transferprice', + rename: 'renameprice', + customize: 'customizeprice', + 'change-race': 'changeraceprice', + 'change-faction': 'changefactionprice', + 'level-up': 'levelupprice', + transfer: 'transferprice', } export interface PriceRow { diff --git a/web-next/lib/admin-promo.ts b/web-next/lib/admin-promo.ts index ab89252..6a13f47 100644 --- a/web-next/lib/admin-promo.ts +++ b/web-next/lib/admin-promo.ts @@ -23,8 +23,8 @@ function toMysqlDate(v: string): string | null { export async function listPromoCodes(): Promise { const [rows] = await db(DB.default).query( `SELECT p.id, p.code, p.pd, p.pv, p.max_uses, p.uses, p.active, p.expires_at, - (SELECT COUNT(*) FROM home_promoredemption r WHERE r.promo_id = p.id) AS redemptions - FROM home_promocode p ORDER BY p.id DESC`, + (SELECT COUNT(*) FROM promoredemption r WHERE r.promo_id = p.id) AS redemptions + FROM promocode p ORDER BY p.id DESC`, ) return rows.map((r) => ({ id: r.id, @@ -48,7 +48,7 @@ export async function createPromoCode( ): Promise<{ id?: number; error?: string }> { try { const [res] = await db(DB.default).query( - 'INSERT INTO home_promocode (code, pd, pv, max_uses, uses, active, expires_at, created_at) VALUES (?, ?, ?, ?, 0, 1, ?, NOW())', + 'INSERT INTO promocode (code, pd, pv, max_uses, uses, active, expires_at, created_at) VALUES (?, ?, ?, ?, 0, 1, ?, NOW())', [code, pd, pv, maxUses, toMysqlDate(expiresAt)], ) return { id: res.insertId } @@ -63,12 +63,12 @@ export async function updatePromoCode( fields: { pd: number; pv: number; maxUses: number; active: boolean }, ): Promise { await db(DB.default).query( - 'UPDATE home_promocode SET pd = ?, pv = ?, max_uses = ?, active = ? WHERE id = ?', + 'UPDATE promocode SET pd = ?, pv = ?, max_uses = ?, active = ? WHERE id = ?', [fields.pd, fields.pv, fields.maxUses, fields.active ? 1 : 0, id], ) } export async function deletePromoCode(id: number): Promise { - await db(DB.default).query('DELETE FROM home_promoredemption WHERE promo_id = ?', [id]) - await db(DB.default).query('DELETE FROM home_promocode WHERE id = ?', [id]) + await db(DB.default).query('DELETE FROM promoredemption WHERE promo_id = ?', [id]) + await db(DB.default).query('DELETE FROM promocode WHERE id = ?', [id]) } diff --git a/web-next/lib/admin-recruit.ts b/web-next/lib/admin-recruit.ts index 5e5143f..c851d1e 100644 --- a/web-next/lib/admin-recruit.ts +++ b/web-next/lib/admin-recruit.ts @@ -13,7 +13,7 @@ export interface RecruitReward { export async function listRecruitRewards(): Promise { const [rows] = await db(DB.default).query( - 'SELECT id, required_friends, reward_name, item_id, item_quantity, item_link, icon_class FROM home_recruitreward ORDER BY required_friends, id', + 'SELECT id, required_friends, reward_name, item_id, item_quantity, item_link, icon_class FROM recruitreward ORDER BY required_friends, id', ) return rows.map((r) => ({ id: r.id, @@ -28,7 +28,7 @@ export async function listRecruitRewards(): Promise { export async function createRecruitReward(data: Omit): Promise { const [res] = await db(DB.default).query( - `INSERT INTO home_recruitreward + `INSERT INTO recruitreward (required_friends, reward_name, item_id, item_quantity, item_link, icon_class) VALUES (?, ?, ?, ?, ?, ?)`, [data.required_friends, data.reward_name, data.item_id, data.item_quantity, data.item_link, data.icon_class], @@ -37,5 +37,5 @@ export async function createRecruitReward(data: Omit): Prom } export async function deleteRecruitReward(id: number): Promise { - await db(DB.default).query('DELETE FROM home_recruitreward WHERE id = ?', [id]) + await db(DB.default).query('DELETE FROM recruitreward WHERE id = ?', [id]) } diff --git a/web-next/lib/admin-votes.ts b/web-next/lib/admin-votes.ts index f2be350..1c649e0 100644 --- a/web-next/lib/admin-votes.ts +++ b/web-next/lib/admin-votes.ts @@ -11,19 +11,19 @@ export interface VoteSite { export async function listVoteSites(): Promise { const [rows] = await db(DB.default).query( - 'SELECT id, name, url, image_url, points FROM home_votesite ORDER BY id', + 'SELECT id, name, url, image_url, points FROM votesite ORDER BY id', ) return rows.map((r) => ({ id: r.id, name: r.name, url: r.url, image_url: r.image_url, points: r.points })) } export async function createVoteSite(name: string, url: string, imageUrl: string, points: number): Promise { const [res] = await db(DB.default).query( - 'INSERT INTO home_votesite (name, url, image_url, points, created_at, updated_at) VALUES (?, ?, ?, ?, NOW(), NOW())', + 'INSERT INTO votesite (name, url, image_url, points, created_at, updated_at) VALUES (?, ?, ?, ?, NOW(), NOW())', [name, url, imageUrl, points], ) return res.insertId } export async function deleteVoteSite(id: number): Promise { - await db(DB.default).query('DELETE FROM home_votesite WHERE id = ?', [id]) + await db(DB.default).query('DELETE FROM votesite WHERE id = ?', [id]) } diff --git a/web-next/lib/change-email.ts b/web-next/lib/change-email.ts index acd5043..11fff47 100644 --- a/web-next/lib/change-email.ts +++ b/web-next/lib/change-email.ts @@ -34,7 +34,7 @@ export async function requestEmailChange( const oldHash = crypto.randomBytes(16).toString('hex') const newHash = crypto.randomBytes(16).toString('hex') await db(DB.default).query( - 'INSERT INTO home_accountactivation (username, email, old_email, password, recruiter_id, hash, old_email_hash, is_used, is_new_email_used, created_at) ' + + 'INSERT INTO accountactivation (username, email, old_email, password, recruiter_id, hash, old_email_hash, is_used, is_new_email_used, created_at) ' + 'VALUES (?, ?, ?, ?, ?, ?, ?, 0, 0, NOW())', [session.username ?? null, newEmail, current, curPassword, userId, newHash, oldHash], ) @@ -51,12 +51,12 @@ export async function requestEmailChange( export async function confirmOldEmail(hash: string): Promise { const [rows] = await db(DB.default).query( - 'SELECT id, email, hash, username FROM home_accountactivation WHERE old_email_hash = ? AND is_used = 0', + 'SELECT id, email, hash, username FROM accountactivation WHERE old_email_hash = ? AND is_used = 0', [hash], ) const act = rows[0] if (!act) return { success: false, error: 'invalidLink' } - await db(DB.default).query('UPDATE home_accountactivation SET is_used = 1 WHERE id = ?', [act.id]) + await db(DB.default).query('UPDATE accountactivation SET is_used = 1 WHERE id = ?', [act.id]) const site = process.env.SITE_URL || '' const link = `${site}/confirm-new-email?hash=${act.hash}` @@ -70,12 +70,12 @@ export async function confirmOldEmail(hash: string): Promise { export async function confirmNewEmail(hash: string): Promise { const [rows] = await db(DB.default).query( - 'SELECT id, email, old_email, password FROM home_accountactivation WHERE hash = ? AND is_new_email_used = 0 AND old_email IS NOT NULL', + 'SELECT id, email, old_email, password FROM accountactivation WHERE hash = ? AND is_new_email_used = 0 AND old_email IS NOT NULL', [hash], ) const act = rows[0] if (!act) return { success: false, error: 'invalidLink' } - await db(DB.default).query('UPDATE home_accountactivation SET is_new_email_used = 1 WHERE id = ?', [act.id]) + await db(DB.default).query('UPDATE accountactivation SET is_new_email_used = 1 WHERE id = ?', [act.id]) const newNorm = normalizeEmail(act.email) const oldNorm = normalizeEmail(act.old_email || '') @@ -99,6 +99,6 @@ export async function confirmNewEmail(hash: string): Promise { } catch { return { success: false, error: 'genericError' } } - await db(DB.default).query('DELETE FROM home_accountactivation WHERE id = ?', [act.id]) + await db(DB.default).query('DELETE FROM accountactivation WHERE id = ?', [act.id]) return { success: true } } diff --git a/web-next/lib/character-services.ts b/web-next/lib/character-services.ts index c75cd2d..a4b4610 100644 --- a/web-next/lib/character-services.ts +++ b/web-next/lib/character-services.ts @@ -43,7 +43,7 @@ async function soapCharacterAction(accountId: number, character: string, cfg: So export function reviveCharacter(accountId: number, character: string): Promise { return soapCharacterAction(accountId, character, { command: (c) => `.revive ${c}`, - historyTable: 'home_revivehistory', + historyTable: 'revivehistory', cooldownHours: 12, }) } @@ -51,7 +51,7 @@ export function reviveCharacter(accountId: number, character: string): Promise { return soapCharacterAction(accountId, character, { command: (c) => `.unstuck ${c}`, - historyTable: 'home_unstuckhistory', + historyTable: 'unstuckhistory', cooldownHours: 12, }) } diff --git a/web-next/lib/content-creator.ts b/web-next/lib/content-creator.ts index 974411c..b2ba0bc 100644 --- a/web-next/lib/content-creator.ts +++ b/web-next/lib/content-creator.ts @@ -2,7 +2,7 @@ import type { RowDataPacket } from 'mysql2' import { db, DB } from './db' /** - * Creador de contenido destacado (`home_contentcreator`, el menú VIDEOS). + * Creador de contenido destacado (`contentcreator`, el menú VIDEOS). * * Como en Django, se muestra SOLO el primero: la tabla se maneja desde el admin * y ahora mismo está vacía, así que la página enseña el aviso de "no hay @@ -25,7 +25,7 @@ export async function getContentCreator(): Promise { const [rows] = await db(DB.default).query( `SELECT title, description, content_type, subtitle, youtube_video_url, avatar_image_url, youtube_channel_url, facebook_page_url - FROM home_contentcreator ORDER BY id LIMIT 1`, + FROM contentcreator ORDER BY id LIMIT 1`, ) const r = rows[0] if (!r) return null diff --git a/web-next/lib/dpoints.ts b/web-next/lib/dpoints.ts index c46674b..3ab2e92 100644 --- a/web-next/lib/dpoints.ts +++ b/web-next/lib/dpoints.ts @@ -7,18 +7,18 @@ export const PD_PER_UNIT = 100 export const DP_MIN_AMOUNT = 1 export const DP_MAX_AMOUNT = 200 -/** Acredita PD (donate points) a una cuenta de juego en `home_api_points` (upsert). */ +/** Acredita PD (donate points) a una cuenta de juego en `api_points` (upsert). */ export async function creditDPoints(accountId: number, points: number): Promise { if (!accountId || !(points > 0)) return false try { const [rows] = await db(DB.default).query( - 'SELECT id FROM home_api_points WHERE accountID = ?', + 'SELECT id FROM api_points WHERE accountID = ?', [accountId], ) if (rows[0]) { - await db(DB.default).query('UPDATE home_api_points SET dp = dp + ? WHERE accountID = ?', [points, accountId]) + await db(DB.default).query('UPDATE api_points SET dp = dp + ? WHERE accountID = ?', [points, accountId]) } else { - await db(DB.default).query('INSERT INTO home_api_points (accountID, vp, dp) VALUES (?, 0, ?)', [accountId, points]) + await db(DB.default).query('INSERT INTO api_points (accountID, vp, dp) VALUES (?, 0, ?)', [accountId, points]) } return true } catch { @@ -31,7 +31,7 @@ export async function getDPointsBalance(accountId: number): Promise { if (!accountId) return 0 try { const [rows] = await db(DB.default).query( - 'SELECT dp FROM home_api_points WHERE accountID = ?', + 'SELECT dp FROM api_points WHERE accountID = ?', [accountId], ) return rows[0] ? Number(rows[0].dp) : 0 @@ -45,7 +45,7 @@ export async function getVPointsBalance(accountId: number): Promise { if (!accountId) return 0 try { const [rows] = await db(DB.default).query( - 'SELECT vp FROM home_api_points WHERE accountID = ?', + 'SELECT vp FROM api_points WHERE accountID = ?', [accountId], ) return rows[0] ? Number(rows[0].vp) : 0 @@ -59,7 +59,7 @@ export async function creditVPoints(accountId: number, points: number): Promise< if (!accountId || !(points > 0)) return false try { await db(DB.default).query( - 'INSERT INTO home_api_points (accountID, vp, dp) VALUES (?, ?, 0) ON DUPLICATE KEY UPDATE vp = vp + ?', + 'INSERT INTO api_points (accountID, vp, dp) VALUES (?, ?, 0) ON DUPLICATE KEY UPDATE vp = vp + ?', [accountId, points, points], ) return true @@ -84,7 +84,7 @@ export async function spendVPoints( try { await conn.beginTransaction() const [src] = await conn.query( - 'SELECT vp FROM home_api_points WHERE accountID = ? FOR UPDATE', + 'SELECT vp FROM api_points WHERE accountID = ? FOR UPDATE', [accountId], ) const balance = src[0] ? Number(src[0].vp) : 0 @@ -92,7 +92,7 @@ export async function spendVPoints( await conn.rollback() return { success: false, error: 'insufficientFunds' } } - await conn.query('UPDATE home_api_points SET vp = vp - ? WHERE accountID = ?', [points, accountId]) + await conn.query('UPDATE api_points SET vp = vp - ? WHERE accountID = ?', [points, accountId]) await conn.commit() return { success: true } } catch { @@ -126,7 +126,7 @@ export async function transferDPoints( await conn.beginTransaction() // Bloquea la fila del origen para evitar dobles gastos concurrentes. const [src] = await conn.query( - 'SELECT dp FROM home_api_points WHERE accountID = ? FOR UPDATE', + 'SELECT dp FROM api_points WHERE accountID = ? FOR UPDATE', [fromAccountId], ) const balance = src[0] ? Number(src[0].dp) : 0 @@ -134,9 +134,9 @@ export async function transferDPoints( await conn.rollback() return { success: false, error: 'insufficientFunds' } } - await conn.query('UPDATE home_api_points SET dp = dp - ? WHERE accountID = ?', [points, fromAccountId]) + await conn.query('UPDATE api_points SET dp = dp - ? WHERE accountID = ?', [points, fromAccountId]) await conn.query( - 'INSERT INTO home_api_points (accountID, vp, dp) VALUES (?, 0, ?) ON DUPLICATE KEY UPDATE dp = dp + ?', + 'INSERT INTO api_points (accountID, vp, dp) VALUES (?, 0, ?) ON DUPLICATE KEY UPDATE dp = dp + ?', [toAccountId, points, points], ) await conn.commit() @@ -170,7 +170,7 @@ export async function spendDPoints( try { await conn.beginTransaction() const [src] = await conn.query( - 'SELECT dp FROM home_api_points WHERE accountID = ? FOR UPDATE', + 'SELECT dp FROM api_points WHERE accountID = ? FOR UPDATE', [accountId], ) const balance = src[0] ? Number(src[0].dp) : 0 @@ -178,7 +178,7 @@ export async function spendDPoints( await conn.rollback() return { success: false, error: 'insufficientFunds' } } - await conn.query('UPDATE home_api_points SET dp = dp - ? WHERE accountID = ?', [points, accountId]) + await conn.query('UPDATE api_points SET dp = dp - ? WHERE accountID = ?', [points, accountId]) await conn.commit() return { success: true } } catch { diff --git a/web-next/lib/home.ts b/web-next/lib/home.ts index f2b4d53..eb83ccf 100644 --- a/web-next/lib/home.ts +++ b/web-next/lib/home.ts @@ -38,7 +38,7 @@ export function expansionFromGamebuild(gamebuild: number): string { */ export async function getNoticias(locale = 'es', limit = 50): Promise { const [rows] = await db(DB.default).query( - 'SELECT id, titulo, titulo_en, contenido, contenido_en, fecha_publicacion, enlace FROM home_noticia ORDER BY fecha_publicacion DESC LIMIT ?', + 'SELECT id, titulo, titulo_en, contenido, contenido_en, fecha_publicacion, enlace FROM noticia ORDER BY fecha_publicacion DESC LIMIT ?', [limit], ) const en = locale === 'en' @@ -81,7 +81,7 @@ function checkServerStatus(host: string, port: number, timeout = 1000): Promise< export async function getServerStatus(): Promise { const [rows] = await db(DB.default).query( - 'SELECT name, address, port, gamebuild FROM home_serverselection LIMIT 1', + 'SELECT name, address, port, gamebuild FROM serverselection LIMIT 1', ) const s = rows[0] if (!s) return null diff --git a/web-next/lib/paid-services.ts b/web-next/lib/paid-services.ts index 63690c1..03ed910 100644 --- a/web-next/lib/paid-services.ts +++ b/web-next/lib/paid-services.ts @@ -125,7 +125,7 @@ export const PAID_SERVICES: Record = { precheck: ({ accountId, email, character, body }) => checkTransferEligibility(accountId, email, character, body), }, // Enviar regalo: es una compra de la tienda cuyo correo va a OTRO personaje y - // dice quién lo manda. El carrito se guarda en home_store_order (order_ref) y + // dice quién lo manda. El carrito se guarda en store_order (order_ref) y // se entrega igual que la tienda, con su reembolso parcial si falla a medias. // `sender` = personaje de origen, para redactar el correo. 'send-gift': { @@ -143,7 +143,7 @@ export const PAID_SERVICES: Record = { extraFields: ['guildId', 'newName'], }, // Tienda pagada con tarjeta: al confirmarse el pago, envía por correo los ítems - // del pedido (guardado en home_store_order) referenciado en metadata.order_ref. + // del pedido (guardado en store_order) referenciado en metadata.order_ref. store: { price: (m) => Promise.resolve(Number(m.amount)), productName: () => 'Compra en la tienda', diff --git a/web-next/lib/points-history.ts b/web-next/lib/points-history.ts index 8dd907b..48162ff 100644 --- a/web-next/lib/points-history.ts +++ b/web-next/lib/points-history.ts @@ -25,7 +25,7 @@ export async function getPointsBalances(accountId: number): Promise<{ dp: number if (!accountId) return { dp: 0, pv: 0 } try { const [rows] = await db(DB.default).query( - 'SELECT dp, vp FROM home_api_points WHERE accountID = ?', + 'SELECT dp, vp FROM api_points WHERE accountID = ?', [accountId], ) return rows[0] ? { dp: Number(rows[0].dp), pv: Number(rows[0].vp) } : { dp: 0, pv: 0 } @@ -36,9 +36,9 @@ export async function getPointsBalances(accountId: number): Promise<{ dp: number /** * Historial unificado de PD/PV de una cuenta, combinando las fuentes reales: - * - `home_stripelog`: pagos por **Stripe** (mode test/live) y **SumUp** (mode sumup). - * - `home_votelog` (+ `home_votesite`): PV ganados al votar. - * - `home_promoredemption` (+ `home_promocode`): PD/PV canjeados por código. + * - `stripelog`: pagos por **Stripe** (mode test/live) y **SumUp** (mode sumup). + * - `votelog` (+ `votesite`): PV ganados al votar. + * - `promoredemption` (+ `promocode`): PD/PV canjeados por código. * Ordenado por fecha descendente; cada consulta es tolerante a fallos. */ export async function getPointsHistory(accountId: number, limit = 100): Promise { @@ -49,7 +49,7 @@ export async function getPointsHistory(accountId: number, limit = 100): Promise< try { const [rows] = await db(DB.default).query( 'SELECT product_name, character_name, amount, mode, service, metadata, fulfilled, timestamp ' + - 'FROM home_stripelog WHERE account_id = ? ORDER BY timestamp DESC LIMIT ?', + 'FROM stripelog WHERE account_id = ? ORDER BY timestamp DESC LIMIT ?', [accountId, limit], ) for (const r of rows) { @@ -76,8 +76,8 @@ export async function getPointsHistory(accountId: number, limit = 100): Promise< // 2) Votos (PV). try { const [rows] = await db(DB.default).query( - 'SELECT v.created_at, s.name, s.points FROM home_votelog v ' + - 'JOIN home_votesite s ON s.id = v.vote_site_id WHERE v.account_id = ? ORDER BY v.created_at DESC LIMIT ?', + 'SELECT v.created_at, s.name, s.points FROM votelog v ' + + 'JOIN votesite s ON s.id = v.vote_site_id WHERE v.account_id = ? ORDER BY v.created_at DESC LIMIT ?', [accountId, limit], ) for (const r of rows) { @@ -100,8 +100,8 @@ export async function getPointsHistory(accountId: number, limit = 100): Promise< // 3) Promociones (PD/PV). try { const [rows] = await db(DB.default).query( - 'SELECT r.redeemed_at, c.code, c.pd, c.pv FROM home_promoredemption r ' + - 'JOIN home_promocode c ON c.id = r.promo_id WHERE r.account_id = ? ORDER BY r.redeemed_at DESC LIMIT ?', + 'SELECT r.redeemed_at, c.code, c.pd, c.pv FROM promoredemption r ' + + 'JOIN promocode c ON c.id = r.promo_id WHERE r.account_id = ? ORDER BY r.redeemed_at DESC LIMIT ?', [accountId, limit], ) for (const r of rows) { diff --git a/web-next/lib/prices.ts b/web-next/lib/prices.ts index bb33bc2..5ba8d4f 100644 --- a/web-next/lib/prices.ts +++ b/web-next/lib/prices.ts @@ -10,13 +10,16 @@ async function priceFrom(table: string, fallback: number): Promise { } } -export const getRenamePrice = () => priceFrom('home_renameprice', 2.0) -export const getCustomizePrice = () => priceFrom('home_customizeprice', 1.0) -export const getChangeRacePrice = () => priceFrom('home_changeraceprice', 10.0) -export const getChangeFactionPrice = () => priceFrom('home_changefactionprice', 10.0) -export const getLevelUpPrice = () => priceFrom('home_levelupprice', 10.0) -export const getTransferPrice = () => priceFrom('home_transferprice', 10.0) -export const getRestoreItemPrice = () => priceFrom('home_restoreitemprice', 1.0) +export const getRenamePrice = () => priceFrom('renameprice', 2.0) +export const getCustomizePrice = () => priceFrom('customizeprice', 1.0) +export const getChangeRacePrice = () => priceFrom('changeraceprice', 10.0) +export const getChangeFactionPrice = () => priceFrom('changefactionprice', 10.0) +export const getLevelUpPrice = () => priceFrom('levelupprice', 10.0) +export const getTransferPrice = () => priceFrom('transferprice', 10.0) +// OJO: la tabla `restoreitemprice` NO existe en la BD, así que esto siempre cae +// al valor por defecto (el catch de priceFrom se come el error). Viene de antes; +// si se quiere un precio configurable, hay que crear la tabla. +export const getRestoreItemPrice = () => priceFrom('restoreitemprice', 1.0) export interface GoldOption { gold_amount: number @@ -26,7 +29,7 @@ export interface GoldOption { export async function getGoldOptions(): Promise { try { const [rows] = await db(DB.default).query( - 'SELECT gold_amount, price FROM home_goldprice ORDER BY gold_amount', + 'SELECT gold_amount, price FROM goldprice ORDER BY gold_amount', ) return rows.map((r) => ({ gold_amount: r.gold_amount, price: Number(r.price) })) } catch { diff --git a/web-next/lib/promo.ts b/web-next/lib/promo.ts index e1cb256..25f8710 100644 --- a/web-next/lib/promo.ts +++ b/web-next/lib/promo.ts @@ -26,7 +26,7 @@ export async function redeemPromoCode(accountId: number, rawCode: string): Promi // Bloquea la fila del código (comparación binaria => sensible a may/min). const [rows] = await conn.query( - 'SELECT id, pd, pv, max_uses, uses, active, expires_at FROM home_promocode WHERE code = ? COLLATE utf8mb4_bin LIMIT 1 FOR UPDATE', + 'SELECT id, pd, pv, max_uses, uses, active, expires_at FROM promocode WHERE code = ? COLLATE utf8mb4_bin LIMIT 1 FOR UPDATE', [code], ) const promo = rows[0] @@ -45,7 +45,7 @@ export async function redeemPromoCode(accountId: number, rawCode: string): Promi // Registra el canje (la clave única promo+cuenta evita el doble uso). try { - await conn.query('INSERT INTO home_promoredemption (promo_id, account_id, redeemed_at) VALUES (?, ?, NOW())', [ + await conn.query('INSERT INTO promoredemption (promo_id, account_id, redeemed_at) VALUES (?, ?, NOW())', [ promo.id, accountId, ]) @@ -57,7 +57,7 @@ export async function redeemPromoCode(accountId: number, rawCode: string): Promi // Consume un uso (condicional, por si hubo carrera con otro canje). const [upd] = await conn.query( - 'UPDATE home_promocode SET uses = uses + 1 WHERE id = ? AND uses < max_uses', + 'UPDATE promocode SET uses = uses + 1 WHERE id = ? AND uses < max_uses', [promo.id], ) if (upd.affectedRows !== 1) { @@ -69,7 +69,7 @@ export async function redeemPromoCode(accountId: number, rawCode: string): Promi const pd = Number(promo.pd) const pv = Number(promo.pv) await conn.query( - 'INSERT INTO home_api_points (accountID, vp, dp) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE vp = vp + VALUES(vp), dp = dp + VALUES(dp)', + 'INSERT INTO api_points (accountID, vp, dp) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE vp = vp + VALUES(vp), dp = dp + VALUES(dp)', [accountId, pv, pd], ) diff --git a/web-next/lib/quest-tracker.ts b/web-next/lib/quest-tracker.ts index 0b6f76b..79cc0fb 100644 --- a/web-next/lib/quest-tracker.ts +++ b/web-next/lib/quest-tracker.ts @@ -104,7 +104,7 @@ export async function questStatuses(guid: number, quests: number[]): Promise { try { const [rows] = await db(DB.default).query( - 'SELECT searched_at FROM home_questsearchhistory WHERE character_name = ? AND category = ? ORDER BY searched_at DESC LIMIT 1', + 'SELECT searched_at FROM questsearchhistory WHERE character_name = ? AND category = ? ORDER BY searched_at DESC LIMIT 1', [character, category], ) if (!rows[0]) return 0 @@ -118,7 +118,7 @@ export async function cooldownRemainingMs(character: string, category: QuestCate export async function recordSearch(character: string, category: QuestCategory): Promise { try { await db(DB.default).query( - 'INSERT INTO home_questsearchhistory (character_name, category, searched_at) VALUES (?, ?, NOW())', + 'INSERT INTO questsearchhistory (character_name, category, searched_at) VALUES (?, ?, NOW())', [character, category], ) } catch { diff --git a/web-next/lib/recover.ts b/web-next/lib/recover.ts index c67770d..52e79b8 100644 --- a/web-next/lib/recover.ts +++ b/web-next/lib/recover.ts @@ -45,7 +45,7 @@ export async function requestRecovery(type: string, value: string): Promise '?').join(',') const [toks] = await db(DB.default).query( - `SELECT user_id, token FROM home_securitytoken WHERE user_id IN (${placeholders})`, + `SELECT user_id, token FROM securitytoken WHERE user_id IN (${placeholders})`, ids, ) if (toks.length) { @@ -132,7 +132,7 @@ export async function requestRecovery(type: string, value: string): Promise( - 'SELECT hash, password FROM home_accountactivation WHERE email = ? AND old_email IS NULL ORDER BY created_at DESC LIMIT 1', + 'SELECT hash, password FROM accountactivation WHERE email = ? AND old_email IS NULL ORDER BY created_at DESC LIMIT 1', [email], ) if (rows[0]) { @@ -154,7 +154,7 @@ export async function requestRecovery(type: string, value: string): Promise { const [rows] = await db(DB.default).query( - 'SELECT id, email, created_at FROM home_passwordreset WHERE token = ? AND used = 0', + 'SELECT id, email, created_at FROM passwordreset WHERE token = ? AND used = 0', [token], ) const pr = rows[0] @@ -174,6 +174,6 @@ export async function resetPassword(token: string, newPassword: string, confPass } catch { return { success: false, error: 'genericError' } } - await db(DB.default).query('UPDATE home_passwordreset SET used = 1 WHERE id = ?', [pr.id]) + await db(DB.default).query('UPDATE passwordreset SET used = 1 WHERE id = ?', [pr.id]) return { success: true, redirect: '/log-in' } } diff --git a/web-next/lib/recruit-claim.ts b/web-next/lib/recruit-claim.ts index 6b3aad5..70e12c2 100644 --- a/web-next/lib/recruit-claim.ts +++ b/web-next/lib/recruit-claim.ts @@ -74,12 +74,12 @@ async function getValidRecruitsAtLevel80(accountId: number, requiredCount: numbe /** Todas las recompensas con marca de si esta cuenta ya las reclamó. */ export async function getRecruitRewards(accountId: number | null): Promise { const [rows] = await db(DB.default).query( - 'SELECT id, required_friends, reward_name, item_id, item_quantity, item_link, icon_class FROM home_recruitreward ORDER BY required_friends, id', + 'SELECT id, required_friends, reward_name, item_id, item_quantity, item_link, icon_class FROM recruitreward ORDER BY required_friends, id', ) let claimedIds = new Set() if (accountId) { const [claimed] = await db(DB.default).query( - 'SELECT recruit_reward_id FROM home_claimedreward WHERE account_id = ?', + 'SELECT recruit_reward_id FROM claimedreward WHERE account_id = ?', [accountId], ) claimedIds = new Set(claimed.map((c) => Number(c.recruit_reward_id))) @@ -119,7 +119,7 @@ export async function claimRecruitReward( ip: string, ): Promise { const [rewardRows] = await db(DB.default).query( - 'SELECT id, required_friends, reward_name, item_id, item_quantity FROM home_recruitreward WHERE id = ?', + 'SELECT id, required_friends, reward_name, item_id, item_quantity FROM recruitreward WHERE id = ?', [rewardId], ) const reward = rewardRows[0] @@ -130,7 +130,7 @@ export async function claimRecruitReward( } const [already] = await db(DB.default).query( - 'SELECT 1 FROM home_claimedreward WHERE account_id = ? AND recruit_reward_id = ? LIMIT 1', + 'SELECT 1 FROM claimedreward WHERE account_id = ? AND recruit_reward_id = ? LIMIT 1', [accountId, rewardId], ) if (already[0]) return { success: false, message: 'alreadyClaimed' } @@ -145,7 +145,7 @@ export async function claimRecruitReward( } await db(DB.default).query( - 'INSERT INTO home_claimedreward (account_id, username, recruit_reward_id, character_name, claimed_at, ip_address) VALUES (?, ?, ?, ?, NOW(), ?)', + 'INSERT INTO claimedreward (account_id, username, recruit_reward_id, character_name, claimed_at, ip_address) VALUES (?, ?, ?, ?, NOW(), ?)', [accountId, username, rewardId, characterName, ip.slice(0, 45)], ) return { success: true, message: 'claimSuccess' } diff --git a/web-next/lib/register.ts b/web-next/lib/register.ts index 75cbf35..6afef00 100644 --- a/web-next/lib/register.ts +++ b/web-next/lib/register.ts @@ -44,7 +44,7 @@ export async function registerAccount(input: RegisterInput): Promise { } // Borrar cualquier activación de registro pendiente para ese email - await db(DB.default).query('DELETE FROM home_accountactivation WHERE email = ? AND old_email IS NULL', [email]) + await db(DB.default).query('DELETE FROM accountactivation WHERE email = ? AND old_email IS NULL', [email]) // Reclutador opcional let recruiterId = 0 @@ -68,7 +68,7 @@ export async function registerAccount(input: RegisterInput): Promise { const hash = crypto.randomBytes(16).toString('hex') // 32 hex chars (col hash = CharField(32)) await db(DB.default).query( - 'INSERT INTO home_accountactivation (email, password, recruiter_id, hash, created_at, is_used, is_new_email_used) VALUES (?, ?, ?, ?, NOW(), 0, 0)', + 'INSERT INTO accountactivation (email, password, recruiter_id, hash, created_at, is_used, is_new_email_used) VALUES (?, ?, ?, ?, NOW(), 0, 0)', [email, password, recruiterId, hash], ) @@ -80,7 +80,7 @@ export async function registerAccount(input: RegisterInput): Promise { export async function activateAccount(hash: string, lastIp = '0.0.0.0'): Promise { const [rows] = await db(DB.default).query( - 'SELECT id, email, password, recruiter_id, created_at FROM home_accountactivation WHERE hash = ? AND old_email IS NULL', + 'SELECT id, email, password, recruiter_id, created_at FROM accountactivation WHERE hash = ? AND old_email IS NULL', [hash], ) const act = rows[0] @@ -107,6 +107,6 @@ export async function activateAccount(hash: string, lastIp = '0.0.0.0'): Promise [gameUsername, game.salt, game.verifier, emailNorm, emailNorm, act.recruiter_id || 0, lastIp, 2, bnetId], ) - await db(DB.default).query('DELETE FROM home_accountactivation WHERE id = ?', [act.id]) + await db(DB.default).query('DELETE FROM accountactivation WHERE id = ?', [act.id]) return { success: true } } diff --git a/web-next/lib/restore-character.ts b/web-next/lib/restore-character.ts index d05d2b3..529e7b5 100644 --- a/web-next/lib/restore-character.ts +++ b/web-next/lib/restore-character.ts @@ -83,7 +83,7 @@ export async function restoreCharacter(accountId: number, guid: number): Promise // Cooldown de 12 h por personaje. try { const [last] = await db(DB.default).query( - 'SELECT used_at FROM home_restorehistory WHERE character_guid = ? ORDER BY used_at DESC LIMIT 1', + 'SELECT used_at FROM restorehistory WHERE character_guid = ? ORDER BY used_at DESC LIMIT 1', [guid], ) if (last[0] && Date.now() - new Date(last[0].used_at).getTime() < COOLDOWN_MS) { @@ -106,7 +106,7 @@ export async function restoreCharacter(accountId: number, guid: number): Promise } await db(DB.default) - .query('INSERT INTO home_restorehistory (character_guid, used_at) VALUES (?, NOW())', [guid]) + .query('INSERT INTO restorehistory (character_guid, used_at) VALUES (?, NOW())', [guid]) .catch(() => {}) return { success: true, name } } diff --git a/web-next/lib/restore-items.ts b/web-next/lib/restore-items.ts index ed7389a..ee70211 100644 --- a/web-next/lib/restore-items.ts +++ b/web-next/lib/restore-items.ts @@ -52,7 +52,7 @@ export async function listDeletedItems(accountId: number, character: string): Pr // Cooldown de 8 h por personaje. try { const [last] = await db(DB.default).query( - 'SELECT used_at FROM home_itemsearchhistory WHERE character_name = ? ORDER BY used_at DESC LIMIT 1', + 'SELECT used_at FROM itemsearchhistory WHERE character_name = ? ORDER BY used_at DESC LIMIT 1', [character], ) if (last[0]) { @@ -69,7 +69,7 @@ export async function listDeletedItems(accountId: number, character: string): Pr if (soap === null) return { success: false, error: 'soapError' } await db(DB.default) - .query('INSERT INTO home_itemsearchhistory (character_name, used_at) VALUES (?, NOW())', [character]) + .query('INSERT INTO itemsearchhistory (character_name, used_at) VALUES (?, NOW())', [character]) .catch(() => {}) return { success: true, items: parseRecoverList(soap) } } diff --git a/web-next/lib/security-history.ts b/web-next/lib/security-history.ts index 652b6fa..eb10628 100644 --- a/web-next/lib/security-history.ts +++ b/web-next/lib/security-history.ts @@ -29,10 +29,10 @@ function webStatusKey(raw: string): 'success' | 'wrongPassword' | 'other' { /** * Historial de seguridad de una cuenta, en tres bloques: - * - **Actividad**: acciones de seguridad (solicitudes de token) desde `home_securitytoken`. + * - **Actividad**: acciones de seguridad (solicitudes de token) desde `securitytoken`. * - **Conexiones (Reino)**: `acore_auth.logs_ip_actions` (histórico de IP) + la última * conexión conocida (`account.last_ip`/`last_login`) si aporta una IP nueva. - * - **Conexiones (Web)**: cada intento de login web desde `home_loginattempt`. + * - **Conexiones (Web)**: cada intento de login web desde `loginattempt`. * Cada consulta es tolerante a fallos (devuelve [] si la tabla no existe). */ export async function getSecurityHistory( @@ -49,7 +49,7 @@ export async function getSecurityHistory( // 1) Actividad: solicitudes de token de seguridad. try { const [rows] = await db(DB.default).query( - 'SELECT created_at, ip_address FROM home_securitytoken WHERE user_id = ? ORDER BY created_at DESC LIMIT ?', + 'SELECT created_at, ip_address FROM securitytoken WHERE user_id = ? ORDER BY created_at DESC LIMIT ?', [accountId, limit], ) for (const r of rows) { @@ -90,7 +90,7 @@ export async function getSecurityHistory( if (email) { try { const [rows] = await db(DB.default).query( - 'SELECT username, status, ip_address, timestamp FROM home_loginattempt WHERE username = ? ORDER BY timestamp DESC LIMIT ?', + 'SELECT username, status, ip_address, timestamp FROM loginattempt WHERE username = ? ORDER BY timestamp DESC LIMIT ?', [email, limit], ) for (const r of rows) { diff --git a/web-next/lib/security-token.ts b/web-next/lib/security-token.ts index 7dc7cfd..8727efe 100644 --- a/web-next/lib/security-token.ts +++ b/web-next/lib/security-token.ts @@ -18,7 +18,7 @@ export async function requestSecurityToken(session: SessionData, ip: string): Pr if (!email) return { success: false, error: 'noEmail' } const [existing] = await db(DB.default).query( - 'SELECT id, created_at FROM home_securitytoken WHERE user_id = ? ORDER BY created_at DESC LIMIT 1', + 'SELECT id, created_at FROM securitytoken WHERE user_id = ? ORDER BY created_at DESC LIMIT 1', [userId], ) if (existing[0]) { @@ -29,9 +29,9 @@ export async function requestSecurityToken(session: SessionData, ip: string): Pr const token = crypto.randomBytes(4).toString('base64url').slice(0, 6) const expiresAt = new Date(Date.now() + 7 * 86400_000) - await db(DB.default).query('DELETE FROM home_securitytoken WHERE user_id = ?', [userId]) + await db(DB.default).query('DELETE FROM securitytoken WHERE user_id = ?', [userId]) await db(DB.default).query( - 'INSERT INTO home_securitytoken (token, created_at, expires_at, ip_address, user_id) VALUES (?, NOW(), ?, ?, ?)', + 'INSERT INTO securitytoken (token, created_at, expires_at, ip_address, user_id) VALUES (?, NOW(), ?, ?, ?)', [token, expiresAt, ip || '0.0.0.0', userId], ) @@ -39,7 +39,7 @@ export async function requestSecurityToken(session: SessionData, ip: string): Pr await sendMail(email, 'Token de seguridad - Nova WoW', securityTokenEmailHtml(email, token, ip || '0.0.0.0')) const [created] = await db(DB.default).query( - 'SELECT created_at FROM home_securitytoken WHERE user_id = ? ORDER BY created_at DESC LIMIT 1', + 'SELECT created_at FROM securitytoken WHERE user_id = ? ORDER BY created_at DESC LIMIT 1', [userId], ) return { success: true, tokenDate: created[0] ? new Date(created[0].created_at).toISOString() : undefined } @@ -48,7 +48,7 @@ export async function requestSecurityToken(session: SessionData, ip: string): Pr /** Comprueba que el token coincide con el de la cuenta. */ export async function checkSecurityToken(userId: number, token: string): Promise { const [rows] = await db(DB.default).query( - 'SELECT token FROM home_securitytoken WHERE user_id = ? ORDER BY created_at DESC LIMIT 1', + 'SELECT token FROM securitytoken WHERE user_id = ? ORDER BY created_at DESC LIMIT 1', [userId], ) return Boolean(rows[0] && rows[0].token === token) diff --git a/web-next/lib/store-pricing.ts b/web-next/lib/store-pricing.ts index 4a98545..498990d 100644 --- a/web-next/lib/store-pricing.ts +++ b/web-next/lib/store-pricing.ts @@ -25,7 +25,7 @@ export const CARD_MIN_EUR: Record<'stripe' | 'sumup', number> = { /** * Máximo de copias de un mismo ítem por línea del carrito (igual que el MAX_QTY * de send-gift). OJO con la diferencia: `copies` es cuántas VECES compras la - * línea, y no se confunde con `home_store_item.quantity`, que es el tamaño del + * línea, y no se confunde con `store_item.quantity`, que es el tamaño del * lote que entrega cada copia (Paño de lino = 20). 2 copias de Paño de lino = * 40 telas, y se envían como dos entradas `2589:20`. */ diff --git a/web-next/lib/store.ts b/web-next/lib/store.ts index 80e0dbe..c54cb85 100644 --- a/web-next/lib/store.ts +++ b/web-next/lib/store.ts @@ -7,7 +7,7 @@ import { MAX_COPIES, PD_PER_EUR, PV_PER_EUR, storeEuroTotal as pureEuroTotal } f /** * Tienda de ítems (transfiguración/equipo), portada del sistema antiguo (BENNU). - * Catálogo en `home_store_category` (árbol por `code` "1-1-1") + `home_store_item` + * Catálogo en `store_category` (árbol por `code` "1-1-1") + `store_item` * (precio en PD o PV, cantidad, icono). Se paga con el saldo PD/PV de la cuenta y * los ítems se envían por correo al personaje elegido (SOAP `.send items`). */ @@ -22,7 +22,7 @@ export function isValidCharName(name: string): boolean { const MAIL_ITEM_LIMIT = 12 // máximo de ítems por correo en AzerothCore export interface StoreItem { - id: number // fila de home_store_item (clave del carrito) + id: number // fila de store_item (clave del carrito) itemId: number name: string icon: string | null @@ -114,10 +114,10 @@ export function parseCategoryName(html: string): NamePart[] { /** * Á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 + * El nombre del ítem sale de `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. El de la - * categoría sale de `home_store_category.name_en` (ver sql/store_category_en.sql). + * `store_item.name` del catálogo original es solo español. El de la + * categoría sale de `store_category.name_en` (ver sql/store_category_en.sql). * En ambos casos, si falta el nombre en ese idioma se cae al del catálogo, que * siempre está. */ @@ -132,13 +132,13 @@ export async function getStoreCatalog(locale: string): Promise try { ;[cats] = await db(DB.default).query( `SELECT code, parent_code, COALESCE(NULLIF(${catNameCol}, ''), name) AS name, css, depth, sort - FROM home_store_category ORDER BY sort`, + FROM store_category ORDER BY sort`, ) ;[items] = await db(DB.default).query( `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 + FROM store_item i + LEFT JOIN item_data d ON d.entry = i.item_id ORDER BY i.sort`, ) } catch { @@ -184,7 +184,7 @@ export async function getStoreBalances(accountId: number): Promise<{ dp: number; if (!accountId) return { dp: 0, vp: 0 } try { const [rows] = await db(DB.default).query( - 'SELECT dp, vp FROM home_api_points WHERE accountID = ?', + 'SELECT dp, vp FROM api_points WHERE accountID = ?', [accountId], ) return rows[0] ? { dp: Number(rows[0].dp), vp: Number(rows[0].vp) } : { dp: 0, vp: 0 } @@ -200,7 +200,7 @@ export interface StoreCartLine { } export interface PricedCart { - // `qty` = lote que entrega CADA copia (home_store_item.quantity); + // `qty` = lote que entrega CADA copia (store_item.quantity); // `copies` = cuántas veces se compra la línea. Total de unidades = qty*copies. // `name` = nombre del catálogo; lo usa el concepto del cobro con tarjeta. lines: { id: number; itemId: number; name: string; qty: number; currency: Currency; price: number; copies: number }[] @@ -217,13 +217,13 @@ export interface PricedCart { * * OJO: la IP va aquí a propósito (identificar al pagador si hay fraude o una * devolución a mano), pero esto se la manda a la pasarela; hasta ahora solo se - * guardaba en `home_stripelog.acore_ip`. Se omite si no se conoce, y también el + * guardaba en `stripelog.acore_ip`. Se omite si no se conoce, y también el * 0.0.0.0 de relleno, que no dice nada. * * Se recorta a `MAX_CONCEPT`: Stripe y SumUp limitan el campo (~250-255), y un * carrito de 100 líneas se pasaría de largo. Se recortan solo los ÍTEMS, nunca * la cabecera: quién ha pagado importa más que el listado completo, que además - * queda entero en `home_store_order`. + * queda entero en `store_order`. */ const MAX_CONCEPT = 200 @@ -255,7 +255,7 @@ export function storeConcept( /** * Valida el carrito contra la BD (precios/cantidades/moneda REALES, nunca del - * cliente) a partir de las filas `home_store_item.id` y las copias pedidas. + * cliente) a partir de las filas `store_item.id` y las copias pedidas. * Devuelve null si está vacío, si alguna copia no es válida o si algún id no * existe en el catálogo (mismo criterio que `priceCart` de send-gift). */ @@ -274,7 +274,7 @@ export async function priceStoreCart(cart: StoreCartLine[]): Promise( - `SELECT id, item_id, name, quantity, currency, price FROM home_store_item WHERE id IN (${ids.map(() => '?').join(',')})`, + `SELECT id, item_id, name, quantity, currency, price FROM store_item WHERE id IN (${ids.map(() => '?').join(',')})`, ids, ) } catch { @@ -353,14 +353,14 @@ export async function purchaseStoreCart( try { await conn.beginTransaction() const [pts] = await conn.query( - 'SELECT dp, vp FROM home_api_points WHERE accountID = ? FOR UPDATE', + 'SELECT dp, vp FROM api_points WHERE accountID = ? FOR UPDATE', [accountId], ) const dp = pts[0] ? Number(pts[0].dp) : 0 const vp = pts[0] ? Number(pts[0].vp) : 0 if (dp < cart.pdTotal) { await conn.rollback(); return { success: false, error: 'insufficientPd' } } if (vp < cart.vpTotal) { await conn.rollback(); return { success: false, error: 'insufficientVp' } } - await conn.query('UPDATE home_api_points SET dp = dp - ?, vp = vp - ? WHERE accountID = ?', [cart.pdTotal, cart.vpTotal, accountId]) + await conn.query('UPDATE api_points SET dp = dp - ?, vp = vp - ? WHERE accountID = ?', [cart.pdTotal, cart.vpTotal, accountId]) await conn.commit() charged = true } catch { @@ -382,7 +382,7 @@ export async function purchaseStoreCart( const vpBack = back('pv') if (charged && (pdBack > 0 || vpBack > 0)) { await db(DB.default) - .query('UPDATE home_api_points SET dp = dp + ?, vp = vp + ? WHERE accountID = ?', [pdBack, vpBack, accountId]) + .query('UPDATE api_points SET dp = dp + ?, vp = vp + ? WHERE accountID = ?', [pdBack, vpBack, accountId]) .catch(() => {}) } // Si no salió ni un correo es el fallo de siempre (SOAP caído). Si salió @@ -430,7 +430,7 @@ export async function createStoreOrder( const amount = storeEuroTotal(cart.pdTotal, cart.vpTotal) try { await db(DB.default).query( - 'INSERT INTO home_store_order (ref, account_id, character_name, items, amount) VALUES (?, ?, ?, ?, ?)', + 'INSERT INTO store_order (ref, account_id, character_name, items, amount) VALUES (?, ?, ?, ?, ?)', [ref, accountId, character, items, amount], ) return true @@ -458,7 +458,7 @@ export async function fulfillStoreOrder( let rows: RowDataPacket[] = [] try { ;[rows] = await db(DB.default).query( - 'SELECT character_name, items, amount FROM home_store_order WHERE ref = ?', + 'SELECT character_name, items, amount FROM store_order WHERE ref = ?', [ref], ) } catch { diff --git a/web-next/lib/stripe.ts b/web-next/lib/stripe.ts index 7d90103..21a611d 100644 --- a/web-next/lib/stripe.ts +++ b/web-next/lib/stripe.ts @@ -9,7 +9,7 @@ const stripe = new Stripe(process.env.STRIPE_SECRET_KEY as string) * * `amountEur` omitido = todo. Stripe cobra en la unidad mínima, así que el * importe va en céntimos. El reembolso se pide sobre el PaymentIntent de la - * sesión de checkout, que es lo que guardamos en `home_stripelog`. + * sesión de checkout, que es lo que guardamos en `stripelog`. */ export async function refundStripeSession(sessionId: string, amountEur?: number): Promise { if (!sessionId) return false @@ -77,7 +77,7 @@ export async function createCheckoutSession( }) const mode = (process.env.STRIPE_SECRET_KEY || '').startsWith('sk_live') ? 'live' : 'test' await db(DB.default).query( - 'INSERT INTO home_stripelog (account_id, username, email, acore_ip, stripe_ip, product_name, amount, session_id, mode, character_name, timestamp, fulfilled) ' + + 'INSERT INTO stripelog (account_id, username, email, acore_ip, stripe_ip, product_name, amount, session_id, mode, character_name, timestamp, fulfilled) ' + 'VALUES (?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, NOW(), 0)', [p.accountId, p.username, p.email, p.acoreIp, p.productName, p.amount, session.id, mode, p.characterName], ) @@ -105,7 +105,7 @@ export async function claimPaidCheckout( return null } const [rows] = await db(DB.default).query( - 'SELECT id, character_name FROM home_stripelog WHERE session_id = ?', + 'SELECT id, character_name FROM stripelog WHERE session_id = ?', [sessionId], ) const log = rows[0] @@ -113,7 +113,7 @@ export async function claimPaidCheckout( // Reclamo ATÓMICO: solo gana quien pasa fulfilled 0->1. Evita doble entrega si // el webhook y la página de éxito corren a la vez. const [res] = await db(DB.default).query( - 'UPDATE home_stripelog SET fulfilled = 1 WHERE id = ? AND fulfilled = 0', + 'UPDATE stripelog SET fulfilled = 1 WHERE id = ? AND fulfilled = 0', [log.id], ) if (res.affectedRows === 0) return null @@ -123,7 +123,7 @@ export async function claimPaidCheckout( /** Registra la IP de Stripe y actualiza el timestamp del log (como el webhook de Django). */ export async function recordStripeIp(sessionId: string, ip: string): Promise { if (!sessionId) return - await db(DB.default).query('UPDATE home_stripelog SET stripe_ip = ?, timestamp = NOW() WHERE session_id = ?', [ + await db(DB.default).query('UPDATE stripelog SET stripe_ip = ?, timestamp = NOW() WHERE session_id = ?', [ ip.slice(0, 45), sessionId, ]) diff --git a/web-next/lib/sumup.ts b/web-next/lib/sumup.ts index 1fc6f81..470e580 100644 --- a/web-next/lib/sumup.ts +++ b/web-next/lib/sumup.ts @@ -43,7 +43,7 @@ interface CreateParams { } /** - * Crea un checkout hospedado de SumUp y registra el pago en `home_stripelog` + * Crea un checkout hospedado de SumUp y registra el pago en `stripelog` * (reutilizamos la tabla de logs; `mode = 'sumup'`, `session_id = reference`). * Devuelve la URL del checkout hospedado para redirigir al usuario. */ @@ -69,7 +69,7 @@ export async function createSumUpCheckout(p: CreateParams): Promise<{ success: b if (!url) return { success: false, error: 'noHostedUrl' } await db(DB.default).query( - 'INSERT INTO home_stripelog (account_id, username, email, acore_ip, stripe_ip, product_name, amount, session_id, mode, character_name, service, metadata, timestamp, fulfilled) ' + + 'INSERT INTO stripelog (account_id, username, email, acore_ip, stripe_ip, product_name, amount, session_id, mode, character_name, service, metadata, timestamp, fulfilled) ' + 'VALUES (?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, NOW(), 0)', [ p.accountId, @@ -170,7 +170,7 @@ export async function fulfillSumUpCheckout( if (!paid) return { ok: false, paid: false } const [rows] = await db(DB.default).query( - 'SELECT id, account_id, amount, service, character_name, metadata FROM home_stripelog WHERE session_id = ? AND mode = ?', + 'SELECT id, account_id, amount, service, character_name, metadata FROM stripelog WHERE session_id = ? AND mode = ?', [reference, 'sumup'], ) const log = rows[0] @@ -178,7 +178,7 @@ export async function fulfillSumUpCheckout( // Reclamo atómico: sólo gana quien pasa fulfilled 0->1. const [res] = await db(DB.default).query( - 'UPDATE home_stripelog SET fulfilled = 1 WHERE id = ? AND fulfilled = 0', + 'UPDATE stripelog SET fulfilled = 1 WHERE id = ? AND fulfilled = 0', [log.id], ) if (res.affectedRows === 0) return { ok: false, paid: true } @@ -215,7 +215,7 @@ export async function fulfillSumUpCheckout( /** * Reconciliación: SumUp ya no ofrece webhooks, así que la entrega no puede * depender de que el navegador vuelva al `return_url`. Esta función recorre los - * checkouts SumUp pendientes (fulfilled=0) registrados en `home_stripelog`, + * checkouts SumUp pendientes (fulfilled=0) registrados en `stripelog`, * consulta su estado en la API de SumUp y acredita los que estén PAID. * * - Sin `accountId`: backstop global (para un cron). Con `accountId`: reconcilia @@ -227,7 +227,7 @@ export async function reconcileSumUpCheckouts(opts?: { accountId?: number; maxAg if (!sumupConfigured()) return 0 const maxAgeDays = opts?.maxAgeDays ?? 7 let sql = - "SELECT session_id FROM home_stripelog WHERE mode = 'sumup' AND fulfilled = 0 AND timestamp > (NOW() - INTERVAL ? DAY)" + "SELECT session_id FROM stripelog WHERE mode = 'sumup' AND fulfilled = 0 AND timestamp > (NOW() - INTERVAL ? DAY)" const params: (string | number)[] = [maxAgeDays] if (opts?.accountId) { sql += ' AND account_id = ?' diff --git a/web-next/lib/trade.ts b/web-next/lib/trade.ts index 0e8c3f6..441e13b 100644 --- a/web-next/lib/trade.ts +++ b/web-next/lib/trade.ts @@ -54,7 +54,7 @@ function generateCode(): string { async function expireOldCodes(): Promise { try { await db(DB.default).query( - "UPDATE home_tradecode SET status = 'expired' WHERE status = 'active' AND expires_at <= NOW()", + "UPDATE tradecode SET status = 'expired' WHERE status = 'active' AND expires_at <= NOW()", ) } catch { /* ignore */ @@ -102,12 +102,12 @@ export async function createTradeCode(params: { // para no poder crear códigos que no se puedan respaldar. try { const [bal] = await db(DB.default).query( - 'SELECT dp FROM home_api_points WHERE accountID = ?', + 'SELECT dp FROM api_points WHERE accountID = ?', [creatorAccount], ) const balance = bal[0] ? Number(bal[0].dp) : 0 const [act] = await db(DB.default).query( - "SELECT COALESCE(SUM(points), 0) AS reserved FROM home_tradecode WHERE creator_account = ? AND status = 'active' AND expires_at > NOW()", + "SELECT COALESCE(SUM(points), 0) AS reserved FROM tradecode WHERE creator_account = ? AND status = 'active' AND expires_at > NOW()", [creatorAccount], ) const reserved = Number(act[0]?.reserved ?? 0) @@ -120,7 +120,7 @@ export async function createTradeCode(params: { const expiresAt = new Date(Date.now() + CODE_TTL_MS) try { await db(DB.default).query( - `INSERT INTO home_tradecode + `INSERT INTO tradecode (code, creator_account, creator_character, points, gold, status, created_at, expires_at) VALUES (?, ?, ?, ?, ?, 'active', NOW(), ?)`, [code, creatorAccount, creatorCharacter, points, gold, expiresAt], @@ -138,7 +138,7 @@ export async function checkTradeCode(code: string): Promise<{ success: boolean; await expireOldCodes() try { const [rows] = await db(DB.default).query( - "SELECT points, gold, status, expires_at FROM home_tradecode WHERE code = ? LIMIT 1", + "SELECT points, gold, status, expires_at FROM tradecode WHERE code = ? LIMIT 1", [trimmed], ) const row = rows[0] @@ -175,7 +175,7 @@ export async function redeemTradeCode(params: { // Bloqueo de 5 s: la cuenta no puede canjear si acaba de canjear otro código. try { const [recent] = await db(DB.default).query( - `SELECT id FROM home_tradecode + `SELECT id FROM tradecode WHERE redeemer_account = ? AND redeemed_at > (NOW() - INTERVAL ? SECOND) LIMIT 1`, [buyerAccount, REDEEM_LOCK_SECONDS], ) @@ -193,7 +193,7 @@ export async function redeemTradeCode(params: { let gold = 0 try { const [rows] = await db(DB.default).query( - "SELECT creator_account, creator_character, points, gold, status, expires_at FROM home_tradecode WHERE code = ? LIMIT 1", + "SELECT creator_account, creator_character, points, gold, status, expires_at FROM tradecode WHERE code = ? LIMIT 1", [trimmedCode], ) const row = rows[0] @@ -223,7 +223,7 @@ export async function redeemTradeCode(params: { let claimed = false try { const [res] = await db(DB.default).query( - `UPDATE home_tradecode + `UPDATE tradecode SET status = 'redeemed', redeemer_account = ?, redeemer_character = ?, redeemed_at = NOW() WHERE code = ? AND status = 'active' AND expires_at > NOW()`, [buyerAccount, buyerCharacter, trimmedCode], @@ -237,7 +237,7 @@ export async function redeemTradeCode(params: { const revertClaim = async () => { try { await db(DB.default).query( - "UPDATE home_tradecode SET status = 'active', redeemer_account = NULL, redeemer_character = NULL, redeemed_at = NULL WHERE code = ?", + "UPDATE tradecode SET status = 'active', redeemer_account = NULL, redeemer_character = NULL, redeemed_at = NULL WHERE code = ?", [trimmedCode], ) } catch { diff --git a/web-next/lib/trans-history.ts b/web-next/lib/trans-history.ts index e7b4201..a355855 100644 --- a/web-next/lib/trans-history.ts +++ b/web-next/lib/trans-history.ts @@ -2,7 +2,7 @@ import type { RowDataPacket } from 'mysql2' import { db, DB } from './db' import { buildConcept } from './tx-concept' -/** Una transacción de pago (Stripe o SumUp) registrada en home_stripelog. */ +/** Una transacción de pago (Stripe o SumUp) registrada en stripelog. */ export interface PaymentTx { id: string // referencia de la pasarela (session_id / checkout_reference) platform: 'Stripe' | 'SumUp' @@ -16,7 +16,7 @@ export interface PaymentTx { } /** - * Transacciones de pago de una cuenta desde `home_stripelog`, limitadas a las + * Transacciones de pago de una cuenta desde `stripelog`, limitadas a las * dos pasarelas activas: **Stripe** (mode test/live) y **SumUp** (mode sumup). * `fulfilled` 1 -> PAID (pagado y entregado), 0 -> PENDING. Orden por fecha desc. */ @@ -24,7 +24,7 @@ export async function getPaymentTransactions(accountId: number, limit = 200): Pr if (!accountId) return [] try { const [rows] = await db(DB.default).query( - 'SELECT session_id, product_name, character_name, amount, mode, service, metadata, fulfilled, timestamp FROM home_stripelog ' + + 'SELECT session_id, product_name, character_name, amount, mode, service, metadata, fulfilled, timestamp FROM stripelog ' + "WHERE account_id = ? AND mode IN ('sumup', 'test', 'live') ORDER BY timestamp DESC LIMIT ?", [accountId, limit], ) diff --git a/web-next/lib/transfer-character.ts b/web-next/lib/transfer-character.ts index 7f8466d..4cac909 100644 --- a/web-next/lib/transfer-character.ts +++ b/web-next/lib/transfer-character.ts @@ -69,7 +69,7 @@ export async function checkTransferEligibility( // Bloqueo de 5 s tras una transferencia reciente de esta cuenta. try { const [recent] = await db(DB.default).query( - "SELECT id FROM home_stripelog WHERE account_id = ? AND service = 'transfer' AND fulfilled = 1 AND timestamp > (NOW() - INTERVAL 5 SECOND) LIMIT 1", + "SELECT id FROM stripelog WHERE account_id = ? AND service = 'transfer' AND fulfilled = 1 AND timestamp > (NOW() - INTERVAL 5 SECOND) LIMIT 1", [accountId], ) if (recent[0]) return { ok: false, message: 'Espera unos segundos antes de transferir otro personaje.' } diff --git a/web-next/lib/tx-concept.ts b/web-next/lib/tx-concept.ts index a26637b..690890e 100644 --- a/web-next/lib/tx-concept.ts +++ b/web-next/lib/tx-concept.ts @@ -1,8 +1,8 @@ -// Concepto traducible de una transacción de home_stripelog, compartido por los +// Concepto traducible de una transacción de stripelog, compartido por los // historiales de PD/PV y de transacciones. Devuelve una CLAVE (+ argumentos) que // la página traduce; `conceptRaw` es la reserva para pagos heredados sin servicio. -/** Slug de servicio (home_stripelog.service) -> clave de concepto (History.points.concept.*). */ +/** Slug de servicio (stripelog.service) -> clave de concepto (History.points.concept.*). */ export const SERVICE_CONCEPT: Record = { rename: 'rename', customize: 'customize', @@ -37,7 +37,7 @@ export interface Concept { } /** - * Concepto de una fila de home_stripelog: compra de PD -> "{n} PD"; servicio + * Concepto de una fila de stripelog: compra de PD -> "{n} PD"; servicio * conocido -> "{etiqueta}: {personaje}"; en otro caso, texto libre heredado. */ export function buildConcept( diff --git a/web-next/lib/vote.ts b/web-next/lib/vote.ts index e5f5d60..3bee7eb 100644 --- a/web-next/lib/vote.ts +++ b/web-next/lib/vote.ts @@ -23,7 +23,7 @@ export interface VoteResult { export async function getVoteSites(): Promise { try { const [rows] = await db(DB.default).query( - 'SELECT id, name, url, image_url, points FROM home_votesite ORDER BY id', + 'SELECT id, name, url, image_url, points FROM votesite ORDER BY id', ) return rows.map((r) => ({ id: r.id, name: r.name, url: r.url, image_url: r.image_url, points: r.points })) } catch { @@ -42,7 +42,7 @@ export async function getVoteSitesForAccount(accountId: number): Promise ({ ...s, lastVoteAt: null, onCooldown: false })) try { const [rows] = await db(DB.default).query( - 'SELECT vote_site_id, MAX(created_at) AS last FROM home_votelog WHERE account_id = ? GROUP BY vote_site_id', + 'SELECT vote_site_id, MAX(created_at) AS last FROM votelog WHERE account_id = ? GROUP BY vote_site_id', [accountId], ) const map = new Map(rows.map((r) => [Number(r.vote_site_id), r.last as Date])) @@ -62,14 +62,14 @@ export async function getVoteSitesForAccount(accountId: number): Promise { const [siteRows] = await db(DB.default).query( - 'SELECT id, name, points FROM home_votesite WHERE url = ?', + 'SELECT id, name, points FROM votesite WHERE url = ?', [url], ) const site = siteRows[0] if (!site) return { success: false, error: 'siteNotFound' } const [last] = await db(DB.default).query( - 'SELECT created_at FROM home_votelog WHERE account_id = ? AND vote_site_id = ? ORDER BY created_at DESC LIMIT 1', + 'SELECT created_at FROM votelog WHERE account_id = ? AND vote_site_id = ? ORDER BY created_at DESC LIMIT 1', [accountId, site.id], ) if (last[0]) { @@ -81,15 +81,15 @@ export async function registerVote(accountId: number, url: string): Promise('SELECT id FROM home_api_points WHERE accountID = ?', [accountId]) + const [pts] = await db(DB.default).query('SELECT id FROM api_points WHERE accountID = ?', [accountId]) if (pts[0]) { - await db(DB.default).query('UPDATE home_api_points SET vp = vp + ? WHERE accountID = ?', [site.points, accountId]) + await db(DB.default).query('UPDATE api_points SET vp = vp + ? WHERE accountID = ?', [site.points, accountId]) } else { - await db(DB.default).query('INSERT INTO home_api_points (accountID, vp, dp) VALUES (?, ?, 0)', [accountId, site.points]) + await db(DB.default).query('INSERT INTO api_points (accountID, vp, dp) VALUES (?, ?, 0)', [accountId, site.points]) } await db(DB.default).query( - 'INSERT INTO home_votelog (account_id, vote_site_id, created_at, last_vote_time, processed) VALUES (?, ?, NOW(), NOW(), 0)', + 'INSERT INTO votelog (account_id, vote_site_id, created_at, last_vote_time, processed) VALUES (?, ?, NOW(), NOW(), 0)', [accountId, site.id], )