B2B

portal

3 uç · /api/b2b/v1/portal

İ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.

OturumYol parametresi: *key
İstek
curl -X GET "https://{slug}.b2b.blesyum.app/api/b2b/v1/portal/assets/<*key>" \
  -H "Authorization: Bearer <oturum-token>" \
  -H "Accept: application/json"
Yanıt
{
  "data": "…",
  "trace_id": "01JC…"
}
GET/api/b2b/v1/portal/bootstrap

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"
Yanıt
{
  "data": "…",
  "trace_id": "01JC…"
}
Bu sayfa işine yaradı mı?