From 5f604b11ba21b958a018772c9db5e7d346083098 Mon Sep 17 00:00:00 2001 From: Ichitux Date: Thu, 9 Jul 2026 00:58:31 +0200 Subject: [PATCH] Frontend Hotfixes & Backend improvements --- .mimocode/.cron-lock | 1 + apps/backend/cima-service.js | 48 +++++++++++++++---- apps/frontend-mobile/app/(tabs)/map.tsx | 2 +- apps/frontend-mobile/app/_layout.tsx | 4 +- apps/frontend-mobile/app/medicine/[id].tsx | 13 ++--- .../components/MedicineCard.tsx | 10 ++-- apps/frontend-mobile/constants/config.ts | 4 +- apps/frontend-mobile/types/index.ts | 22 ++++++--- 8 files changed, 73 insertions(+), 31 deletions(-) create mode 100644 .mimocode/.cron-lock diff --git a/.mimocode/.cron-lock b/.mimocode/.cron-lock new file mode 100644 index 0000000..2c7e60e --- /dev/null +++ b/.mimocode/.cron-lock @@ -0,0 +1 @@ +{"pid":864463,"startedAt":1783550197179} \ No newline at end of file diff --git a/apps/backend/cima-service.js b/apps/backend/cima-service.js index be824ee..ad185fd 100644 --- a/apps/backend/cima-service.js +++ b/apps/backend/cima-service.js @@ -151,19 +151,52 @@ export async function getMedicineDetails(nregistro) { return JSON.parse(cachedData); } - // Consultar la API de CIMA + // Intentar obtener de la API de CIMA (endpoint individual puede no existir) console.log(`🌐 Fetching medicine details from CIMA: ${nregistro}`); - const response = await axios.get(`${CIMA_API_BASE_URL}/medicamento/${nregistro}`, { + try { + const response = await axios.get(`${CIMA_API_BASE_URL}/medicamento/${nregistro}`, { + timeout: 5000 + }); + + if (response.data) { + const med = response.data; + const medicineDetails = { + id: med.nregistro, + nregistro: med.nregistro, + name: med.nombre, + active_ingredient: med.principiosActivos?.[0]?.nombre || med.vtm?.nombre || null, + dosage: med.dosis || null, + form: med.formaFarmaceutica?.nombre || null, + formSimplified: med.formaFarmaceuticaSimplificada?.nombre || null, + laboratory: med.labtitular, + prescription: med.cpresc, + commercialized: med.comerc, + generic: med.generico, + photos: med.fotos || [], + docs: med.docs || [], + presentations: med.presentaciones || [] + }; + + await redisClient.setEx(cacheKey, CACHE_TTL * 24, JSON.stringify(medicineDetails)); + return medicineDetails; + } + } catch (apiError) { + console.log(`⚠️ Individual medicine endpoint failed, trying search fallback`); + } + + // Fallback: buscar por nregistro usando el endpoint de búsqueda + const searchResponse = await axios.get(`${CIMA_API_BASE_URL}/medicamentos`, { + params: { nregistro }, timeout: 5000 }); - if (response.data) { - const med = response.data; + if (searchResponse.data?.resultados?.length > 0) { + const med = searchResponse.data.resultados[0]; const medicineDetails = { id: med.nregistro, nregistro: med.nregistro, name: med.nombre, - active_ingredient: med.principiosActivos?.[0]?.nombre || med.vtm?.nombre || null, + active_ingredient: med.vtm?.nombre || null, dosage: med.dosis || null, form: med.formaFarmaceutica?.nombre || null, formSimplified: med.formaFarmaceuticaSimplificada?.nombre || null, @@ -172,13 +205,10 @@ export async function getMedicineDetails(nregistro) { commercialized: med.comerc, generic: med.generico, photos: med.fotos || [], - docs: med.docs || [], - presentations: med.presentaciones || [] + docs: med.docs || [] }; - // Guardar en caché (TTL más largo para detalles específicos) await redisClient.setEx(cacheKey, CACHE_TTL * 24, JSON.stringify(medicineDetails)); - return medicineDetails; } diff --git a/apps/frontend-mobile/app/(tabs)/map.tsx b/apps/frontend-mobile/app/(tabs)/map.tsx index 33c49ae..12051e7 100644 --- a/apps/frontend-mobile/app/(tabs)/map.tsx +++ b/apps/frontend-mobile/app/(tabs)/map.tsx @@ -4,7 +4,7 @@ import MapView, { Marker } from 'react-native-maps'; import { useRouter } from 'expo-router'; import { getPharmacies } from '../../services/pharmacies'; import { LoadingSpinner } from '../../components/LoadingSpinner'; -import { colors, spacing } from '../../constants/theme'; +import { colors, spacing, borderRadius } from '../../constants/theme'; import { Pharmacy } from '../../types'; export default function MapScreen() { diff --git a/apps/frontend-mobile/app/_layout.tsx b/apps/frontend-mobile/app/_layout.tsx index 84a01a4..6b105a4 100644 --- a/apps/frontend-mobile/app/_layout.tsx +++ b/apps/frontend-mobile/app/_layout.tsx @@ -97,10 +97,10 @@ const bgStyles = StyleSheet.create({ flex: 1, }, backgroundImage: { - opacity: 0.5, + opacity: 0.8, }, overlay: { ...StyleSheet.absoluteFillObject, - backgroundColor: 'rgba(255, 252, 245, 0.48)', + backgroundColor: 'rgba(255, 252, 245, 0.2)', }, }); diff --git a/apps/frontend-mobile/app/medicine/[id].tsx b/apps/frontend-mobile/app/medicine/[id].tsx index e2166e0..ffb8630 100644 --- a/apps/frontend-mobile/app/medicine/[id].tsx +++ b/apps/frontend-mobile/app/medicine/[id].tsx @@ -56,17 +56,18 @@ export default function MedicineDetailScreen() { return ( - {medicine.nombre} - + {medicine.name} + {medicine.stock != null && } - - - + + + + diff --git a/apps/frontend-mobile/components/MedicineCard.tsx b/apps/frontend-mobile/components/MedicineCard.tsx index e7649e1..2f077e2 100644 --- a/apps/frontend-mobile/components/MedicineCard.tsx +++ b/apps/frontend-mobile/components/MedicineCard.tsx @@ -29,27 +29,27 @@ export function MedicineCard({ medicine }: MedicineCardProps) { > - {medicine.nombre} + {medicine.name} - + {medicine.stock != null && } - {medicine.principioActivo} + {medicine.active_ingredient}{medicine.dosage ? ` - ${medicine.dosage}` : ''} - {medicine.precio ? `${medicine.precio.toFixed(2)} €` : 'Sin precio'} + {medicine.precio != null ? `${medicine.precio.toFixed(2)} €` : 'Sin precio'} - {medicine.laboratorio} + {medicine.laboratory} diff --git a/apps/frontend-mobile/constants/config.ts b/apps/frontend-mobile/constants/config.ts index 47a4f06..4767c0b 100644 --- a/apps/frontend-mobile/constants/config.ts +++ b/apps/frontend-mobile/constants/config.ts @@ -11,8 +11,10 @@ const ENV = { const environment = Constants.expoConfig?.extra?.environment || (__DEV__ ? 'development' : 'production'); +const envBaseUrl = process.env.EXPO_PUBLIC_API_URL; + export const config = { - API_BASE_URL: ENV[environment as keyof typeof ENV]?.API_BASE_URL || ENV.development.API_BASE_URL, + API_BASE_URL: envBaseUrl || ENV[environment as keyof typeof ENV]?.API_BASE_URL || ENV.development.API_BASE_URL, SEARCH_DEBOUNCE_MS: 300, CACHE_STALE_TIME: 5 * 60 * 1000, // 5 minutes CACHE_CACHE_TIME: 30 * 60 * 1000, // 30 minutes diff --git a/apps/frontend-mobile/types/index.ts b/apps/frontend-mobile/types/index.ts index 9a119e7..6338cb7 100644 --- a/apps/frontend-mobile/types/index.ts +++ b/apps/frontend-mobile/types/index.ts @@ -1,12 +1,20 @@ export interface Medicine { + id: string; nregistro: string; - nombre: string; - principioActivo: string; - laboratorio: string; - formaFarmaceutica: string; - precio: number | null; - stock: number; - disponibilidad: 'disponible' | 'sin_stock' | 'bajo_stock'; + name: string; + active_ingredient: string; + dosage: string; + form: string; + formSimplified: string; + laboratory: string; + prescription: string; + commercialized: boolean; + generic: boolean; + photos: string[]; + docs: { tipo: number; url: string; urlHtml?: string; secc: boolean; fecha: number }[]; + // Optional pharmacy-specific fields (only present in pharmacy_medicines joins) + precio?: number | null; + stock?: number; } export interface Pharmacy { -- 2.52.0