Vai al contenuto
Tutti i lavori

Sconti Nova

Offerte Amazon verificate ogni ora. Costruito con un socio.

Apri la demo

Codice disponibile su richiesta

Il problema

I siti di offerte invecchiano in fretta: i prezzi cambiano, i coupon scadono e lo stesso prodotto compare tre volte da tre fonti. Sconti Nova importa offerte da un canale Telegram e da Amazon stessa, verifica ogni prezzo su Amazon prima di mostrarlo e tiene una sola scheda per ogni offerta reale.

Stato
Online, con un ciclo del catalogo ogni ora
Stack
Next.js 16, React 19, TypeScript, Tailwind 4, Supabase, PostgreSQL, Vercel Cron, Tiptap, Vitest, Playwright
Facts
75 file di test, compresi test del database su PGlite
29 migrazioni
Controlli di accessibilità con axe nei test end-to-end

Le scelte che vale la pena spiegare

Due fonti non possono creare due volte la stessa offerta

Telegram e Amazon alimentano entrambi il catalogo. Prima di inserire, la ricerca prende un advisory lock di transazione sull’ASIN del prodotto, così due importazioni contemporanee non possono decidere entrambe che la scheda manca. Il lock sta nelle funzioni di salvataggio, quindi copre anche il ciclo orario.

Stesso prodotto non vuol dire stessa offerta

Due offerte si uniscono solo se variante, accesso Prime, quantità, coupon, codice, venditore e limiti d’acquisto coincidono tutti. Un nome simile non prova niente, e un venditore sconosciuto non viene mai considerato uguale a un altro.

Il ciclo orario resiste a timeout e doppioni

Ogni ora di lavoro è una riga con un proprietario, un lease e un fencing token. Ogni blocco gira in una richiesta serverless con un budget di tempo e scrive un checkpoint, e un worker superato il cui fence è cambiato non può più scrivere. Se l’ora finisce, il riepilogo dice parziale, mai completato.

Un pezzo del codice

Il lock si prende prima della ricerca, così controllo e inserimento non possono essere separati da un’altra importazione.

supabase/migrations/…_verified_offer_deduplication.sql
-- Separate commands after the lock give the lookup a fresh Read Committed snapshot.
create function nova_catalog.find_verified_product(p_asin text,p_conditions jsonb,p_preferred_id uuid default null)
returns uuid language plpgsql volatile security invoker set search_path='' as $$
declare pid uuid;
begin
 if p_asin is null or p_asin !~ '^[A-Z0-9]{10}$' then return null; end if;
 perform pg_catalog.pg_advisory_xact_lock(pg_catalog.hashtextextended('sconti-nova:verified-offer:'||p_asin,0));
 -- An unknown seller is not evidence that two commercial offers are equal.
 if jsonb_typeof(p_conditions) is distinct from 'object' or nullif(p_conditions->>'merchantId','') is null then return null; end if;
 select p.id into pid from public.products p
 where p.verified_asin=p_asin and (p.catalog_source_offer_id is not null or p.catalog_discovery_id is not null)
  and nova_catalog.product_verified_conditions(p)=p_conditions
 order by (p.id=p_preferred_id) desc nulls last,p.created_at asc,p.id asc
 limit 1 for update of p;
 return pid;
end $$;
Progetto successivoIter