← Projekty
2026Aktivní

BrickMatch

Full-stack aplikace, která páruje vlastní LEGO dílky s katalogem stavebnic Rebrickable. Ukáže vám, ke kterým setům máte nejblíže a které dílky vám do jejich dokončení scházejí. Jádrem aplikace je vyhledávací matching engine postavený na efektivní databázové indexaci a jediném agregovaném SQL dotazu, namísto pomalého procházení jednotlivých položek nebo nespolehlivého rozpoznávání obrázků pomocí AI.

  • Next.js
  • NestJS
  • TypeScript
  • Drizzle ORM
  • Neon Postgres
  • Zod
  • pnpm workspaces
  • TanStack Query
  • nuqs
  • Tailwind CSS
  • shadcn/ui
  • Vitest
  • Jest

Náhled projektu

BrickMatch — project preview screenshot
BrickMatch — project screenshot 2
BrickMatch — project screenshot 3

Kontext

LEGO je moje osobní záležitost. Často se mi stávalo, že jsem doma našel staré kostky nebo koupil náhodnou směs dílků, ale neměl jsem přehled, co z nich vlastně dokážu postavit. Dostupné nástroje buď spoléhají na rozpoznávání obrazu pomocí AI, které je u barev a specifických dílků velmi nespolehlivé, nebo nedokážou odpovědět na tu nejjednodušší otázku: které stavebnici jsem s dostupnými dílky nejblíže. Chtěl jsem vytvořit robustní vyhledávací jádro nad rozsáhlým reálným datasetem, spíše než jen postavit další jednoduchou CRUD aplikaci s nálepkou AI.

Technický přístup

  • API v NestJS a frontend v Next.js provozované jako samostatně nasaditelné služby v pnpm monorepu, sdílející společný balíček se schématy Zod pro typovou bezpečnost a validaci dat.
  • PostgreSQL B-tree index nad dvojicí (part_num, color_id) efektivně omezí prohledávaný katalog pouze na reálné kandidáty ještě před samotným výpočtem shody.
  • Výpočet procentuální shody pro všechny potenciální stavebnice v rámci jediného seskupeného SQL dotazu s klauzulí HAVING namísto postupného dotazování pro každého kandidáta zvlášť.
  • Katalogová data se do databáze importují předem z datových exportů Rebrickable. Backend tak při zpracování požadavků nemusí komunikovat s API třetích stran. Obrázky dílků a setů se načítají na straně klienta přímo z CDN sítě Rebrickable.
  • JWT je bezpečně předáván prostřednictvím httpOnly cookie a na straně API validován pomocí Nest Passport. Frontend k tokenu nemá přímý přístup a stav přihlášení odvozuje z požadavku na endpoint /me prostřednictvím TanStack Query.
  • Správa serverového stavu výhradně pomocí TanStack Query. Stav filtrů v URL adrese (témata, minimální shoda) je synchronizován pomocí knihovny nuqs.

Výzvy

  • Služba Rebrickable ukládá dílky minifigurek v oddělené struktuře (grafu) namísto přímého inventáře dané stavebnice. Tento problém jsem vyřešil už ve fázi importu denormalizací a rozbalením všech částí minifigurek přímo do mateřského setu.
  • Platformy BrickLink a Rebrickable používají odlišné interní identifikátory pro dílky a barvy, přičemž neexistuje žádné ucelené mapování. Místo náročné údržby vlastní převodní tabulky generuji exporty ve formátu Rebrickable CSV a samotný převod na formát BrickLink XML deleguji na osvědčený externí nástroj Rebrickable.
  • Nalezení optimální prahové hodnoty pro minimální procento shody, která by fungovala konzistentně pro stavebnice různých velikostí – od drobných setů s desítkami dílků až po obří modely s tisíci kostkami.
  • Návrh efektivního stránkování pro neustále se rozrůstající sbírku uživatele při zachování přímého načítání malých statických číselníků (barvy, témata) bez zbytečné režie.

Co jsem se naučil

  • U rozsáhlých katalogů patří nejtěžší práce do databázového indexu a jediné SQL agregace. Cyklické procházení desítek tisíc záznamů v aplikačním kódu je jasným architektonickým prohřeškem (code smell).
  • Komplexní vazby v katalogu, jako jsou dílky minifigurek, je nejlepší denormalizovat už při importu. Runtime vyhledávání pak zůstane jednoduchou a plochou operací nad dvojicí (part_num, color_id).
  • Sdílení Zod schémata eliminuje riziko nesouladu (driftu) datových modelů mezi frontendem a backendem. Pro integraci plně postačila jednoduchá vlastní validační runda v NestJS – použití knihoven jako nestjs-zod by přineslo jen zbytečnou komplexitu.
  • Nemá smysl vyvíjet a udržovat vlastní převodníky ID mezi různými platformami, pokud již existuje spolehlivé řešení přímo u zdroje. Generování CSV ve formátu Rebrickable se ukázalo jako podstatně jednodušší cesta s minimální režií.
  • Stránkování je důležité produktové rozhodnutí. Zatímco neustále rostoucí uživatelské sbírky jej vyžadují, drobné statické číselníky (barvy, témata) je mnohem efektivnější stáhnout jednorázově a cachovat na klientovi.

Hlavní funkce

  • Vyhledávací matching engine využívající databázové indexy nad katalogem s více než 20 000 stavebnicemi
  • Sdílená Zod schémata pro stoprocentní typovou bezpečnost a validaci mezi frontendem a backendem v rámci pnpm workspace
  • Bezpečná JWT autentizace předávaná přes httpOnly cookie s dodatečným potvrzením hesla u citlivých akcí
  • Export chybějících dílků do CSV (formát Rebrickable) a BrickLink XML prostřednictvím oficiálního převodníku
  • Předpřipravení (denormalizace) dílků z minifigurek přímo do inventáře stavebnic při importu, což zrychluje vyhledávání
  • Atomická operace „postavení stavebnice“, která odečte použité dílky z vaší sbírky pouze při stoprocentním dokončení setu

Další projekt

TextForge

Nástroj pro okamžitý převod a formátování textu s podporou AI, odvozováním schémat a prémiovým přístupem přes Stripe.

Zobrazit projekt