Files
nutriscan/app/api/cache/sync/route.ts
T
evandro 30d7ef701f fix: cache JSON concorrente, validação do sync e timeout nas chamadas ao Open Food Facts
- JsonCacheManager: a leitura inicial concorrente carregava o arquivo duas
  vezes e a segunda descartava as alterações da primeira; gravações
  simultâneas escreviam no mesmo arquivo. Agora a leitura é compartilhada
  e a gravação é enfileirada, via arquivo temporário + rename.
- POST /api/cache/sync: aceitava qualquer objeto e usava code como chave
  do cache (inclusive ausente ou não numérico); agora só grava produtos
  com code numérico e conta os demais em failed. JSON malformado responde
  400 em vez de 500.
- GET /api/products/[barcode]: resposta da API sem product virava 200
  com corpo vazio; agora responde 404.
- Chamadas ao Open Food Facts (busca e produto) passam a ter timeout de
  15 s e o User-Agent vem de um único lugar (lib/offSearch).
2026-10-10 04:18:59 -03:00

47 lines
1.5 KiB
TypeScript

import { NextRequest, NextResponse } from "next/server";
import { jsonCacheManager } from "@/lib/jsonCacheManager";
import type { Product } from "@/lib/openFoodFactsApi";
const INVALID_PRODUCTS = { error: "Produtos inválidos" };
/** Aceita só objetos com `code` numérico (texto de dígitos): a chave do cache não pode ser arbitrária. */
function isSyncableProduct(value: unknown): value is Product {
if (typeof value !== "object" || value === null) return false;
const code = (value as { code?: unknown }).code;
return typeof code === "string" && /^\d{1,32}$/.test(code);
}
export async function POST(request: NextRequest) {
let body: { products?: unknown };
try {
body = await request.json();
} catch {
return NextResponse.json(INVALID_PRODUCTS, { status: 400 });
}
try {
const products = body?.products;
if (!Array.isArray(products)) {
return NextResponse.json(INVALID_PRODUCTS, { status: 400 });
}
// Salvar produtos válidos no cache; os demais contam como falha
const valid = products.filter(isSyncableProduct);
const result = await jsonCacheManager.saveProducts(valid);
console.log(`[Cache Sync] ${result.saved} novos produtos salvos`);
return NextResponse.json({
success: true,
saved: result.saved,
failed: result.failed + (products.length - valid.length),
});
} catch (error) {
console.error("Erro ao sincronizar cache:", error);
return NextResponse.json(
{ error: "Erro ao sincronizar cache" },
{ status: 500 }
);
}
}