İstek örnekleri ucun GERÇEK metodu ve yolundan üretilir. 3 ucun elle doğrulanmış gövde örneği henüz yok; o uçlarda iskelet gövdesizdir — uydurma bir alan yazmıyoruz.
GET/api/b2b/v1/portal/assets/{*key}
GET /api/b2b/v1/portal/assets/{*key} (B2bPublicCtx, public) — durable marka varlığı sunumu.
GET /api/b2b/v1/portal/bootstrap (require_b2b_public). BF6 Plan A — frontend'in SSR
Herkese açık
aşamasında (`layout.tsx`, Task 6) çağırdığı **tek** sözleşme ucu; dönen JSON `window.
bootstrapData` olarak enjekte edilir. `redact`: yanıt yalnız burada el ile kurulan sabit
alanları taşır (hiçbir geniş "settings"/config ağacı okunmaz) → sır (llm.*/api key/sealed
cred) sızma YÜZEYİ hiç YOK (CRM bootstrap'ının aksine, burada redaksiyon edilecek genel bir
ayar deposu zaten sorgulanmıyor).
- `brand`: portal-scoped (Task 2 `branding::resolve_portal`+`get_published`; host eşleşmezse
tenant'ın `is_default` portalına düşer, o da yoksa `null`). `info_handler`'ın kullandığı
`blesyum_branding::get_published` (tenant-level, ayrı tablo/kavram) İLE KARIŞTIRILMAMASI için
burada modül-yerel `branding::` alias'ı (bkz. yukarıdaki `use crate::branding;`) kullanılır.
- `settings.features.online_payment`: `b2b.payment_settings` (tenant-RLS; satır yoksa `false`
— BF5 varsayılanıyla birebir aynı fail-closed davranış).
- `user`: anonim/`InactiveDealer`/`NonMember` → `null` (misafir görünümü — oturum "geçerli"
olsa bile çözülebilir bir principal karşılık gelmiyorsa sızdırılacak bir şey yok). Dealer/
Staff → `{id, name, email, principal, permissions}`. Dealer izinleri `rbac::
effective_dealer_permissions`'tan; **Staff izinleri (2026-08-14) `b2b.*` ile SINIRLI
olarak** [`staff_b2b_permissions`]'tan gelir. Eskiden Staff için boş dönüyordu ve
gerekçesi "admin yüzeyleri zaten `require_permission` ile korunuyor" idi — bu doğru ama
eksikti: kapı korunuyordu, **menü süzülemiyordu**, kısıtlı personel giremeyeceği yedi
bölümü de görüp tıklayınca duvara çarpıyordu. Liste bir YETKİ KAPISI DEĞİL, görünürlük
ipucudur; kapı yerinde duruyor.
İstek
curl -X GET "https://{slug}.b2b.blesyum.app/api/b2b/v1/portal/bootstrap" \
-H "Accept: application/json"
Yanıt
{"data":"…","trace_id":"01JC…"}
GET/api/b2b/v1/portal/info
GET /api/b2b/v1/portal/info (require_b2b_public; anonim portal/login marka).
Herkese açık
NOT: burada `blesyum_branding::get_published` (extern crate, **tenant-level**
`core.tenant_branding`, RLS'siz) çağrılır — [`bootstrap_handler`]'ın kullandığı modül-yerel
`branding::get_published` (**portal-level**, `b2b.portal_brand`, Task 2) İLE KARIŞTIRILMAMALI;
ikisi ayrı tablo/ayrı kavramdır (bkz. `crate::branding` modül dokümantasyonu).
İstek
curl -X GET "https://{slug}.b2b.blesyum.app/api/b2b/v1/portal/info" \
-H "Accept: application/json"