import { action } from '../_generated/server'; import { v } from 'convex/values'; interface OpenFoodFactsProduct { product?: { product_name?: string; product_name_pt?: string; generic_name?: string; generic_name_pt?: string; categories?: string; categories_tags?: string[]; image_url?: string; image_front_url?: string; image_front_small_url?: string; brands?: string; quantity?: string; packaging?: string; }; status?: number; status_verbose?: string; } interface ProductInfo { nome?: string; descricao?: string; categoria?: string; imagemUrl?: string; marca?: string; quantidade?: string; embalagem?: string; } /** * Busca informações de produto via API externa (Open Food Facts) * Esta é uma funcionalidade opcional que pode ser usada para preencher * automaticamente informações de produtos quando disponível. */ export const buscarInfoProdutoPorCodigoBarras = action({ args: { codigoBarras: v.string() }, handler: async (ctx, args): Promise => { const { codigoBarras } = args; // Validar formato básico de código de barras (EAN-13, UPC, etc.) if (!codigoBarras || codigoBarras.length < 8 || codigoBarras.length > 14) { return null; } try { // Tentar buscar na API Open Food Facts (gratuita, sem autenticação) const response = await fetch( `https://world.openfoodfacts.org/api/v0/product/${codigoBarras}.json`, { method: 'GET', headers: { 'User-Agent': 'SGSE-App/1.0 (Almoxarifado)' }, signal: AbortSignal.timeout(5000) // Timeout de 5 segundos } ); if (!response.ok) { return null; } const data = (await response.json()) as OpenFoodFactsProduct; if (data.status !== 1 || !data.product) { return null; } const product = data.product; // Extrair categoria (primeira categoria disponível) let categoria: string | undefined; if (product.categories_tags && product.categories_tags.length > 0) { // Pegar a primeira categoria e limpar tags const primeiraCategoria = product.categories_tags[0]; categoria = primeiraCategoria .replace(/^pt:/, '') .replace(/^en:/, '') .replace(/-/g, ' ') .split(' ') .map((word) => word.charAt(0).toUpperCase() + word.slice(1)) .join(' '); } else if (product.categories) { categoria = product.categories.split(',')[0].trim(); } const info: ProductInfo = { nome: product.product_name_pt || product.product_name || undefined, descricao: product.generic_name_pt || product.generic_name || undefined, categoria, imagemUrl: product.image_front_url || product.image_url || product.image_front_small_url || undefined, marca: product.brands || undefined, quantidade: product.quantity || undefined, embalagem: product.packaging || undefined }; // Retornar apenas se tiver pelo menos nome ou descrição if (info.nome || info.descricao) { return info; } return null; } catch (error) { // Log do erro mas não falhar a operação console.error('Erro ao buscar informações do produto:', error); return null; } } });