feat/parapharmacy-baby-products #31
@@ -231,6 +231,86 @@ export async function getMedicineDetails(nregistro) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Busca medicamentos OTC (Sin Receta) en la API de CIMA con caché de Redis
|
||||||
|
* @param {string} query - Término de búsqueda
|
||||||
|
* @returns {Promise<Array>} - Lista de medicamentos OTC encontrados
|
||||||
|
*/
|
||||||
|
export async function searchOTC(query) {
|
||||||
|
if (!query || query.trim().length < 2) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const searchTerm = query.trim().toLowerCase();
|
||||||
|
const cacheKey = `cima:otc:${searchTerm}`;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Intentar obtener del caché
|
||||||
|
const cachedData = await redisClient.get(cacheKey);
|
||||||
|
|
||||||
|
if (cachedData) {
|
||||||
|
console.log(`📦 Cache hit for OTC search: ${searchTerm}`);
|
||||||
|
return JSON.parse(cachedData);
|
||||||
|
}
|
||||||
|
|
||||||
|
const parsed = parseSearchQuery(searchTerm);
|
||||||
|
const apiSearchTerm = parsed.nameQuery || searchTerm;
|
||||||
|
|
||||||
|
console.log(`🌐 Fetching OTC from CIMA API: ${apiSearchTerm}`);
|
||||||
|
const response = await axios.get(`${CIMA_API_BASE_URL}/medicamentos`, {
|
||||||
|
params: {
|
||||||
|
nombre: apiSearchTerm,
|
||||||
|
cpresc: 'Sin Receta'
|
||||||
|
},
|
||||||
|
timeout: 5000
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.data && response.data.resultados) {
|
||||||
|
// Transformar los datos de CIMA al modelo unificado Product
|
||||||
|
const medicines = response.data.resultados.map(med => ({
|
||||||
|
id: med.nregistro,
|
||||||
|
source: 'cima',
|
||||||
|
name: med.nombre,
|
||||||
|
brand: med.labtitular || '',
|
||||||
|
category: 'otc',
|
||||||
|
image_url: med.fotos?.[0]?.url || null,
|
||||||
|
active_ingredient: med.vtm?.nombre || null,
|
||||||
|
dosage: med.dosis || null,
|
||||||
|
form: med.formaFarmaceutica?.nombre || null,
|
||||||
|
prescription: med.cpresc,
|
||||||
|
commercialized: med.comerc,
|
||||||
|
photos: med.fotos || [],
|
||||||
|
docs: med.docs || []
|
||||||
|
}));
|
||||||
|
|
||||||
|
const filtered = filterMedicinesByFullQuery(medicines, searchTerm);
|
||||||
|
|
||||||
|
// Guardar en caché (1h TTL)
|
||||||
|
await redisClient.setEx(cacheKey, CACHE_TTL, JSON.stringify(filtered));
|
||||||
|
|
||||||
|
console.log(`✅ Cached ${filtered.length} OTC medicines for: ${searchTerm}`);
|
||||||
|
return filtered;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [];
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error searching OTC medicines from CIMA:', error.message);
|
||||||
|
|
||||||
|
// Si falla, intentar devolver datos cacheados aunque hayan expirado
|
||||||
|
try {
|
||||||
|
const staleData = await redisClient.get(cacheKey);
|
||||||
|
if (staleData) {
|
||||||
|
console.log('⚠️ Returning stale OTC cache data due to API error');
|
||||||
|
return JSON.parse(staleData);
|
||||||
|
}
|
||||||
|
} catch (cacheError) {
|
||||||
|
console.error('OTC cache fallback also failed:', cacheError);
|
||||||
|
}
|
||||||
|
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Limpia el caché de búsquedas (útil para testing o mantenimiento)
|
* Limpia el caché de búsquedas (útil para testing o mantenimiento)
|
||||||
* @param {string} pattern - Patrón de claves a eliminar (ej: 'medicines:search:*')
|
* @param {string} pattern - Patrón de claves a eliminar (ej: 'medicines:search:*')
|
||||||
|
|||||||
Reference in New Issue
Block a user