Sitora · restoran operatsiyalari platformasi

Texnik topshiriq

Platforma nima qilishi kerak va qaysi qoidalarga bo'ysunadi. Har bir satr — tekshirsa bo'ladigan talab; sabablar 59 ta arxitektura qarori (ADR) va 28 ta spetsifikatsiyada, repozitoriyda.

Versiya 1.02026-08-25O'zbek tilidaManba: docs/ — 175 hujjat
0-qism

Maqsad va qamrov

Muammo

Restoran dasturlari odatda bitta bo'lakni yechadi: alohida POS, alohida buyurtma ilovasi, alohida ombor jadvali, alohida xodimlar chati. Ularni bir-biriga moslashtirish ishi restoranning o'z zimmasida qoladi — va bu ish odamlar tomonidan, qayta-qayta, vaqt tig'izligida bajariladi.

Asosiy g'oya

Mehmon ko'rgan tajriba va oshxona ko'rgan operatsiya — bitta voqeaning ikki tomoni. Mehmon buyurtma bergani va oshxona uni boshlashi mumkinmi degan savol — bitta fakt, ikki tarafdan qaralgan. Ular bitta tizimda yashasa, moslashtirish ishi butunlay yo'qoladi.

Shuning uchun Sitora modul-modul sotiladigan "to'plam" emas. Bitta buyurtma o'zi bilan o'z to'lov haqiqatini, stol kontekstini, muhokama tredini va ombor oqibatini olib yuradi — chunki restoran ularni bitta narsa sifatida boshdan kechiradi.

Bozor

O'zbekistondagi ko'p filialli restoranlar.

ParametrQiymat
Tillaruz · ru · en — uchtasi ham birinchi darajali
ValyutaUZS
Vaqt mintaqasiAsia/Tashkent (restoran bo'yicha sozlanadi)
To'lov provayderlariPayme · Click · Paynet · Uzum
IdentifikatsiyaTelegram, Google, telefon OTP, SMS

Kim uchun

AuditoriyaNima kerak
MehmonlarFilialni topish, haqiqiy menyuni ko'rish, buyurtma berish, nima bo'layotganini bilish
Zal va oshxonaHar bir rol uchun bitta aniq navbat; keyingi harakat doim ko'rinib turadi
KassirlarIshonib harakat qilsa bo'ladigan to'lov haqiqati va har bir qarorning izohli yozuvi
Filial adminiPlatformaga kirmasdan bitta filialni boshqarish
EgalarBir necha filialni bitta joydan, operatsiya ichida yashamasdan ko'rish
KuryerlarShartlari ko'rinib turgan ish va saqlab bo'ladigan reyting
Sitora xodimlariHar bir harakat kimga tegishli ekani yozilgan boshqaruv

Qamrovdan tashqarida (ataylab)

Bular qilinmaydi, va bu — qaror:

  • Sitora pul o'tkazmaydi. U restoran qarzini yozadi, lekin hech qachon to'lamaydi (ADR 0044). Ish haqi hisoblanadi — to'lanmaydi.
  • Sitora provayder hisobidan pul yechmaydi. Faqat provayder boshlagan qaytarish (refund).
  • Robotlar buyurtma statusini yozmaydi (ADR 0008). Ular buyurtmaga bo'ysunadi.
  • AI yordamchi o'zi hech narsani o'zgartirmaydi (ADR 0009). Faqat taklif; odam tasdiqlaydi.
  • Bo'lgan voqea tahrirlanmaydi. Tuzatish — yangi yozuv (ADR 0014).
  • Fiskal operator ulanmagan. Struktura tayyor, real operator yo'q.
1-qism

Arxitektura

MOBIL — BITTA KOD BAZASI, TO'RTTA ILOVA (Expo / RN) Sitora mehmon Pro xodim · 8 rol Biz ega Courier kuryer WEB (React + Vite) Console ichki admin Handbook ichki bilim STATIK Landing reklama Docs uz·ru·en HTTPS REST + WebSocket generatsiya qilingan OpenAPI kontrakt Backend — Django + DRF + Channels 27 domen app · ~534 endpoint · yagona haqiqat 4 auth tekisligi · filial chegarasi (X-Filial-ID) web · machine · worker · scheduler rollari PostgreSQL yagona haqiqat manbai navbat ham shu yerda (ADR 0023) Redis channel layer kesh Tashqi servislar — adapterlar ortida Payme · Click · Paynet · Uzum · Supabase (identifikatsiya) Telegram · xarita provayderi · AI provayderi · robot vendorlari timeout jadvali · idempotent callback · SSRF himoyasi SQL pub/sub adapterlar backend'ga bog'liq emas
To'qqiz yuza, bitta backend. Statik saytlar backend'siz yashaydi; qolgan hammasi bitta API va bitta identifikatsiya orqali ishlaydi.

To'qqizta yuza

#YuzaWorkspaceNima
1Backendbackend/Django + DRF + Channels. Yagona API, yagona haqiqat
2Sitoramobile/ customerMehmon uchun buyurtma ilovasi
3Sitora Promobile/ pro8 ta rol workspace'i
4Sitora Bizmobile/ bizEga uchun biznes boshqaruvi
5Sitora Couriermobile/ courierKuryer ilovasi
6Consolefrontend/Sitora xodimlari uchun platforma admini. Passkey auth
7Handbookhandbook/Ichki bilim mahsuloti
8Landinglanding/Reklama sayti. Backend'ga bog'liq emas
9Docs sitedocs-site/Ochiq hujjatlar, uz/ru/en (Astro + Starlight)

Stack

QatlamTexnologiyaNega
BackendPython / Django + DRFDomen qoidalari bitta joyda
RealtimeDjango Channels (WebSocket)Zal, oshxona, chat jonli yangilanadi
BazaPostgreSQLYagona haqiqat manbai
KeshRedisWebSocket guruhlari, kesh
NavbatPostgreSQL jadvaliADR 0023 — Celery/RabbitMQ o'rniga bitta substrat
API kontraktOpenAPI (drf-spectacular)Mijoz kodi generatsiya qilinadi, qo'lda yozilmaydi
MobilExpo / React Native, TypeScript4 ilova bitta kod bazasidan
WebReact + ViteConsole va Handbook — zich, desktop uchun
IdentifikatsiyaSupabase (faqat tekshirish)ADR 0029

To'rt ilova — bitta kod bazasi (ADR 0011)

mobile/ bitta daraxtdan to'rtta ilovani yig'adi; tanlov APP_VARIANT orqali (customer :8081, pro :8082, biz :8083, courier :8084).

Variant izolyatsiyasi — kosmetik emas. To'rtta mexanizm buni majburlaydi, va har biri real xatodan kelib chiqqan:

  • start-variant.mjs — yagona kirish nuqtasi. Port band bo'lsa ishga tushmaydi (Expo boshqa portga sirg'alib noto'g'ri ilovani ko'rsatmasligi uchun).
  • Har variantga alohida Metro kesh ildizi. (Umumiy kesh tufayli Biz dev-serveri bir marta "Sitora Biz" nomi ostida mijoz ilovasini ochib qo'ygan.)
  • appVariant.ts manifest bilan env o'zgaruvchini solishtiradi; mos kelmasa dev'da xato tashlaydi.
  • Metro *.variant.* importlarini *.<APP_VARIANT>.* fayliga yo'naltiradi.

Arxitektura qoidalari

  • Ish oqimi haqiqati — backend'niki. Odam keyin nima qila olishini platforma hisoblaydi, mijoz faqat chizadi. Har obyekt allowed_actions ro'yxatini olib yuradi.
  • Filial — operatsion chegara (ADR 0001). Filialga bog'liq har endpoint X-Filial-ID talab qiladi.
  • Identifikatsiya global, huquq kontekstual. Bitta User butun platformada; vakolat filialdagi a'zolik + o'sha yerdagi huquqdan keladi.
  • Auth tekisliklari aralashmaydi. To'rttasi bor; birining sessiyasi boshqasiga o'tmaydi.
  • Xatolik loyihalanadi. Offline, eskirgan, ziddiyatli, kirish yo'qolgan — har bir jonli ekran o'zi qaysi holatda ekanini aytadi.
  • Hech qachon ishonchli soxta narsa. Orqasida backend yo'q imkoniyat ochiq "mavjud emas" deb ko'rsatiladi.
  • Ekranlar boshqariladi, o'qilmaydi. Xodim ekrani — boshqaruv paneli. Skroll uzunligi — nuqson o'lchovi.
2-qism

Rollar va huquqlar

Ijara (tenancy) zanjiri

Restaurant → Filial → FilialMembership → FilialRole / RestaurantRole → Permission
ModelQoida
RestaurantBiznes. Bitta egasi, bitta tarifi, o'z vaqt mintaqasi va valyutasi
FilialFilial — operatsion chegara. (restaurant, name) unikal
FilialMembershipBitta user ↔ bitta filial. Rol ustuni yo'q — a'zolik kirish fakti, rollar unga osiladi
MembershipRoleA'zolik ushlagan bitta rol; filial_role yoki restaurant_role — aniq bittasi (DB constraint)
PermissionHaqiqiy huquq tekshiruvi shu yerda

A'zolik rollarning to'plamini ushlaydi (ADR 0036). Bitta odam bitta filialda Ofitsiant va Kassir bo'la oladi, boshqa filiallarda boshqa rollar, bir nechta restoranda a'zolik. Rollar beriladi va olinadi — rolni "almashtiradigan" operatsiya mavjud emas.

Sakkizta workspace

App roleWorkspaceNima bilan ishlaydi
waiterZalStollar, dining session, stol tasdig'i — filial yetkazib bersa, dispatch ham
kitchenTicketlarTayyorlash navbati va topshirish
cashierTo'lov ko'rigiKutilayotgan da'volar, muammolar, ko'rilgan tarix
managerNazoratE'tibor talab qiladiganlar, insidentlar, zal va fleet holati
inventory_managerOmborZaxira darajalari, tuzatishlar, chegaralar, ogohlantirishlar
supply_managerTa'minotYetkazib beruvchilar, narxlar, xarid, qabul, hisob-fakturalar
content_managerKontentReels yozish, chop etish, izoh moderatsiyasi
adminFilial boshqaruviSozlamalar, xodimlar, override'lar, audit

Dispatcher roli yo'q (ADR 0049). Yetkazib berish taxtasi — Zal workspace'ining qo'shimcha bo'limlari: taxtani o'qish — buyurtmani o'qish, unda harakat — buyurtmani o'zgartirish, ofitsiant ikkalasini allaqachon ushlaydi. Dispatch uchun hech kimga ortiqcha vakolat kerak emas.

App role — bu workspace tanlagichi. U hech qachon huquq tekshiruvi emas.

"Stock Room Assistant" deb nomlangan rol ombor workspace'ini ochadi — lekin ichidagi har harakat o'sha filialdagi haqiqiy huquqqa tayanadi. Bu qoidani unutish ikki marta imtiyoz oshirishga olib kelgan. Amaliy natija: rolga nom berish unga hech narsa bermaydi; huquqlar alohida beriladi.

To'rtta autentifikatsiya tekisligi

#TekislikKredensialKim uchun
1Mobil / tenant APIAuthorization: Bearer4 mobil ilova
2Ichki adminX-Console-Session-ID / X-Handbook-Session-IDConsole, Handbook
3Robotics vendorsit_rk_ kalitiRobot vendorlari
4Realtime WS1-tekislik bearer'ini qayta ishlatadiJonli ekranlar
  • JWT emas, stateful sessiya (ADR 0002). Kredensial — bazadagi qator; bekor qilish darhol va haqiqiy.
  • Sessiya ID — kredensial emas (ADR 0056). 384-bitli bearer yaratiladi, faqat SHA-256'si saqlanadi.
  • Console/Handbook — passkey (WebAuthn), apex RP ID orqali (ADR 0005): bitta kredensial ikkala originda.

Console ichki rollari

Sitora xodimlari uchun 8 rol, 37 huquq kodi: support_agent · billing_operator · risk_reviewer · platform_operations_manager · developer_read_only · auditor · knowledge_reader · super_admin. Xavfli operatsiyalar tasdiqlash oqimidan o'tadi (pending → approved/rejected → executed/failed); audit jurnali faqat qo'shiladi.

3-qism

Funksional talablar

16 kichik tizim, har biri bir xil shaklda: aktorlar → oqim → qoidalar → chegara.

3.1 Buyurtma va zal

Turlari: dine_in · takeout · delivery. Tur kosmetik emas — u holatlar mashinasini qirqadi.

received         → cancelled | pending_payment | preparing
pending_payment  → cancelled | preparing
preparing        → cancelled | out_for_delivery | pickup_ready | ready
ready            → served | cancelled
pickup_ready     → delivered | cancelled
out_for_delivery → delivered | cancelled
served, delivered, cancelled → (terminal)

Jadval ikki marta toraytiriladi: tur bo'yicha (masalan dine_in hech qachon out_for_deliveryga yetmaydi) va settlement timing bo'yicha (prepay + to'lanmagan = hech qanday tayyorlash holati ochilmaydi).

IDQoida
B-1Buyurtma — o'zgarmas operatsion birlik; submitted_at yaratilishda bosiladi
B-2Narxlar server tomonidan joriy menyudan yoziladi. Mijoz yuborgan narx rad etilmaydi — e'tiborsiz qoldiriladi
B-3status yaratilishda o'qish uchun — aks holda mashina ham, to'lov darvozasi ham chetlab o'tiladi
B-4settlement_timing hech qachon mijoz yoza olmaydi — o'z timing'ini nomlay olgan mijoz bepul ovqat topgan bo'lardi
B-5Zalda qo'shimcha buyurtma — yangi buyurtma, tahrirlash emas
B-6Ko'pi bilan bitta buyurtmachi: customer yoki guest_profile (DB constraint)
B-7served_quantity yaratilishda nol — xizmat haqiqati faqat xodim tasdig'i bilan

Filial xizmat rejimlari (accepting_orders, tur bo'yicha yoqish, favqulodda pauza) yaratishni to'sadi; rad etish — 409 va mashina kodi. Sozlama qatori yo'q filial ruxsat beruvchi. Pauza xodim buyurtmalariga ham tegishli — xodim jim chetlab o'ta oladigan pauza pauza emas. Boshqa filial menyusi — 400 (buzuq so'rov); tugagan element — 409 (oddiy poyga, hujum emas).

3.2 Stol xizmati — tab

is_paid ikki savolga javob berardi: to'landimi? (fakt) va to'lovi kafolatlanganmi? (risk hukmi). Darvozaga ikkinchisi kerak — shu sababli boolean o'rniga uch qiymatli enum (ADR 0048):

TimingMa'nosiQachon
prepayTo'lanmaguncha pishirilmaydiHar doim standart
on_deliveryKuryer naqd oladiYetkazib berish + filial COD'ni yoqqan
on_departureStol hisobiga yoziladiFaqat zalda + filial tab rejimini yoqqan
  • Dining session — bu tab. Alohida obyekt yo'q; ochiq sessiyadagi to'lanmagan buyurtmalar yig'indisi = qarz.
  • Faqat zalda va faqat stolda (DB constraint). Tab — filial sozlamasi, standart o'chiq. Tab limiti bor.
  • Qarz bilan sessiya yopish yoziladi, jim o'tmaydi. Hisobdan chiqarish (write-off) hech qachon is_paidni true qilmaydi — pul kelmadi.

3.3 To'lov va pul

Sitora pulni ushlamaydi. U pulning haqiqatini yozadi.

Ikki qatlam: Transaction (restoran nima olgani; pending → confirmed | rejected) va ProviderPayment (Payme/Click/Paynet/Uzum bilan muomala; 7 holat, paid → refunded yagona qaytish yo'li).

IDQoida
P-1is_paid uchun yagona yozuv o'rni (ADR 0006)
P-2Buyurtma qatori — qulf. Parallel to'lovlar SELECT FOR UPDATE bilan seriyalanadi
P-3Imzolanmagan provayder maydoniga qarab qaror qabul qilinmaydi (Click refund soxtalashtirishi shu tarzda topilgan)
P-4Kiruvchi summa menyu haqiqatidan hisoblangan jami bilan solishtiriladi
P-5Kredensiallar muhrlangan; hech qachon to'liq qaytarilmaydi
P-6Refund — faqat provayder tomonidan. Sitora pul yechmaydi
P-7Kill switch pulni to'xtata oladi, hech qachon ko'chira olmaydi
P-8Takroriy callback (replay) zararsiz — idempotentlik majburiy

Qurilmalar: terminal, smart-POS, fiskal registr, mijoz displeyi — mashina printsiplari, foydalanuvchi emas; tor scope'li o'z kredensiali bilan. Bosh qoida: qurilma pul kelganini xabar qilishi mumkin, lekin hech qachon e'lon qila olmaydi. 12 konformans stsenariysi kontraktni pinlaydi (device_cannot_declare_money_received, duplicate_callback_replay, kill_switch_compliance…).

Solishtirish (reconciliation) har farqni nomlaydi (matched · missing_in_sitora · missing_at_provider · amount_mismatch) va faqat aniq harakat bilan yopiladi. Fiskalizatsiya: struktura tayyor (FiscalJob: queued → submitted → fiscalized | failed), real operator ulanmagan.

3.4 Yetkazib berish va kuryerlar

Kotirovka — yetkazib berish to'lovi o'ta oladigan yagona yo'l. Masofa manbasi haqida halol (provayder yoki zaxira formula). Kotirovka bir marta sarflanadi; manzil — snapshot. Narxlash — faqat masofa bandlari.

Ish (job): 9 holat (dispatching … delivered | failed | cancelled | unfilled). Kuryerlar taklif qiladi, siyosat hal qiladi; ish buyurtma mashinasiga aniq ikki nuqtada tegadi. Taklif muddati rad etishdan oldin yoziladi — kuryer "javob bermaslik" bilan statistikadan qochmasligi uchun.

Kuryer maqomi — uch mustaqil qatlam: platforma maqomi (hujjatlar, yosh, shartlar) · restoran bilan kelishuv · hozirgi holat (smena, heartbeat, faol ish). Har taklifda qayta tekshiriladi, hech qachon keshlanmaydi.

Ishonchlilik hisoblanadi, saqlanmaydi: completion 0.45 · on-time delivery 0.25 · on-time pickup 0.15 · acceptance 0.15, 30 kunlik oynada. Sovuq start — band, yomon ball emas. Bitta restoran ta'siri 0.3 bilan cheklangan, statistik chetlanuvchi restoran chiqariladi. Har bir majburlash raqami Console'dan boshqariladi; avtomatik jazo bo'lsa — apellyatsiya navbati majburiy.

COD ikkinchi pul yo'lini qo'shmaydi: kuryer qaytadi → da'vo → kassir tasdiqlaydi — mavjud Transaction yo'lining o'zi. Daromad hisoblanadi; Sitora kuryerga pul to'lamaydi.

3.5 Menyu va zaxira

StockTransactiono'zgarmas. Zaxira soni hech qachon "qo'yilmaydi", faqat tranzaksiya qo'shiladi; ko'rinadigan son — hisoblangan ko'rinish. record_transaction() — yagona yozuv yo'li. Qo'lda tuzatish ziddiyatni aniqlaydi: sanoq davomida son o'zgargan bo'lsa, yozuv rad etiladi. stock_mode qaysi ledger sotiladiganlikni hal qilishini e'lon qiladi — menyu zaxirasi sotiladiganlik, ingredient zaxirasi tannarx (ADR 0042): ikki savol, ikki ledger.

3.6 Ingredientlar va ta'minot

Katalog restoranga, zaxira filialga tegishli. Asosiy birliklar g / ml / unit; konversiya e'lon qilinmagan bo'lsa tizim taxmin qilmaydi — rad etadi. Ingredient ledgeri ham o'zgarmas (11 sabab: qabul, retsept kamomadi, ishlab chiqarish, chiqit, ko'chirish…).

  • Manfiy zaxira ruxsat etilgan — ataylab. Oshxonani "bazada 0" degan sabab bilan to'xtatib bo'lmaydi; manfiy son — ko'rinadigan muammo, to'xtagan xizmatdan yaxshi.
  • Sanash va tuzatish — ikki xil harakat. Ko'chirish har doim juftlik (transfer_out + transfer_in).
  • Xarid: PO 8 holatli (draft → … → received → closed). Sitora taklif qiladi, odam tasdiqlaydi; ko'tarish ≠ tasdiqlash (ikki huquq). Hech narsa yubormaydi, hech narsa to'lamaydi.
  • Qabulda tannarx o'rtacha vaznli usulda (ADR 0043). Lot va muddat xizmatni hech qachon to'smaydi. Narxni ko'rish — huquq: yo'q bo'lsa null qaytadi.
  • Retsept versiyalanadi, lahzaga qarab hal qilinadi; kamomad oshxona boshlaganda yoziladi. Tannarx chiqmasa sababi yoziladi (no_recipe…), jim nolga aylanmaydi.

Storekeeper javonni sanaydi va narxni ko'rmaydi; Supply manager sotib oladi va ko'radi. Ikki ish, bitta so'zning ikki varianti emas.

3.7 Smenalar va mehnat xarajati

To'rt yozuv: smena andozasi · rejalashtirilgan smena (a'zolikni nomlaydi) · ishlangan vaqt (hech qachon tahrirlanmaydi) · stavka (odamni nomlaydi).

  • Davomat hech qachon rad etmaydi va hech qachon avtorizatsiya emas. Kelgan odam kelgan — smenasiz ham yoziladi.
  • Rejalashtirish ogohlantiradi, rad etmaydi (double_booked, overlong_shift, role_not_held…). Menejer sababini biladi.
  • Ikki fe'l — taslim qilish va olish — ikkalasi menejer tasdig'i bilan.
  • Xarajat ishga ergashadi, kalendarga emas. Sitora ish haqi to'lamaydi (ADR 0044) — payroll chegaradan tashqarida.

3.8 Operatsion xarajatlar

  • Doimiy yoki o'zgaruvchan — kiritiladi, taxmin qilinmaydi.
  • Ikki sana juftligi, chunki ikki haqiqat bor: qachon to'landi va qaysi davrni qopladi. Kapital xarajat bir vaqtda butun (naqd oqim) va taqsimlangan (foyda) ko'rinadi.
  • Takrorlanuvchi andoza taklif qiladi; odam yozadi. Umumiy xarajat o'z taqsimlash qoidasini nomlaydi (revenue_share · seat_share · equal · none).
  • Natija: operatsion foyda va zararsizlik nuqtasi (break-even).

3.9 Analitika va hisobotlar

Metrika qatlami — modeli ham, HTTP yuzasi ham yo'q kutubxona: 45 metrika, hammasi bitta natija shaklida. Halollik qoidalari: har raqam qayerdan kelganini e'lon qiladi; zal metrikalari o'z ko'rligini aytadi; tannarx metrikasi nimani narxlay olmaganini aytadi; yalpi / chegirma / tushum — uch har xil raqam; kompozit metrika eng yosh kirishi qadar eski; ikki renderer bir xil raqam chiqarishi golden faylga pinlangan.

Hisobot: 13 bo'lim (10 operatsiya + 3 pul), 4 tasi bepul, qolgani entitlement bilan. Ikki render — Excel workbook va PDF hujjat; generatsiya past ustuvorlikdagi navbat ishi. Console tahlil mavjudligini ko'radi, hech qachon nima yozilganini emas (ADR 0047).

3.10 Muloqot

Ikki o'q: sinf (direct · staff_group · context_thread · incident) va kontekst (stol, sessiya, buyurtma, mijoz, to'lov, insident). Har xabar o'z auditoriyasini olib yuradi (internal_only / customer_visible). Kim ko'rishi — bitta funksiya, to'rt qoida. Tred konteksti hal bo'lgach "settled", 24 soatdan keyin qulflanadi (ADR 0040). Realtime faqat muloqot uchun (ADR 0007). Tred hech qachon ikkinchi buyurtma yo'liga aylanmaydi (ADR 0059).

3.11 Sitora AI yordamchisi

Transport: ish (job), keyin so'rov (poll) — so'rov ichida model kutilmaydi. Vositalar — qat'iy ro'yxat (17 ta: 9 Pro + 8 Biz), model uni kengaytira olmaydi.

Ikki darvoza qoidasi: har vosita (1) chaqiruvchining o'sha filialdagi haqiqiy huquqini va (2) vositaning o'z ruxsat ro'yxatini tekshiradi.

  • Model hech narsani o'zgartirmaydi — faqat draft (ADR 0009): proposed → confirmed | discarded | expired; faqat odam tasdiqlaydi. Draft turi ikkita: zaxira tuzatish, rol o'zgarishi.
  • Erkin matn hech qachon tashqariga chiqmaydi — redaksiya chegarasi majburiy. Provayder chegarasi gateway'niki; domen kodi provayderni bilmaydi. Byudjet va tezlik chegarasi bor.

3.12 Counter — ilovasiz mehmonlar

Vakolatli xodim mehmon nomidan mijoz yuzasida ishlaydi (ADR 0041). Mehmon profili — hech qachon akkaunt emas: kirish yo'q, parol yo'q. Ishlaydigan filial mehmondan olinadi. X-Acting-For sarlavhasi vakolatni e'lon qiladi va tekshiriladi (400/403/404/409 kodlari bilan). Counter hech qachon pul ko'chirmaydi — buyurtmasi oddiy to'lov yo'lidan o'tadi. Har harakat o'zgarmas jurnalga yoziladi.

3.13 Reels

Qamrov: filial yoki restoran darajasida — hech qachon noaniq emas. Hayot davri — aniq holatlar mashinasi; mijozga ko'rinish — bitta queryset. Reyting tushuntirib beriladigan qilib qurilgan — qora quti emas. Ko'rish hisobi: ikki jadval, ikki ish; ReelViewDay — kunlik haqiqat.

3.14 Console va Handbook

Console: rol → huquq kodi → tasdiqlash. Audit — qurilishi bo'yicha append-only, o'chirish yo'li mavjud emas. Boshqariladigan operatsiya oilalari tasdiqsiz bajarilmaydi. Console pulni to'xtata oladi, hech qachon ko'chira olmaydi. Deploy tekshiruvi bir protsessli konfiguratsiyadan bosh tortadi.

Handbook: klassifikatsiya — asosiy o'q; grant sezgirlik oshgani sayin torayadi; vakolat imkoniyatlar (capabilities) orqali, rollar orqali emas. Eskirish hisoblanadi, da'vo qilinmaydi. Kirish audit qilinadi.

3.15 Robotics

Vendor → filialga aktivatsiya → mashina kredensiali. Robotlar foydalanuvchi emas(AnonymousUser, credential) juftligi. Robot buyurtma statusini hech qachon yozmaydi (ADR 0008). Bitta buyurtma + bitta oyoq uchun bitta jonli vazifa. Webhook chiqishi ikki marta qo'riqlanadi (SSRF); yetkazish navbatga qo'yiladi. "O'lib qolgan" robot uchun aniq qaytish yo'li bor. Konformans to'plami vendorni tekshiradi.

3.16 Eksport va import

Arxiv shifrlangan (AES-GCM); parol o'qiladigan holda saqlanmaydi. Import eksportdan ataylab torroq: faqat menyu va stollar; validate (aniq oldindan ko'rish) yoki apply; faqat birlashtirish, tabiiy kalit bo'yicha — hech narsa o'chirilmaydi. Eksport yozuvlari — append-only audit; tashqariga chiqadigan yagona identifikator — public_id.

4-qism

Ma'lumotlar modeli

Backend'da ~200 model bor; quyida yadro — 26 asosiy obyekt.

GuruhModellarKalit qoida
ShaxsUser · UserIdentity · SessionGlobal odam; provayderga xos login (link_origin tasodifiy loginni ataylab bog'lashdan ajratadi); bearer'ning faqat SHA-256'si saqlanadi
IjaraRestaurant · Filial · FilialMembership · MembershipRoleFilial — operatsion chegara; a'zolikda rol ustuni yo'q, rollar to'plam bo'lib osiladi
BuyurtmaOrder · OrderItem · OrderItemAddon · DiningSession · DiningSpot · BranchOperationalSettingsO'zgarmas buyurtma; narx yaratilishda muhrlanadi; sessiya = tab
ZaxiraMenuItem · StockTransaction · Ingredient · IngredientStockTransaction · Recipe/Version · PurchaseOrderIkki o'zgarmas ledger; retsept versiyalanadi; PO'ni odam tasdiqlaydi
PulTransaction · PaymentProviderConfig · ProviderPayment · PaymentIntent · PaymentDeviceYozuv va provayder qatlami alohida; qurilma — mashina printsipi
Yetkazish / mehnatCourierProfile · DeliveryJob · ScheduledShift · TimeEntry · WageRateKuryer — profil, a'zolik emas (ADR 0015); ishlangan vaqt tahrirlanmaydi

O'zgarmaslik naqshi

Uchta ledger bitta naqshni ishlatadi va bu ataylab: StockTransaction · IngredientStockTransaction · Transaction. Har biri faqat qo'shiladi, hech qachon tahrirlanmaydi; joriy qiymat yig'indi sifatida hisoblanadi. Tuzatish — kompensatsiya yozuvi (ADR 0014).

5-qism

Integratsiyalar

IntegratsiyaNima uchunChegara
Payme · Click · Paynet · UzumOnlayn to'lovHar biri o'z adapteri; kredensiallar filial bo'yicha muhrlangan; imzolanmagan maydonga qarab qaror yo'q
SupabaseFaqat identifikatsiya tekshiruvi (ADR 0029)Backend Supabase sessiyasini ushlamaydi; kimlik faqat sub bo'yicha — user_metadata foydalanuvchi yozadigan maydon, unga ishonilmaydi
Telegram BotDeep-link va kod orqali kirishSessiya ID — chop etiladigan identifikator, kredensial emas
Google Sign-InTizim akkaunt tanlagichiBrowser emas, webview emas — oddiy token almashinuvi
Xarita provayderiMasofa hisoblashYagona gateway; oylik byudjet va throttle; yiqilsa — filial siyosatiga qarab zaxira narx yoki rad etish
AI provayderiSitora AIGateway chegarani egallaydi; erkin matn tashqariga chiqmaydi
Robot vendorlariOchiq xizmat APISertifikatlash → aktivatsiya → kredensial; webhook SSRF'dan qo'riqlangan
Fiskal operatorChek fiskalizatsiyasiUlanmagan. Struktura tayyor, real operator yo'q

Umumiy qoidalar: provayder chegarasi adapter ortida; har chiquvchi so'rovning yozilgan timeout'i bor; callback'lar idempotent; webhook'lar navbatga qo'yiladi; provayder yiqilganda tizim nima bo'lganini aytadi — jim zaxiraga o'tmaydi.

6-qism

Nofunksional talablar

Tezlik maqsadlari (ADR 0057)

Maqsad Sitora nazorat qiladigan joyda o'lchanadi — server tomonida, telefonda emas. Toshkentdagi yaxshi 4G server maqsadiga 150–250 ms qo'shadi; yomon ulanishda chegara yo'q.

TekislikNima kiradip95p99
XizmatMehmon/xodim kutib turgani: buyurtmalar, menyu, counter, tranzaksiyalar400 ms1 200 ms
Back officeConsole, Handbook, Biz tahlillari, eksport1 000 ms3 000 ms
PollKuryer/qurilma/robot pollingi, provayder callback'lari250 ms800 ms

Qurilma: sovuq start ≤ 3 s (etalon Android'da); har asosiy fe'lning javobi ≤ ~100 ms — ushlab turilgan, o'chirilgan yoki optimistik.

Miqyos siyosati (ADR 0058)

Poydevor hozir A darajaga quriladi — arxitektura, so'rov samaradorligi, mobil javobgarlik. Qolgani — yetarli darajada; yuqori darajali optimizatsiya trigger otmaguncha sotib olinmaydi (hajm, kechikish, navbat yoshi, tarix o'qishi, qurilma triggerlari). Miqyos protsess roli bo'yicha (web · machine · worker · scheduler), tenant bo'yicha emas (ADR 0021).

Xavfsizlik

IDTalab
SEC-1A'zolik — filialga bog'liq har o'qish uchun pol (ADR 0030); anonim o'qishlar e'lon qilinadi, meros qilib olinmaydi
SEC-2Auth tekisliklari aralashmaydi; sessiya ko'tarilmaydi
SEC-3Sessiya tekshiruvi hech qachon keshlanmaydi (ADR 0027) — bekor qilish darhol ishlashi uchun
SEC-4Console/Handbook — passkey (WebAuthn), apex RP ID, step-up bilan
SEC-5Kredensiallar muhrlangan; to'liq qaytarilmaydi
SEC-6Chiquvchi so'rovlar SSRF'dan qo'riqlanadi
SEC-7Media avtorizatsiya qilinadi: imzolangan redirect yoki oqim; kalit egasini nomlaydi
SEC-8Audit — append-only
SEC-9Erkin matn AI provayderiga chiqmaydi

Ma'lumot, til, kontrakt

  • Operatsion ma'lumot saqlash soatiga ega (ADR 0025); tiklash maqsadlari mashq qilinadi yoki yo'q hisoblanadi (ADR 0024).
  • Uch til birinchi darajali. Ma'lum cheklov: generatsiya qilingan hisobotlar hozircha ingliz tilida (ADR 0055) va muqova buni ochiq aytadi.
  • API ikkita oldingi mobil kontraktni qo'llab-quvvatlaydi (ADR 0026); barcha ro'yxatlar sahifalanadi (100/500, katalog 500/1000); mijoz kodi generatsiya qilinadi (ADR 0010); generatsiya qilingan artefaktlar qayta generatsiya bilan tekshiriladi (ADR 0031).
  • Har protsess rolini e'lon qiladi, /healthz / /readyz javob beradi; so'rov korrelyatsiya ID bilan kuzatiladi; deploy tekshiruvi bir protsessli konfiguratsiyadan bosh tortadi.
7-qism

Holat: nima tayyor, nima tayyor emas

Bu bo'lim ataylab ochiq. Repozitoriyda uni saqlaydigan alohida fayl bor va u blokerlarni faqat haqiqatda bajarilganda o'chiradi — uzoq turgani uchun emas.

YuzaLokal darvozaOchiq bloker
Consoleo'tadiStaging smoke — real HTTPS'da cross-origin passkey
Handbooko'tadiCross-origin passkey staging smoke (Console bilan umumiy)
Bizo'tadiStaging smoke — onboarding'dan faol filialgacha
Proo'tadiRol bo'yicha doktrina o'tishlari va qolgan launch hardening
Customero'tadiQurilma/do'kon sinovi yo'q; store assets va maxfiylik siyosati
Deliveryo'tadiKuryer qurilma sinovi — real temirda; fon geolokatsiyasi yo'q
Landingo'tadi
Birinchi ishga tushish ekranilokalQurilmada va screen reader bilan sinalmagan
Generatsiya qilingan tahliltestlarRU/UZ hisobotlar ingliz tilida; raqamlarni hech kim o'qib chiqmagan
Docs sitequriladiProduction domen yo'qligi sababli sozlanmagan
Operatsion tiklashmashq qilingan2026-08-24: RTO 25 s, RPO ≤ 60 s — lekin lokal stack'da; production infratuzilmasi hali mavjud emas
Tezlik maqsadiartefakt yo'qStaging load-smoke o'tkazilmagan: maqsad da'vo qilingan, tekshirilmagan

Bitta jumlada: hech bir yuza "chiqarilgan" (released) emas. Darvozasi qanchalik yashil bo'lmasin, ochiq blokeri bo'lgan har yuza bloklangan holicha qoladi.

Nima haqiqatan ishlaydi

  • Backend to'liq: 27 domen app, ~534 endpoint, testlar yashil
  • To'rt mobil ilova quriladi va yuklanadi (bundle + signing tekshirilgan; kuryer AAB sinalgan)
  • To'liq stack bitta buyruq bilan lokalda: docker compose up --build — demo restoran bilan urug'langan
  • Tiklash muolajasi mashq qilingan va takrorlanadigan

Nima yo'q

  • Production infratuzilmasi mavjud emas — staging ham, prod ham
  • Hech bir yuza real qurilmada, real tarmoqda, real mehmon bilan sinalmagan
  • Fiskal operator ulanmagan
  • Kuryer ilovasida fon geolokatsiyasi yo'q (faqat ilova ochiq turganda)
  • Tezlik maqsadlari o'lchanmagan — faqat e'lon qilingan

Nega bu ochiq yozilgan

Yashil test — yuza ishlashini aytadi, yaxshi ekanini hech qachon aytmaydi. Eng aniq misol repozitoriyda yozilgan: hisobot tizimining barcha testlari o'tgan edi — jumladan ikkala renderer bir xil raqam chiqarishini isbotlaydigani ham — va PDF mijozning kirill alifbosidagi nomini har sahifada qora kvadratchalar qatori qilib chop etayotgan edi. Testlar renderer xabar qilgan raqamlarni solishtirgan; hech kim o'quvchidan nima ko'rayotganini so'ramagan. Nuqson tuzatilgan va endi ratchet bor. Dars qoladi: har bir yozuv nimani hali hech kim ko'rmaganini ham nomlaydi.

8-qism

Ilova — chuqurroq o'qish uchun

Bu TZ — qisqartma. Har mavzuning to'liq versiyasi repozitoriyda:

Kerak bo'lsaQarang
Hujjatlar xaritasidocs/README.md
Mahsulot tavsifidocs/product/product-overview.md
Platforma tuzilishidocs/reference/platform-map.md
Kim nima qila oladidocs/reference/identity-and-access.md
Har domen qanday ishlaydidocs/reference/domains/ — 19 hujjat
Batafsil spetsifikatsiyalardocs/specs/ — 28 hujjat
Qarorlar va sabablaridocs/decisions/ — 59 ADR
Doktrinalardocs/doctrine/ — 10 hujjat
Chiqarish holatidocs/operations/release/verification/README.md

Hujjat vakolat sinflari (ADR 0017)

Repozitoriyda faqat reference sinfi kod hozir nima qilishini da'vo qila oladi — va har da'vo dalil langariga (evidence anchor) ega. Hujjat va kod ziddiyatga tushsa — kod yutadi.

Loyihani ishga tushirish

docker compose up --build     # keyin: bash docker/smoke.sh

Backend PostgreSQL va Redis'da, worker va scheduler, Console (:5173/console), Handbook (:5174), landing (:4173), docs (:4321), to'rt mobil ilova web ko'rinishida (:8081–:8084) — demo restoran bilan. Kirish yo'llari: docs/operations/local-stack.md.