Porównanie cen sprzętu sportowego w polskich sklepach, pełne specyfikacje, historia cen i alerty o obniżkach. Na start: narty zjazdowe.
Translation pending
CommerceTypeScript · JavaScriptGitHub @kacper08070605OnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗Serwis z cenami i specyfikacjami sprzętu sportowego. Pokazuje najniższą cenę w sklepach partnerskich, kieruje do sklepu linkiem afiliacyjnym i wysyła alerty o obniżkach. Na start jedna kategoria: narty zjazdowe (każdy rocznik osobno), a w strefie narciarskiej lista polskich ośrodków. Założenia biznesowe: PROJEKT.md.
Oferty sklepów są prawdziwe: każda prowadzi na kartę produktu w polskim sklepie internetowym, a cena
pochodzi z tej strony (data sprawdzenia przy ofercie). Serwis nie ma jeszcze umów afiliacyjnych, więc
linki są zwykłymi linkami do sklepów. Zdjęcia nart pochodzą z materiałów producentów.
Historia cen sprzed 25.10.2026 jest symulowana na potrzeby projektu (punkty z "sim": true
w data/offers.json); od 25.10.2026 punkty pochodzą z npm run prices:update.
npm install
npm run dev # http://localhost:3000
Wymaga Node 22+ i bazy Postgres (Supabase). W pliku .env.local ustaw
DATABASE_URL (Supabase → Connect → Direct → Transaction pooler, port 6543), potem raz:
npm run db:setup # zakłada tabele z data/schema.sql
Wdrożenie: Vercel, import repozytorium z GitHuba, zmienna środowiskowa DATABASE_URL.
npm run prices:update otwiera karty produktów ze wszystkich ofert (1,5 s przerwy, bot przedstawia się
jako ApexSport), czyta cenę i dostępność z danych schema.org na stronie, zapisuje punkt historii
najniższej ceny i sprawdza alerty. npm run prices:update -- <slug-produktu> sprawdza jeden model.
Strony, z których nie udało się odczytać ceny, skrypt wypisuje na końcu; ich oferty zostają z poprzednią
ceną i datą. Skrypt uruchamia się ręcznie. Docelowo ceny przychodziłyby z feedów sieci afiliacyjnych.
Test alertu bez czekania na prawdziwą obniżkę: załóż alert na stronie produktu, podnieś jego próg w bazie
(UPDATE alerts SET target_price = 99999 w SQL Editorze Supabase) i uruchom npm run prices:update -- <slug>.
Bez RESEND_API_KEY e-mail trafia tylko do bazy, a status widać na /alerty.
npm run resorts:import: lista ośrodków i statystyki (OpenSkiData).npm run resorts:details: trasy i wyciągi z OpenSkiData oraz ich geometria z OpenStreetMap (Overpass) do public/maps/resorts/. Wymaga data/.cache/runs.csv i lifts.csv z tiles.openskimap.org. Skrypt można wznawiać, bo pomija pobrane mapy.npm run resorts:climate: średnie opady śniegu z 10 sezonów (Open-Meteo, ERA5).src/lib/weather.ts). Darmowe API Open-Meteo jest tylko do użytku niekomercyjnego.data/resort-info.json. Pełne cenniki skipassów (kategorie wiekowe, okresy, karnety godzinowe, wielodniowe, sezonowe): data/resort-pricelists.json./dobor-nart: kreator w 5 krokach. Cechy każdej narty (chwyt, stabilność, zwrotność, łatwość, miękki śnieg) są wyliczane ze specyfikacji w src/lib/ski-traits.ts, dopasowanie i długość dla każdego modelu w src/lib/selector.ts. Wynik jest zapisany w adresie strony, więc można go udostępnić.
Strona /radar, konto /radar/rejestracja, panel /panel: wyszukiwania (modele z katalogu, słowa kluczowe, cena, długość, stan, serwisy), znalezione ogłoszenia (zapisz/odrzuć), historia powiadomień, plan i konto. Plan Free: 2 wyszukiwania i dzienne podsumowanie. Plan Pro (39 zł/mies., 349 zł/rok): 25 wyszukiwań i powiadomienie od razu. Płatność jest atrapą, przycisk włącza Pro bez obciążenia.
src/lib/radar/vinted.ts, wyłączenie RADAR_VINTED=false). Najwyżej 8 fraz na skan, 1,5 s przerwy, bot przedstawia się jako ApexRadar. OLX blokuje automatyczne pobieranie (403) i wymaga zgody serwisu. Allegro ma oficjalne REST API: adapter src/lib/radar/allegro.ts działa po ustawieniu ALLEGRO_CLIENT_ID, ALLEGRO_CLIENT_SECRET i weryfikacji aplikacji przez Allegro. Generator przykładowych ogłoszeń (src/lib/radar/demo-source.ts) włącza RADAR_DEMO=true.data/olx-snapshot.json (src/lib/radar/olx-snapshot.ts, wyłączenie RADAR_OLX_SNAPSHOT=false). Bot nie łączy się z OLX.src/lib/radar/discord.ts).RESEND_API_KEY i ALERT_FROM. Bez klucza wiadomości trafiają tylko do zakładki Powiadomienia.npm run radar:scan (podsumowania: npm run radar:digest) albo POST /api/radar/scan z nagłówkiem Authorization: Bearer $CRON_SECRET (?digest=1 dla podsumowań).NEXT_PUBLIC_SITE_URL.src/components/ui/, dodawanie: npx shadcn@latest add <komponent>), ikony Lucide, animacje Motion, karuzele Embla, wyszukiwarka cmdk (Ctrl+K). Motyw w src/app/globals.css, font Onest.postgres: alerty, kliknięcia w oferty, powiadomienia, konta i dane Radaru| Plik | Zawartość |
|---|---|
data/skis.json | Narty: model + rocznik, długości, taliowanie, promień, zdjęcie, źródło |
data/shops.json | Sklepy partnerskie: sieć afiliacyjna, prowizja, długość cookie |
data/offers.json | Oferty sklepów (adres karty produktu, cena, data sprawdzenia) i historia najniższej ceny |
data/resorts.curated.json → data/resorts.json | Ośrodki; statystyki z OpenSkiData (npm run resorts:import) |
data/schema.sql | Schemat bazy Postgres |
src/content/articles.ts | Artykuły redakcyjne |
Zasady: specyfikacje tylko od producentów (lub z archiwum ich stron i testów z danego sezonu),
nigdy hurtowo z katalogów konkurencji. Brakujących liczb nie zgadujemy. needs_review: true
oznacza dane niepotwierdzone u producenta.
| URL | Co robi |
|---|---|
/produkt/[slug] | Karta produktu: najniższa cena, oferty, historia cen, alert, specyfikacja, inne roczniki |
/szukaj?q= | Wyszukiwarka grupująca roczniki jednej linii („atomic s9”, „hero 24/25”) |
/narciarstwo/narty-zjazdowe | Katalog z filtrami i porównywaniem |
/go/[offerId] | Przekierowanie do sklepu + zapis kliknięcia |
/api/alerts | Zakładanie, odczyt i anulowanie alertów |
/statystyki | Panel demo: kliknięcia według sklepu i szacowana prowizja |