Tahlil obyekti:
safaarmonorepo (apps/web-user,apps/web-admin,apps/web-partner,apps/backend,packages/api-client,packages/types)
Sana: 2026-07-22
Audit darajasi: Lead Software Architect & Performance / Security Audit
Safaar platformasi zamonaviy Next.js 16 (App Router), NestJS 11, Prisma ORM, va TypeScript Monorepo arxitekturasi negizida qurilgan yirik va yuqori salohiyatli loyihadir. Frontend va backend qismlari modulli ko'rinishda ajratilgan, tur-tizimi (TypeScript strict mode) toza ushlab turilibdi.
Biroq, loyihani Production-Ready / High-Load Scaling darajasiga olib chiqish uchun quyidagi yo'nalishlarda Senior-level arxitekturaviy va unumdorlik muammolari aniqlandi:
- Frontend Rendering & Hydration: Ortiqcha
'use client'direktivalari, Client Bundle shishishi, ketma-ket (waterfall) so'rovlar vanext/imageo'rniga native<img>ishlatilishi. - Monorepo Standartlari va Fragmentatsiya: Sub-app'lar o'rtasidagi papka va kodiylik nomuvofiqligi,
@safaar/api-clientpaketining admin va partner app'larida ishlatilmay, axio/mock API bilan almashtirilgani. - Backend & Database Bottlenecks: PostgreSQL jadvallarida indekslar yetishmasligi, N+1 so'rovlar va mehmonxona xonalarini band qilishda Concurrent Overbooking (poyga holati) xavfi.
- Xavfsizlik & Data Exposure:
public/katalogidagi konfidentsial tijorat hujjatlari, dev-role sarlavhalari va HTTP Security header'larining yo'qligi.
Quyida har bir muammo chuqur texnik tahlil, kod joylashuvi va aniq yechimlar bilan taqdim etiladi.
- Joylashuv: apps/web-admin, apps/web-partner
- Muammo: Monorepoda yagona va markazlashtirilgan
@safaar/api-clientpaketi mavjud bo'lsada,web-adminvaweb-partnerilovalari undan foydalanmaydi. Buning o'rnigaaxios,js-cookieva har bir app ichida katta hajmli mock API fayllari (mock-api.ts- 13KB,mock-data.ts- 28KB) yaratilgan. - Oqibat: API endpoint'lar o'zgarganda yoki yangi xususiyat qo'shilganda har bir ilovada so'rovlar qayta yoziladi. Kod qaytarilishi (code duplication) va tur-xatolariga (type mismatch) olib keladi.
- Yechim:
@safaar/api-clientpaketida Admin va Partner xizmatlarini ham qamrab oluvchi sub-service'larni (admin.ts,partner.ts) kengaytirish va barcha 3 ta frontend ilovani yagona API SDK bilan integratsiya qilish.
- Joylashuv: apps/web-user/package.json:L24
- Muammo: Next.js App Router muhitida ishlayotgan
apps/web-userilovasiga"react-router-dom": "^6.30.4"kutubxonasi o'rnatilgan. - Oqibat: Next.js o'zining router va routing tizimiga ega.
react-router-domilova JS bundle hajmiga ortiqcha ~30KB+ og'irlik beradi va loyihada arxitekturaviy chalkashlik tug'diradi. - Yechim:
react-router-dompaketiniapps/web-user/package.jsondan to'liq o'chirib tashlash.
- Muammo:
apps/web-userloyihasida komponentlar va kutubxonalar ildiziycomponents/,lib/,types/papkalarida saqlanadi.apps/web-partneresa Next.js ichki yo'naltirishiga qarshi ravishdaapp/_components,app/_hooks,app/_lib,app/_storesko'rinishida tuzilgan. - Yechim: Monorepoda yagona loyiha tuzilishi konventsiyasini (Standard Feature-Based Folder Structure) joriy etish.
- Joylashuv:
CityCardsSection.tsx,DealsSection.tsx,FeaturedHotelsCarousel.tsx - Muammo: Ushbu komponentlar faqatgina oddiy gorizontal scroll yoki tugma bosish logikasi uchun to'liqligicha Client Component (
'use client') qilib qo me'yorlashtirilgan. - Oqibat: Ushbu bloklar serverda HTML streaming sifatida uzatilmaydi. Kattagina HTML tuzilmasi va matnlar client-side JavaScript bundle hajmiga qo'shiladi va sahifa yuklanganda Hydration vaqtini uzaytiradi.
- Yechim: Interaktiv scroll boshqaruv tugmalarini alohida kichik client wrapper komponentga (
ScrollControls.tsx) ajratish va kartochkalar ro'yxatini toza Server Component (RSC) sifatida qoldirish.
- Joylashuv: CityCardsSection.tsx:L95
- Muammo:
/* eslint-disable @next/next/no-img-element */izohi orqali va native HTML<img>elementi ishlatilgan. - Oqibat: Next.js-ning avtomatik WebP/AVIF o'tkazish, responsive
srcset, responsivesizes, va lazy-loading imkoniyatlari ishlamaydi. Mobil tarmoqlarda foydalanuvchilar 2MB-5MB hajmdagi asl rasmlarni yuklab olishga majbur bo'ladi. - Yechim: Native
<img>teglarininext/image(<Image />) komponentiga o'tkazish hamda tegishlisizes="(max-width: 768px) 100vw, 33vw"atributlarini biriktirish.
- Joylashuv: Hero.tsx
- Muammo: Sahifaning eng yuqori qismidagi (Above the fold) Hero va fondagi rasmlarga
priorityatributi berilmagan. - Oqibat: Brauzer preload-scanner rasmlarni kechikib aniqlaydi va yuklaydi, bu esa LCP (Largest Contentful Paint) ko'rsatkichini 600ms-1200ms sekinlashtiradi.
- Yechim: Birinchi ekrandagi asosiy rasmga
<Image priority ... />atributini biriktirish.
- Joylashuv: apps/web-user/next.config.ts:L8
- Muammo:
remotePatternskonfiguratsiyasidahostname: "**"(wildcard) berilgan va AVIF qo me'yorlashtirilmagan. - Oqibat: Har qanday tashqi internet domenidan rasm yuklash server orqali o'tishi sababli Server-Side Request Forgery (SSRF) va Image Proxy Open-Relay xavfini tug'diradi.
- Yechim: Wildcard
**o'rniga aniq ishonchli CDN domenlarini kiritish vaformats: ['image/avif', 'image/webp']sozlamasini qo'shish (AVIF formati WebP'ga qaraganda 30% kichikroq hajm beradi).
- Joylashuv:
HotelFilters.tsx,HotelSortSelect.tsx - Muammo: Mehmonxonalarni filtrlaganda yoki saralaganda har bir parametr o'zgarganda
router.push()to'g me'ridan-to'g me'ri chaqiriladi. - Oqibat: React sahifani qayta render qilayotgan vaqtda kiritish maydonlari va interfeys qotib qoladi (jank).
- Yechim:
useTransitionhookini qo'llash orqali URL yangilanishini non-blocking fonda bajarish va optimistic UI renderlashni ta'minlash.
- Joylashuv: apps/web-user/public/sw.js:L9
- Muammo:
CACHE_NAME = "safaar-v1"qattiq kodlangan (hardcoded). - Oqibat: Production muhitiga yangi reliz/build chiqarilganda brauzer Service Worker eskirgan static JS va CSS fayllarni keshdan uzatishda davom etadi. Foydalanuvchilar interfeysida buzilishlar va hydration xatolari yuzaga keladi.
- Yechim: Build jarayonida kesh kalitini dinamik ravishda
process.env.NEXT_PUBLIC_BUILD_IDyoki versiya tegi bilan sinxronlash.
- Joylashuv:
apps/web-user/app/[lang]/(main)/hotels/[slug]/page.tsx - Muammo: Ba'zi sub-sahifalarda lug'atlar (
getDictionary) va backend API so'rovlari ketma-ketawaitqilingan. - Yechim: Barcha Server Component sahifalarida
Promise.allyokiPromise.allSettledorqali parallel so'rovlar strategiyasini qo'llash (bosh sahifapage.tsxda qo'llanilgan senior modelini barcha sub-sahifalarga unifikatsiya qilish).
- Muammo:
/hotels/[slug],/booking/[id]va/account/*yo me'nalishlari uchun alohidaloading.tsxvaerror.tsxfayllari mavjud emas. - Oqibat: Backend tarmoq xatoligi bersa, foydalanuvchiga to'liq oq sahifa yoki umumiy xato ekrani chiqadi.
- Yechim: Har bir sub-marshrutga skeleton loader va foydalanuvchiga mos mahalliy qayta urinish (
reset()) tugmasiga egaerror.tsxqo'shish.
- Muammo:
apps/web-user/public/aim/katalogida ichki konfidentsial biznes, investor va texnik hujjatlar (SAFAAR.txt,Investor Pitch Deck.txt,UZRoom_Texnik_Vazifa.docx) statik ochiq papkada saqlangan edi. - Xavf: Har qanday internet foydalanuvchisi brauzer orqali URL yo'lini yozib, loyihaning tijorat va investor sirlarini yuklab olish imkoniyatiga ega bo'lgan.
- Bajarilgan Harakat: Ushbu ochiq maxfiy fayllar loyihaning
public/papkasidan to'liqligicha o'chirildi va tozalandi.
- Joylashuv: apps/backend/src/main.ts:L66
- Muammo: Main bootstrap faylida Swagger va so'rovlar uchun
x-user-rolesarlavhasi (header) sozlangan. - Xavf: Production muhitiga chiqarilganda agar ushbu guard yaxshi tekshirilmasa, tajovuzkor so'rov sarlavhasida
x-user-role: ADMINberib, authorization qatlamini chetlab o'tishi mumkin. - Yechim: Production muhitda (
NODE_ENV === 'production') dev-role atributlarini va sarlavhalarini mutlaqo o'chirish.
- Muammo:
next.config.tsva NestJSmain.ts(Helmet) sozlamalaridaContent-Security-Policy(CSP),X-Frame-Options: DENY,X-Content-Type-Options: nosniffvaReferrer-Policy: strict-origin-when-cross-originsarlavhalari to'liq belgilanmagan.
- Joylashuv:
apps/backend/src/hotels/hotels.service.ts,bookings.service.ts - Muammo:
findManyso'rovlarida mehmonxona, xona, sharhlar va rasmlar kabi munosabatlar (relations) bitta so'rovda kerakli ustunlar ko'rsatilmasdan to'lig'icha (include: { rooms: true, reviews: true }) tortib olinadi. - Oqibat: Ma'lumotlar bazasidan keraksiz megabaytlab matnlar va ustunlar ko'chiriladi va DB xotirasi (RAM) zohiriy ravishda to'ladi.
- Yechim:
includeo'rniga doimoselect: { id: true, name: true, ... }proektsiyalaridan foydalanish.
- Joylashuv: apps/backend/prisma/schema.prisma
- Muammo: Ko'p qidiriladigan va filtrlanadigan ustunlar bo'yicha murakkab indekslar (composite indexes) yetarli emas:
Hotel(cityId, isPublished, minPriceSum)Booking(userId, status, createdAt)Review(hotelId, rating)
- Yechim: Prisma sxemasida
@@index([cityId, isPublished, minPriceSum])va tegishli indekslarni ta me me'minlash.
- Joylashuv:
apps/backend/src/bookings/bookings.service.ts - Muammo: Bir vaqtning o'zida ikki foydalanuvchi bir xil xonani bir xil sanalarga band qilganda (booking creation), xonaning bo me me'shligini tekshirish va band qilish tranzaksiyasi o'rtasida poyga holati (Race Condition) yuzaga keladi.
- Oqibat: Bitta xona ikkita alohida mijozga sotilib ketishi (Overbooking) mumkin.
- Yechim: PostgreSQL Row-Level Locking (
SELECT ... FOR UPDATE) yoki PrismaSerializableisolation level bilan optimistik concurrency locking modelini joriy etish.
- Joylashuv:
globals.cssvatheme.css - Muammo: CSS o'zgaruvchilari va stillar ikkita alohida faylda tarqalgan.
- Oqibat: CSS Spesifiklik (specificity) urushlari hamda sahifa yuklanganda mavzu (Dark/Light mode) o'zgarganda miltillash (FOUC - Flash of Unstyled Content) kuzatiladi.
- Yechim: Barcha dizayn tokenlari va tayanch o'zgaruvchilarni bitta unified
globals.cssfayliga biriktirish.
- Joylashuv:
GuestPicker.tsx,Select.tsx - Muammo: Mobil interfeysda bitta barmoq bilan bosiladigan tugmalar o'lchami minimal tavsiya etilgan 44x44px o'lchamdan kichik va
Escape/ArrowUpklaviatura tugmalari to'g me'ri ulanmagan. - Yechim:
min-h-[44px]vamin-w-[44px]sinflarini biriktirish hamda Accessibility (A11y) standartlariga moslashtirish.
- Maxfiy Fayllar Izolyatsiyasi:
public/papkasidan maxfiy hujjatlar tozalanganini tasdiqlash va.gitignoreqoidalarini yangilash. - Overbooking Himoyasi:
bookings.service.tsichida xona band qilish algoritmini DB Row-Level Locking yoki Prisma Serializable Transaction rejimiga o'tkazish. react-router-domPaketini Tozalash:apps/web-user/package.jsondanreact-router-domni olib tashlash.
next/imageMigratsiyasi:CityCardsSection.tsxva boshqa joylardagi HTML<img>teglarini<Image />ga o'tkazish,next.config.tsga AVIF format hamda xavfsizremotePatternskiritish.- RSC & Client Boundaries:
CityCardsSection,DealsSection,FeaturedHotelsCarouseltarkibidagi'use client'direktivalarini faqat kichik interaktiv wrapper komponentlarga ajratish. - API SDK Unifikatsiyasi:
@safaar/api-clientpaketiniweb-adminvaweb-partnerloyihalariga ham to'liq tatbiq etish.
- Service Worker Kesh Versiyalash:
public/sw.jsdagi cache versiyasini dinamik build ID bilan bog'lash. - Prisma Indekslari & Proektsiyalar: DB so'rovlariga
selectatributlarini majburiy qilish va composite indekslarni joriy etish. - Granular Loaders: Sub-sahifalarga
loading.tsxvaerror.tsxqatlamlarini qo'shish.
- A11y Touch Targets: Mobil interfeysdagi barcha tugmalarni 44px o'lchamga yetkazish va klaviatura navigatsiyasini yaxshilash.
- CSS Consolidation:
globals.cssvatheme.cssfayllarini bitta arxitekturaviy dizayn tizimiga birlashtirish.
Ushbu hisobot Safaar platformasining barcha qatlamlarini to'liq va professional darajada barqarorlashtirish uchun tayyorlandi.