გორა.
AI-translation · draft (awaiting native review)
Jusmila — მოტო-ნაწილების კატალოგი ლიტვაში

ტექნიკური სტეკი

Turborepo მონორეპო, NestJS API, Next.js ვიტრინა, Vite-ადმინი, chrome-devtools MCP სკრეიპერი.

~4 წუთი წასაკითხი · 726 სიტყვა

TL;DR

Turborepo მონორეპო სამი აპლიკაციით: API (NestJS + TypeORM + PostgreSQL 16 + Redis + Socket.IO), საჯარო ვიტრინა (Next.js 14 + next-intl + TanStack Query), ადმინი (Vite 6 + React 18 + Leaflet). კატალოგის სკრეიპინგი — chrome-devtools MCP Puppeteer-ის ნაცვლად. ჰოსტინგი — ცალკე ARM64 VPS.

სტეკი და არქიტექტურა

მონორეპო

Turborepo აგებს სამ აპლიკაციასა და საერთო პაკეტებს:

auto-parts/
├── apps/
│   ├── api/        NestJS — REST + WebSocket
│   ├── web/        Next.js — საჯარო ვიტრინა
│   └── admin/      Vite + React SPA — შიდა ადმინი
├── packages/
│   ├── shared/     საერთო DTO ტიპები
│   └── ui/         shared React-კომპონენტები (admin-ისთვის)
├── scraper/        chrome-devtools MCP სკრეიპერი
└── deploy/         docker-compose, nginx-კონფიგი

Turborepo იძლევა აგების კეშს (CI ხელახლა აგებს მხოლოდ შეცვლილ აპლიკაციებს), turbo dev უშვებს სამივეს პარალელურად ლოკალური დეველოპმენტისთვის.

API (NestJS)

NestJS 10 TypeORM-ით:

  • ავთენტიფიკაცია: @nestjs/jwt + @nestjs/passport + bcrypt. Cookie-based ადმინისთვის, Bearer-ტოკენები მომავალი ინტეგრაციებისთვის.
  • საცავი: PostgreSQL 16 TypeORM-ით. ძირითადი entity — Product, Category, Fitment, Order, OrderItem, Customer, DeliveryZone, Inventory, Supplier.
  • კეში: Redis @nestjs/cache-manager + @keyv/redis-ით. კეშირდება: გაფილტრული კატალოგი, fitment-ცხრილები, გეო-მიბმები.
  • Real-time: @nestjs/platform-socket.io @socket.io/redis-adapter-ით — ჰორიზონტალური მასშტაბირება, ნაშთების სინქრო ადმინსა და ვიტრინას შორის გადატვირთვის გარეშე.
  • დოკუმენტაცია: @nestjs/swagger აგენერირებს OpenAPI-სპეცს /api/docs-ზე.
  • დაცვა: @nestjs/throttler rate-limiting-ისთვის (განსაკუთრებით ძიების endpoint-ებზე), გლობალური guards JWT-სა და როლების შესამოწმებლად.

ვიტრინა (Next.js)

Next.js 14 App Router-ით. საკვანძო მოდულები:

  • next-intl — მრავალენოვნება (LT / RU / EN). თითო ენა — ცალკე URL-პრეფიქსი (/lt, /ru, /en), სტატიკურად რენდერდება SEO-სთვის.
  • TanStack Query (React Query) — სერვერული კეში კატალოგისთვის, კალათისთვის, შეკვეთის სტატუსებისთვის. Refetch ფანჯრის ფოკუსზე, განახლება WebSocket-ინვალიდაციით.
  • Framer Motion — გადასვლის ანიმაციები მდგომარეობებს შორის (ბარათის ჩატვირთვა, კალათაში დამატება).
  • Zustand — კლიენტური მდგომარეობა კალათისა და კატალოგის ფილტრებისთვის.
  • Tailwind CSS v4 — სტილიზაცია, ცალკე დიზაინ-სისტემის გარეშე; კომპონენტები იწერება ადგილზე.

კატალოგი რენდერდება შერეულ რეჟიმში: კატეგორიების სიები — სტატიკურად (ISR), პროდუქტების ბარათები — სერვერზე ტაიმერითა და ადმინიდან event-ით ინვალიდირებით.

ადმინი (Vite SPA)

Vite 6 + React 18. მძიმე SPA — ბევრი ეკრანი, ხშირი rerender-ები, ამიტომ Vite-რეჟიმი იძლევა სწრაფ hot-reload-ს დაყოვნების გარეშე, Next.js dev-build-ისგან განსხვავებით.

  • Leaflet — ლიტვის რუკები მიწოდების ზონებისთვის. გამოიყენება გარე API-ების გარეშე (OpenStreetMap-ის tiles).
  • jsPDF + jspdf-autotable — ზედნადებებისა და რეპორტების ექსპორტი პირდაპირ ბრაუზერში, სერვერული rendering-ის გარეშე.
  • react-quill-new — rich-text პროდუქტების აღწერებისთვის (HTML სურათების მხარდაჭერით).
  • rrweb-player — ჩაშენებული player session replay-სთვის კლიენტთა საჩივრებიდან.
  • Recharts — ანალიტიკის გრაფიკები (გაყიდვები, კონვერსია).
  • react-router-dom 7 — კლიენტური routing, file-based არ გამოიყენება.
  • Zustand — საერთო store, Redux-ის გარეშე.

ავთენტიფიკაცია — API-სთან საერთო JWT + cookie-ით admin-* საბდომენზე (ან basic-auth სრულიად დახურული endpoint-ებისთვის).

სკრეიპერი

ცალკე scraper/ საქაღალდე იმპორტ-სკრიპტებით. მიდგომა — chrome-devtools MCP, არა Puppeteer ან Playwright:

scraper/
├── README.md
├── scripts/
│   ├── import-mototex.ts
│   ├── import-anjese.ts
│   └── ...
└── data/         შუალედური შედეგების კეში

MCP (Model Context Protocol) უშვებს რეალურ ბრაუზერს და მართავს მას Node-პროცესიდან. წყაროს საიტის თვალსაზრისით — ეს ჩვეულებრივი მომხმარებელია Chrome-ში, ამიტომ მუშაობს საიტებზე აგრესიული anti-bot დაცვით.

იმპორტის ციკლი: კატალოგის სიის გახსნა → გვერდების გადარჩევა → თითო ბარათზე SKU-ის, ფასების, ფოტოების, fitment-ცხრილის ამოღება → ნორმალიზაცია → API-ში გადაგზავნა → API ქმნის ან აახლებს პროდუქტს. პროგრესი ფრინდება ადმინში WebSocket-ით, ოპერატორი ხედავს იმპორტს რეალურ დროში.

ჰოსტინგი

  • ARM64 VPS. ცალკე სერვერი, user parts. ARM არჩეულია სიიაფისა და დაბალი ენერგო-მოხმარების გამო — heavy-compute-ის გარეშე კატალოგისთვის ეს არ არის კრიტიკული.
  • nginx — reverse-proxy, TLS-ტერმინატორი, სტატიკა. ვირტუალური ჰოსტები საჯარო ვიტრინისთვის და ადმინისთვის სხვადასხვა საბდომენებზე.
  • Docker compose — ყველა სერვისი (api, web, admin, postgres, redis) ერთ ფაილში. დეპლოი — docker compose pull && docker compose up -d.
  • GitHub Actions — CI: lint, type-check, build → push image GHCR-ში. Smart path-ფილტრი ხელახლა აგებს მხოლოდ შეცვლილ აპლიკაციებს.

კრიპტო-გადახდები

API-ში ჩართულია bitcoinjs-lib და bip32 — ეს ინფრასტრუქტურაა კრიპტო-გადახდების მიღებისთვის (BTC, ETH child-key-ებით). მისამართების დერივაცია BIP32: ერთი master-key პლატფორმაზე, child-მისამართები თითო შეკვეთაზე — ეს იძლევა შემოსული ტრანზაქციების თვალყურის დევნებას master-key-ის გამხელის გარეშე.

ეს ჯერ ოპციონალურია ვიტრინაზე, მაგრამ არქიტექტურა არსებობს; რუსულენოვანი სეგმენტისთვის ლიტვაში ეს შეიძლება გახდეს ანგარიშსწორების არხი, როცა ევრო-acquiring-ი არ არის მოსახერხებელი.

რას გადავწერდი

ახალი იტერაციაზე:

  • ფასის ატესტაცია. დღეს ფასები იმპორტდება, როგორც არის. შეიძლება დაემატოს ნორმალიზაციის ფენა ისტორიით: «ეს ნაწილი მომწოდებელ X-ში ღირდა Y, ახლა Z, სხვაობა 30%, ხომ არ შემოგვიგდეს ყალბი?»
  • CDN ფოტოებისთვის. ახლა სურათები მიდის nginx-ით დისკიდან. კატალოგის ზრდასთან ერთად — ღირს S3/R2 + CDN-ზე გადასვლა.
  • სრულტექსტური ძიება. TypeORM LIKE ეუფლება 10 000 SKU-ს, მაგრამ 50 000+-ზე საჭიროა Postgres FTS ან Meilisearch.

ამჟამად პლატფორმა მუშაობს პროდაქშენში, შეკვეთები მიდის, კატალოგის იმპორტი ავტომატიზებულია. შემდგომი იტერაციები დამოკიდებულია ასორტიმენტისა და ტრაფიკის ზრდაზე.