Görünüm
Mimari özet
Kimin içinBT
Katmanlar
| Katman | Bileşen | Sorumluluk |
|---|---|---|
| L0 | CukoZ One | Kimlik (OAuth2/OIDC), organizasyonlar, abonelikler, faturalama, yetkilendirmeler (entitlements) |
| L1 | Suite Core | Kiracı, şube, rol/izin, modül kaydı, olaylar |
| L2 | Genel modüller | Müşteriler, Stok, Muhasebe, Rezervasyon, Raporlar, Operasyon |
| L3 | Sektör paketleri | Restoran (Adisyon, QR menü) |
| L4 | Portallar | CukoZ One portalı, CukoZ Suite portalı (panel + POS + misafir sayfaları) |
CukoZ Suite bir modüler monolittir: tek bir dağıtılabilir API; her modül kendi PostgreSQL şemasında. Yerleşik modüller: Contacts, Adisyon, Inventory, Accounting, Reservation, Reports, QrMenu, Operations.
Teknoloji yığını
- CukoZ One: ASP.NET Core (net8.0), ASP.NET Core Identity (PBKDF2, kilitleme, TOTP), OpenIddict, EF Core + Npgsql, Redis önbellek (Redis yoksa bellek içi).
- CukoZ Suite: ASP.NET Core (net9.0), EF Core 9 + Npgsql (snake_case), JWT bearer, HTTP dayanıklılık (resilience), Swagger.
- Veritabanı: PostgreSQL 16 — ayrı veritabanları
cukoz_one/cukoz_suite, en az yetkili uygulama rolleri. - Önbellek: Redis 7 (yalnızca önbellek).
- Portallar: Next.js; BFF deseni — belirteçler httpOnly çerezde tutulur, tarayıcı API’leri doğrudan çağırmaz.
- Kenar: Caddy (otomatik Let’s Encrypt) veya Kubernetes’te ingress-nginx + cert-manager.
Kimlik ve oturum
- Portallar CukoZ One’a Authorization Code + PKCE (S256) ile bağlanır; birinci taraf istemcilerde onay ekranı gösterilmez. Kullanıcı One’da oturum açtıysa Suite’e tekrar parola sorulmadan girer.
- Erişim belirteci 4 saat, yenileme belirteci 30 gün geçerlidir.
- Suite, One’a istemci kimlik bilgileriyle (client credentials) bağlanarak işletmenin yetkilendirmelerini okur. One’a ulaşılamazsa son bilinen iyi değer (24 saate kadar) kullanılır.
- POS terminalleri kullanıcı belirteci yerine cihaz sırrı ve isteğe bağlı PIN oturumu ile kimlik doğrular. Bkz. API.
Çok kiracılılık ve üç kapı
Her varlık OrganizationEntity’den türer ve DbContext’teki genel sorgu filtresi kiracıyı otomatik uygular. Konuma bağlı varlıklar IBranchScoped uygular; şube X-Branch-Id başlığıyla seçilir (* = tüm şubeler, salt okunur). Her işletme otomatik bir “Ana Şube” ile başlar.
| Soru | Mekanizma | Sonuç |
|---|---|---|
| Bu satır bu kiracıya mı ait? | DbContext genel sorgu filtresi | Görünmez |
| Bu kiracı bu modülü kullanabilir mi? | [RequireModule("key")] | 402 module_not_enabled |
| Bu kullanıcı bu işlemi yapabilir mi? | [RequirePermission("x.y")] | 403 forbidden |
Roller, kiracının tanımladığı izin dizesi kümeleridir (sabit bir rol listesi yoktur). “Owner” sistem rolü ["*"] ile başlatılır ve son Owner kaldırılamaz. Hassas izinler POS’ta yönetici PIN’i veya uzaktan onayla “ödünç alınabilir”.
Ölçeklenebilirlik
- Dış yan etkiler outbox ile (
FOR UPDATE SKIP LOCKED), işleyiciler idempotent. Idempotency-Keybaşlığıyla POST tekrarları güvenli; idempotency kayıtları dağıtık önbellekte.- Tek seferlik arka plan işleri için veritabanı tabanlı lider seçimi (
core.job_leases). - Data Protection anahtarları veritabanında (
core.data_protection_keys) — servisler durumsuz. - İkinci düğüm eklerken: Redis, PgBouncer, yük dengeleyici sağlık yoklamaları,
--migrate-only, outbox etkin.
Olaylar ve modüller arası iletişim
Modüller birbirini doğrudan çağırmaz. Çekirdek alan olayları yayınlar (örn. OrderClosed, OrderItemFired); modüller bunları dinler. Örnek: ürün mutfağa gönderilince reçete tüketimi stoktan düşülür; mutfak takibi kapalıysa ürün hemen “servis edildi” olarak işaretlenir.
Ayrıntılar: Modül eklenti mimarisi.

