Fecha de Última Actualización: 09 de Mayo de 2025
Esta guía recopila problemas técnicos significativos o no obvios encontrados durante el desarrollo de LoyalPyME, sus causas y soluciones, para agilizar futuras depuraciones.
NUEVO: Problemas con el Script de Seed (npx prisma db seed)
A. npx prisma db seed no ejecuta el script prisma/seed.ts o no muestra console.logs:
- Síntomas: El comando
npx prisma db seedse completa rápidamente sin mostrar losconsole.logdel scriptseed.ts, y la base de datos no se puebla. Sin embargo, ejecutarnpx ts-node ./prisma/seed.tsdirectamente SÍ funciona y muestra los logs. - Causa Más Probable: Prisma CLI (v5+) no está encontrando o interpretando correctamente la configuración para ejecutar el script de seed TypeScript.
- Solución Crítica:
- Asegurar
package.json(enbackend/): Dentro de tubackend/package.json, añade o verifica una sección"prisma"que defina el comando de seed:{ // ... otras secciones ... "prisma": { "seed": "ts-node prisma/seed.ts" // La opción --compiler-options "{\"module\":\"commonjs\"}" puede causar errores TS5023 // Es mejor confiar en el tsconfig.json del proyecto si está configurado para commonjs. } } - Asegúrate de que
ts-nodeestá en tusdevDependencies. - Ejecuta
npx prisma db seeddesde la misma carpeta donde está elpackage.jsonque contiene la sección"prisma"(normalmentebackend/).
- Asegurar
B. Error TSError: ⨯ Unable to compile TypeScript: error TS5023: Unknown compiler option 'X' al ejecutar npx prisma db seed:
- Síntomas: El comando
npx prisma db seedfalla con erroresTS5023indicando opciones de compilador desconocidas (a menudo números o caracteres sueltos). - Causa: El comando definido en
package.jsonpara el seed (bajo"prisma": { "seed": "..." }) tiene una sintaxis incorrecta para pasar argumentos como--compiler-optionsats-node, usualmente debido a problemas con el escapado de comillas dentro del JSON delpackage.json. - Solución: Simplifica el comando de seed en
package.jsona:Asegúrate que tu"prisma": { "seed": "ts-node prisma/seed.ts" }
backend/tsconfig.jsontiene"module": "commonjs"(o el módulo que estés usando para tu backend).
C. Errores de TypeScript en seed.ts (ej: Property 'X' does not exist on type 'BusinessCreateInput') después de modificar schema.prisma:
- Síntomas: El editor o la compilación de
ts-nodemuestra errores de TypeScript enseed.tsindicando que campos recién añadidos al schema no existen en los tipos de entrada generados por Prisma (ej:BusinessCreateInput). - Causa: El Cliente Prisma (
node_modules/.prisma/client) no se ha regenerado después de la última migración exitosa deschema.prisma(migrate devomigrate reset). - Solución Crítica: SIEMPRE ejecuta
npx prisma generateenbackend/después de cadanpx prisma migrate devonpx prisma migrate resetexitoso. Si el editor sigue mostrando errores, reinicia el servidor TypeScript de tu editor (ej: en VS Code, Ctrl+Shift+P -> "TypeScript: Restart TS server").
D. Error P3018 (Migration failed to apply) con DETAIL: La llave (businessId)=... no está presente en la tabla «Business» al intentar migrar schema.prisma después de cambios estructurales:
- Síntomas:
npx prisma migrate devfalla conP3018y un error de base de datos sobre violación de clave foránea (usualmenteERROR: inserción o actualización en la tabla «YYY» viola la llave foránea «YYY_businessId_fkey»). Prisma también puede advertir sobreDROPde tablas no vacías antes de intentar la migración. - Causa: Un cambio estructural grande (ej: hacer opcional un campo que era parte de una relación obligatoria, cambiar tipos de campos relacionados, etc.) hace que Prisma determine que necesita recrear tablas. Si tienes datos existentes, Prisma intenta aplicar los cambios, pero si los datos se reinsertan en un orden incorrecto (ej: un
Tierantes que suBusinessasociado si la tablaBusinessfue recreada) o si los datos referenciados se pierden temporalmente durante la migración, las restricciones de claves foráneas pueden fallar. - Solución (Para Desarrollo donde los datos NO son críticos): La forma más limpia y rápida es resetear la base de datos. Esto eliminará todos los datos existentes y aplicará todas las migraciones desde cero sobre una BD limpia.
Confirma la acción cuando se te pregunte. Luego, no olvides ejecutar
npx prisma migrate reset
npx prisma generatey, si tienes un script de seed,npx prisma db seed. - Solución (Para Producción o datos críticos - ¡CON MUCHO CUIDADO!): Esto es mucho más complejo. Implica analizar el SQL generado por la migración fallida (en
prisma/migrations/.../migration.sql), entender por qué falla, y potencialmente editar ese SQL o realizar operaciones manuales en la BD para preparar los datos ANTES de reintentar la migración. A menudo es preferible hacer cambios más pequeños e incrementales en producción o tener una estrategia de backup/restore robusta. Consulta la documentación de Prisma sobre "Resolving failed migrations".
(Aquí continúa el resto de tu contenido original de TROUBLESHOOTING_GUIDE.md) (Me aseguro de incluir los puntos que ya tenías)
1. Backend: Inestabilidad con yarn dev (nodemon + ts-node)
- Síntomas: Reinicios inesperados, errores
SyntaxError, cambios no reflejados. - Causa: Conflictos/inestabilidad de
ts-node-dev/nodemoncon módulos ES/CJS en el entorno. - Solución Estable: Usar dos terminales en
backend/:npx tsc --watch(Compilación continua)npx nodemon dist/index.js(Ejecución con reinicio automático al cambiardist/)
2. Backend: Cambios en .ts No Se Reflejan / Ruta Nueva da 404 / Lógica Antigua se Ejecuta
- Síntomas: Modificas código en un archivo
.ts(ej: un servicio), pero la API sigue comportándose como antes (ej: no guarda un campo nuevo, usa lógica vieja). O creas una ruta nueva y da 404. - Causa: El proceso
nodeque ejecutanodemonsolo vigila cambios en la carpetadist/. Si no tienesnpx tsc --watchcorriendo o no has ejecutadoyarn buildmanualmente después de guardar el.ts, los cambios no se compilan a JavaScript endist/. Además, si añades una nueva ruta, debes asegurarte de montarla conapp.use()enindex.ts. - Solución Crítica: SIEMPRE asegúrate de que los cambios en
.tsse compilen adist/(tsc --watchoyarn build). Si añades rutas, asegúrate de queindex.tslas importa y las monta (app.use(...)). Reinicianodemondespués de cambiarindex.ts. Si persiste, forzar limpieza:rm -rf dist && yarn build && npx nodemon dist/index.js. (Visto con rutas /api/customer/activity y /api/uploads/image)
3. Frontend: Cambios No Se Aplican (Vite HMR)
- Síntomas: Funcionalidad no cambia, estilos viejos, etc., tras guardar archivo.
- Solución: 1. Verificar terminal
yarn devpor errores. 2. Refresco forzado navegador (Ctrl+Shift+R). 3. Reiniciaryarn dev(Ctrl+Cyyarn dev --host), especialmente tras cambios envite.config.ts.
4. Backend: Errores TS2305 (Module '"@prisma/client"' has no exported member 'User', 'Reward', etc.)
- Síntomas: TypeScript no encuentra ninguno de los tipos/enums generados por Prisma al importar desde
@prisma/client, incluso después de una migración exitosa. Ocurre al compilar (npx tsc). - Causa: La generación del Cliente Prisma (
node_modules/.prisma/client) está incompleta, corrupta, o no se ejecutó/terminó correctamente después de la última migración (prisma migrate).tscno puede encontrar las definiciones de tipos necesarias. - Solución Crítica: Ejecutar explícitamente
npx prisma generateenbackend/después de cadaprisma migrate devexitoso. Asegurarse de queprisma generatetermina sin errores. Reiniciar el servidor TS del editor si es necesario. Si persiste, borrarnode_modules/.prisma/clientmanualmente y regenerar.
5. Backend: Dependencias Circulares (TS)
- Síntomas: Errores de ciclo de importación entre archivos.
- Solución: Mover definiciones (interfaces, tipos) a archivos independientes e importar desde allí.
6. Backend: API no se conecta a Base de Datos (PrismaClientInitializationError)
- Síntomas: Endpoints fallan con 500, logs muestran error de conexión a DB. Frecuente tras reinicios del sistema.
- Solución: 1. Verificar que servicio PostgreSQL corre. 2. Verificar
DATABASE_URLen.env. 3. Ejecutarnpx prisma migrate devsi la BD está vacía/corrupta (onpx prisma migrate reseten desarrollo).
7. Frontend: Error 401 al llamar a Rutas Públicas Backend desde axiosInstance
- Estado: Resuelto (Backend v1.3.0+).
- Causa Antigua: Middleware
authenticateTokenaplicado globalmente a/api. - Solución Aplicada: Middlewares aplicados individualmente a rutas protegidas en
backend/src/index.ts. Rutas públicas (/api/auth/*,/public/*) no llevan middleware global. UsaraxiosInstancepara/api/*(incl./api/auth) yaxiosbase para/public/*.
8. Frontend: Formulario Mantine parece vacío tras cargar datos
- Estado: Resuelto (en
TierSettingsPage.tsx). - Causa Antigua: Llamada incorrecta a
form.reset()después deform.setValues()en la carga. - Solución Aplicada: Eliminar
form.reset()de la función de carga inicial. Usarform.setValues()y luegoform.reset()después de un guardado exitoso para actualizar valores base y limpiar estado 'dirty'.
9. Mobile: Escáner QR falla (setPhotoOptions failed)
- Estado: Resuelto (Obsoleto).
- Causa Antigua: Bug/incompatibilidad en
react-qr-reader. - Solución Aplicada: Reemplazo por
html5-qrcodey uso del hookuseQrScanner.
10. Git: Error Deletion of directory '...' failed (Windows)
- Causa: Bloqueo de archivo/carpeta por otro programa.
- Solución: Cerrar programas ->
git merge --abort/git reset --hard HEAD(si necesario) ->git pull.
11. Testing Backend (Vitest): Test file no se descubre
- Síntomas: Tests en archivo
.tsno se ejecutan. - Causa: Nombre de archivo no termina en
.test.tso.spec.ts. - Solución: Renombrar archivo correctamente.
12. Testing Backend (Vitest): Mocking de Prisma falla (Cannot read properties of undefined, spy not called)
- Síntomas: Tests unitarios de funciones que usan
new PrismaClient()internamente fallan al intentar mockear Prisma. - Causa: Instancia interna de Prisma ignora mocks globales (
vi.mock). - Solución Aplicada: Inyección de Dependencias. 1. Refactorizar función/helper para aceptar
prismaClientcomo argumento. 2. En el test, crear mock simple y pasarlo como argumento.
13. Testing Backend (Vitest/TS): Errores TS2352/TS2554 persistentes (Mock vs Type)
- Síntomas:
tscse queja de incompatibilidad de tipos entre el mock simple pasado por DI y el tipo esperado (Pick<PrismaClient,...>) o de número incorrecto de argumentos. - Causa: Discrepancia estructural grande entre mock y tipo real, o TS server cache/resolución incorrecta de firmas tras refactor.
- Solución Aplicada: 1. Asegurar archivo fuente (
.ts) guardado y compilado (yarn build). 2. Reiniciar servidor TS en VS Code. 3. Si persiste, usar// @ts-expect-erroren la línea anterior a la llamada dentro del archivo.test.ts.
14. Testing Integración (Supertest): Error 401 devuelve text/plain, no JSON
- Síntomas: Test que espera 401 por falta de token falla por
Content-Type. - Causa: Middleware
authenticateTokenusares.sendStatus(401)que responde context/plain. - Solución: En esos tests específicos, eliminar la aserción
.expect('Content-Type', /json/).
15. Testing Integración (Supertest): Test Login 401 (Éxito esperado)
- Causa: Credenciales hardcodeadas en el test no coinciden con las de la BD de prueba.
- Solución: Verificar/corregir usuario admin de test en BD. Considerar usar variables de entorno para credenciales de test.
16. Testing Integración (Supertest): Setup Falla - Registro Cliente (DNI Inválido)
- Causa: DNI generado aleatoriamente en
beforeAllno tenía letra de control válida. - Solución: Añadir función helper
generateValidDni()al test setup para crear DNIs válidos.
17. Testing Integración (Supertest): Ruta PATCH devuelve HTML/404
- Causa: Olvido de definir la ruta
router.patch(...)en el archivo.routes.ts. - Solución: Añadir la definición de la ruta PATCH en el router.
18. Testing Integración (Supertest): Error 500 en lugar de 400 (Validación) o 409 (Conflicto)
- Causa: Falta validación de entrada en controlador; Error P2002 (Unique Constraint) de Prisma no manejado específicamente en el
catchdel controlador. - Solución: Añadir validaciones en controlador; Añadir
if (error instanceof Error && error.message.includes(...))específico para unicidad encatchpara devolver 409.
19. Frontend (i18n): Claves (loginPage.title, desc_REDEEMED) se muestran en lugar de texto traducido
- Causa: Clave no encontrada en el archivo de idioma (
translation.json) cargado para el idioma actual (ej:en). Puede ser por error tipográfico en la clave (código vs JSON), error de sintaxis en el archivo JSON que impide su carga completa, o clave no añadida a todos los archivos de idioma necesarios. - Solución: Verificar coincidencia exacta de claves. Validar sintaxis JSON. Asegurar que la clave existe en los archivos de todos los idiomas soportados (
es,en). Usardebug: trueeni18n.tsy revisar consola pori18next: missingKey ....
20. Frontend: Banderas de Idioma (Emoji Unicode) no se renderizan
- Causa: Falta de soporte de fuente en el sistema/navegador.
- Solución: Usar una librería como
react-country-flagque utiliza SVG.
21. Frontend: Navbar Móvil Admin no se cierra automáticamente
- Causa: Componente Navbar no tenía acceso a función
close. - Solución: Pasar
close(deuseDisclosure) como prop desde Layout a Navbar y llamarla enonClickdel enlace.
22. PowerShell: Sintaxis para curl y JSON
- Solución: Usar
Invoke-RestMethodcon parámetros PowerShell (-Method,-Headers @{},-Body ($obj | ConvertTo-Json -Depth N)).
23. Backend: Subida de Imágenes Cloudinary Falla (Error 500 o 401)
- Síntomas: Error 500/401 desde backend al subir, logs indican
Invalid cloud_nameoUnknown API key. - Causas: Credenciales (
.env) incorrectas/mezcladas, backend no reiniciado tras cambiar.env, error lectura.env, problema cuenta Cloudinary. - Solución Aplicada: Crear cuenta Cloudinary nueva, obtener credenciales nuevas, ponerlas correctamente en
.env(CLOUDINARY_CLOUD_NAME,_API_KEY,_API_SECRET), reiniciar backend.
24. Backend/Frontend: Campo Nuevo (ej: imageUrl, name_es) Se Guarda/Recibe Como null o Da Error de Tipo
- Síntomas: Campo nuevo no se guarda en BD, o el frontend da error de tipo (ej:
Property 'name_es' does not exist on type 'Reward') al intentar usar datos de la API. - Causas:
- Backend: Controlador no extrae/pasa el campo al servicio; Servicio no incluye campo en
prisma.create/update; Servicio no incluye campo enselectal leer;tscno recompilódist/. - Frontend: Tipo/Interfaz (
types/customer.ts) no actualizado; Hook que obtiene datos no usa/devuelve el tipo actualizado; Componente que muestra datos usa el nombre de campo antiguo.
- Backend: Controlador no extrae/pasa el campo al servicio; Servicio no incluye campo en
- Solución: Verificar/corregir toda la cadena: Controlador (extracción/paso) -> Servicio (guardado) -> Servicio (lectura
select) -> Backend Compilación (tsc) -> Frontend Tipo (types/customer.ts) -> Frontend Hook (estado/retorno) -> Frontend Componente (acceso a propiedad correcta, ej:reward.name_es).
25. Mobile: Escáner QR (html5-qrcode) No Se Inicia / Error "Element ... not found"
- Síntomas: Al abrir modal de escáner en móvil, la cámara no inicia, consola muestra
Element with ID '...' not found. - Causa: Timing:
useEffectdel hookuseQrScannerintenta inicializarHtml5Qrcodeantes de que el DOM del modal esté completamente listo. - Solución/Workaround Aplicado: En
useQrScanner.ts, envolver la inicialización (new Html5Qrcode,scannerInstance.start) dentro de unsetTimeout(() => { ... }, 500). Limpiar timeout en cleanup. Corregir tipo deuseRefpara timeout anumber | null.
26. Backend: Error TS2307 (Cannot find module '...') Persistente
- Síntomas:
npx tscsigue fallando al importar un módulo (ej:./uploads.servicedesdeuploads.controller) incluso después de verificar exportaciones y limpiardist. - Causa Probable: Nombre de archivo incorrecto en el disco (ej:
upload.controller.tsvsuploads.controller.ts); Error interno en el archivo que se intenta importar (uploads.service.ts) que impide atscanalizarlo; Problema cachétsc. - Solución: Verificar exactamente el nombre del archivo en disco y en la importación. Revisar el código del archivo importado en busca de errores. Forzar recompilación limpia (
rm -rf dist && npx tsc).
27. Frontend: Error TS2322 (Type '... | TFunctionDetailedResult' is not assignable to type 'string'/'ReactNode') Persistente
- Síntomas: Error de tipo al asignar el resultado de
t()(de i18next) a una prop que esperastringoReactNode(ej:titleenTimeline.Item), incluso después de intentar conversiones (String(), template literals). - Causa Probable: Inferencia de tipos compleja de
t()con interpolación; Problema de tipos específico de la versión de Mantine/i18next/TS; Caché/Entorno. - Solución Aplicada: Usar aserción de tipo
as string(prop={resultado_t as string}) o variable intermedia tipada explícitamente (const titulo: string = String(resultado_t); prop={titulo}). Si persiste, resetear entorno (rm -rf node_modules yarn.lock && yarn install).
28. Frontend: Error Runtime Mantine (Tooltip component children should be an element or component that accepts ref...)
- Síntomas: La aplicación falla en runtime al renderizar un
Tooltip. - Causa: El hijo directo del
Tooltipno es un elemento/componente válido que acepteref(ej: Fragment<>...</>, texto suelto, o componente complejo anidado). A veces relacionado con advertencias de hidratación por whitespace. - Solución: Asegurar que el hijo directo del
Tooltipsea un único elemento válido (ej:<ActionIcon>,<Button>). Si es necesario, envolver el contenido en un<Box>. Limpiar espacios en blanco en JSX de tablas (Table,Thead,Tr, etc.).
(Fin de la Guía)