Tech stekas
Turborepo monorepo, NestJS API, Next.js vitrina, Vite admin skydelis, chrome-devtools MCP skreperis.
TL;DR
Turborepo monorepo su trimis programomis: API (NestJS + TypeORM + PostgreSQL 16 + Redis + Socket.IO), vieša vitrina (Next.js 14 + next-intl + TanStack Query), admin skydelis (Vite 6 + React 18 + Leaflet). Katalogo skreipingas — chrome-devtools MCP vietoj Puppeteer. Hostingas — atskiras ARM64 VPS.
Stekas ir architektūra
Monorepo
Turborepo surenka tris programas ir bendrus paketus:
auto-parts/
├── apps/
│ ├── api/ NestJS — REST + WebSocket
│ ├── web/ Next.js — vieša vitrina
│ └── admin/ Vite + React SPA — vidinis admin skydelis
├── packages/
│ ├── shared/ bendri DTO tipai
│ └── ui/ shared React komponentai (skirti admin)
├── scraper/ chrome-devtools MCP skreperis
└── deploy/ docker-compose, nginx konfigūracijos
Turborepo suteikia surinkimo cache (CI surenka tik pakeistą programą), turbo dev paleidžia visas tris lygiagrečiai lokalų vystymą.
API (NestJS)
NestJS 10 su TypeORM:
- Autentifikacija:
@nestjs/jwt+@nestjs/passport+ bcrypt. Cookie pagrindu admin skydeliui, Bearer-tokenai būsimoms integracijoms. - Saugykla: PostgreSQL 16 per TypeORM. Pagrindiniai entity —
Product,Category,Fitment,Order,OrderItem,Customer,DeliveryZone,Inventory,Supplier. - Cache: Redis per
@nestjs/cache-manager+@keyv/redis. Kešuojamas filtruotas katalogas, fitment lentelės, geo susiejimai. - Real-time:
@nestjs/platform-socket.iosu@socket.io/redis-adapter— horizontalus mastelio keitimas, likučių sinchronizacija tarp admin skydelio ir vitrinos be perkrovimo. - Dokumentacija:
@nestjs/swaggergeneruoja OpenAPI specifikaciją /api/docs adresu. - Apsauga:
@nestjs/throttlerrate-limiting užtikrinimui (ypač paieškos endpointuose), globalūs guards JWT ir rolių patikrai.
Vitrina (Next.js)
Next.js 14 su App Router. Pagrindiniai moduliai:
- next-intl — daugiakalbiškumas (LT / RU / EN). Kiekviena kalba — atskiras URL prefiksas (
/lt,/ru,/en), statiškai renderinama SEO tikslais. - TanStack Query (React Query) — serverio cache katalogui, krepšeliui, užsakymų būsenoms. Refetch lango fokusavimo metu, atnaujinimas per WebSocket invalidaciją.
- Framer Motion — perėjimo tarp būsenų animacijos (kortelės įkrovimas, pridėjimas į krepšelį).
- Zustand — kliento pusės būsena krepšeliui ir katalogo filtrams.
- Tailwind CSS v4 — stilizavimas, be atskiros dizaino sistemos; komponentai rašomi vietoje.
Katalogas renderinamas mišriu režimu: kategorijų sąrašai — statiškai (ISR), prekių kortelės — serveryje su invalidacija pagal taimerį arba įvykį iš admin skydelio.
Admin skydelis (Vite SPA)
Vite 6 + React 18. Sunki SPA — daug ekranų, dažni perpiešimai, todėl Vite režimas suteikia greitą hot-reload be vėlinimų, skirtingai nei Next.js dev surinkimas.
- Leaflet — Lietuvos žemėlapiai pristatymo zonoms. Naudojama be išorinių API (OpenStreetMap kaladėlės).
- jsPDF + jspdf-autotable — sąskaitų ir ataskaitų eksportas tiesiai naršyklėje, be serverinio rendering.
- react-quill-new — rich-text prekių aprašymams (HTML su paveikslėlių palaikymu).
- rrweb-player — integruotas grotuvas session replay iš klientų skundų peržiūrai.
- Recharts — analitikos grafikai (pardavimai, konversija).
- react-router-dom 7 — kliento pusės maršrutizavimas, file-based nenaudojama.
- Zustand — bendras store, be Redux.
Autentifikacija — bendra su API per JWT + cookie admin-* subdomene (arba basic-auth visiškai uždariems endpointams).
Skreperis
Atskiras scraper/ aplankas su duomenų importo skriptais. Požiūris — chrome-devtools MCP, o ne Puppeteer ar Playwright:
scraper/
├── README.md
├── scripts/
│ ├── import-mototex.ts
│ ├── import-anjese.ts
│ └── ...
└── data/ tarpinių rezultatų cache
MCP (Model Context Protocol) paleidžia realią naršyklę ir valdo ją iš Node proceso. Šaltinio svetainės požiūriu — tai įprastas vartotojas Chrome naršyklėje, todėl veikia svetainėse su agresyvia anti-bot apsauga.
Importo ciklas: atidaryti katalogo sąrašą → pereiti per puslapius → kiekvienoje kortelėje ištraukti artikulą, kainas, nuotraukas, fitment lentelę → normalizuoti → siųsti į API → API sukuria arba atnaujina prekę. Progresas keliauja į admin skydelį per WebSocket, operatorius mato importo eigą realiu laiku.
Hostingas
- ARM64 VPS. Atskiras serveris, vartotojas
parts. ARM pasirinktas dėl pigumo ir mažesnio energijos suvartojimo — katalogui be heavy-compute tai nėra kritinė problema. - nginx — reverse-proxy, TLS terminatorius, statika. Virtualūs hostai www vitrinai ir admin skydeliui skirtinguose subdomenuose.
- Docker compose — visi servisai (api, web, admin, postgres, redis) viename faile. Deploy —
docker compose pull && docker compose up -d. - GitHub Actions — CI: lint, type-check, build → push image į GHCR. Smart path filtras perrenka tik pakeistas programas.
Kriptomokėjimai
API yra prijungta bitcoinjs-lib ir bip32 — tai infrastruktūra kriptomokėjimų priėmimui (BTC, ETH per child-raktus). Adresų derivacija BIP32: vienas master-key platformai, child-adresai kiekvienam užsakymui — tai leidžia sekti įeinančias transakcijas neatskleidžiant master-key.
Tai kol kas pasirenkamas variantas vitrinoje, bet architektūra yra; rusakalbiam segmentui Lietuvoje tai gali tapti atsiskaitymų kanalu, kai euro įsigyjimas yra nepatogus.
Ką perrašyčiau
Naujoje iteracijoje:
- Kainų atestavimas. Šiuo metu kainoraščiai importuojami kaip yra. Galima pridėti normalizavimo sluoksnį su istorija: „ši detalė pas tiekėją X kainavo Y, dabar Z, skirtumas 30%, gal pakišo padirbinį?“
- CDN nuotraukoms. Šiuo metu paveikslėliai eina per nginx iš disko. Augant katalogui — vertėtų perjungti į S3/R2 + CDN.
- Pilnatekstė paieška. TypeORM
LIKEištveria 10 000 SKU, bet esant 50 000+ reikia Postgres FTS arba Meilisearch.
Šiuo metu platforma veikia produkcijoje, užsakymai eina, katalogo importas automatizuotas. Tolimesnės iteracijos priklauso nuo asortimento ir srauto augimo.