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).
This commit is contained in:
evandro committed 2026-10-10 04:18:59 -03:00
1 parent 5ee5dcd893
commit 30d7ef701f
7 files changed
+273 -30

No files matched your search

+4 -4
View File
@@ -1,7 +1,6 @@
import { NextRequest, NextResponse } from "next/server";
import { jsonCacheManager } from "@/lib/jsonCacheManager";
const USER_AGENT = "NutriScan/1.0 (https://nutriscan.com.br)";
import { OFF_TIMEOUT_MS, OFF_USER_AGENT } from "@/lib/offSearch";
export async function GET(
request: NextRequest,
@@ -55,9 +54,10 @@ export async function GET(
`https://world.openfoodfacts.org/api/v2/product/${cleanBarcode}.json`,
{
headers: {
"User-Agent": USER_AGENT,
"User-Agent": OFF_USER_AGENT,
Accept: "application/json",
},
signal: AbortSignal.timeout(OFF_TIMEOUT_MS),
}
);
@@ -70,7 +70,7 @@ export async function GET(
const data = await response.json();
if (data.status === 0) {
if (data.status === 0 || !data.product) {
return NextResponse.json(
{ error: "Produto não encontrado" },
{ status: 404 }