# Yetki ve kimlik mimarisi — tasarım brief'i

*30.07.2026 · Sets'in talebi: kullanıcı yetki sayfası tasarlanacak · kaynak: `docs/specs/omurga-spec.md` §3/§5/§6, `docs/arch/mimari-kararlar.md` AD-09/AD-23/AD-28, `config/authorization.php`, `app/Support/Authorization/*`*

Bu belge tasarımcıya **sistemin yetki modelini eksiksiz** anlatır ve **hangi ekranların tasarlanmasını beklediğimizi** söyler. Kod referansları doğrulama içindir; tasarımcı okumak zorunda değildir.

Mevcut ekranlar için `63 Yonetici Kullanici Log.dc.html` zaten bir kullanıcı listesi ve kullanıcı detayı veriyor — **onu değiştirmek istemiyoruz**, eksik olan **"Yetkileri Düzenle" düğmesinin arkası**: bugün orada tasarım yok, kod bir tabloyu kendi kafasına göre çiziyor ve karman çorman görünüyor.

---

## 1. Sistemde üç ayrı kimlik alanı var

Üçü **ayrı host, ayrı oturum tablosu, ayrı yetki havuzu**. Bir alandaki yetki diğerinde hiçbir şey açmaz; aynı isim iki alanda farklı şey demektir (`training.view` ofiste *planlanmış eğitim*, backoffice'te *eğitim kataloğu tanımı*).

| Alan | Kim | Nerede | Ne yapar |
|---|---|---|---|
| **Ofis** | 3E çalışanı: planlamacı, satışçı, operasyon, direktör, **eğitmen** | `ofis.…` | Günlük iş: eğitim planlar, satar, yürütür |
| **Backoffice** | Sistem yöneticisi (3E'nin kendi BT/yönetim tarafı) | `backoffice.…` | Kural ve tanım: mevzuat, eğitim kataloğu, fiyat listesi, şablonlar, ayarlar. **Filament paneli — tasarım kapsamı dışı** |
| **Müşteri** | Müşteri firmanın kullanıcıları + katılımcılar | `portal.…` | Kendi firmasının personeli, teklifleri, eğitimleri |

⚠ **Eğitmen ayrı bir kimlik alanı değildir** — ofis kullanıcısıdır, üzerinde bir *eğitmen dosyası* vardır. Eğitmen panelini açan şey bir yetki değil, o dosyanın **var olmasıdır**.

### Giriş yöntemleri

Dört yöntem var: **şifre**, **iki adımlı doğrulama (authenticator)**, **passkey** (parmak izi / Face ID / güvenlik anahtarı), **magic link** (e-postaya gelen tek kullanımlık bağlantı).

- Hangi alanın hangi yöntemi kullanabileceği **admin ayarıdır**, kodda sabit değildir.
- **Backoffice'te MFA herkes için zorunlu** — yetkisi olmayan hesap için de. Yöntem kişinin seçimi (authenticator ya da passkey), zorunluluk pazarlığa açık değil.
- **Magic link tek başına kimlik kanıtlamaz** (bağlantı paylaşılabilir): magic link'le açılan oturum panel yetkilerini açmaz, ikinci bir kimlik kontrolü ister.
- 5 başarısız denemede hesaba **giriş kısıtı** uygulanır (30 dk) — bu "dondurma" değildir, ayrı bir durumdur ve yönetici elle kaldırabilir.

---

## 2. Yetki modeli

### 2.1 Yetki = kaynak × eylem

Yetkiler düz bir liste değil, **matris**tir: satırda **kaynak** (neye), sütunda **eylem** (ne yapabilir).

Sütunlar sabit ve **artan sırada** okunur:

| Görüntüleme | Ekleme | Düzenleme | Pasifleştirme | Yetki devri |
|---|---|---|---|---|
| Okur, değiştirmez | Yeni kayıt açar | Mevcudu değiştirir | Yeni kullanıma kapatır (silmez) | Başkasının yetkisini belirler |

**Neden matris:** on iki yetki düz listede aynı şekle sahip; birine *bakma* vermek isteyen kişi farkında olmadan *yazma* verebiliyor — satırlar fark etmesi için bir şey sunmuyor. Matriste tikin durduğu sütun **fiilin kendisidir**.

**Bir eylem o kaynak için yoksa hücre boş kalır (—).** Uydurulmaz. Örnek: fiyat listesi *pasifleştirilmez* (teklif verilmiş liste kapatılmaz, yerine yenisi geçer) → o hücre em-dash.

**Ofis matrisi — 10 satır:** Ofis ekibi · Müşteri firmalar · Planlanan eğitimler · Eğitim talepleri · Tedarikçiler · Eğitmen dosyası · Evrak · Denetim izi · Raporlar · Finansal veriler
**Backoffice matrisi — 11 satır:** Sistem ayarları · Mevzuat kayıtları · Eğitim kataloğu · Belge türleri ve listeler · Fiyat listeleri · Bildirim şablonları · Rıza metinleri · Backoffice hesapları · Ofis hesapları · Denetim kaydı · Erişim günlüğü
**Müşteri matrisi — 4 satır:** Firma bilgileri · Personel · Teklifler · Evrak

Toplam: ofis **53**, backoffice **35**, müşteri **7** yetki.

### 2.2 Kapsam: aynı yetki, üç mesafe

Bazı ofis yetkileri **kime kadar** sorusunu da taşır. Bu, ayrı bir alan değil, yetkinin **kendi adının parçasıdır**:

| Kapsam | Anlamı |
|---|---|
| **Kendi** (`own`) | Yalnız kendi kayıtları |
| **Grubu** (`group`) | Bulunduğu düğüm + altındaki her şey |
| **Tümü** (`all`) | Kısıt yok |

Kapsam taşıyan yetkiler: ofis ekibi (görüntüleme/düzenleme/pasifleştirme/yetki devri/ekleme), planlanan eğitimler (görüntüleme/ekleme/düzenleme/onay/iptal/iptal onayı/eğitmen atama/bakanlık bildirimi), eğitim talepleri (görüntüleme).

⚠ **Her yetkinin üç kapsamı yoktur.** "Kendini oluşturma" diye bir şey olmadığı için *ekleme*de `own` yok. Evrak yükleme, denetim izi okuma gibi işlerde *"kimin kaydı"* sorusu hiç sorulmuyor — onlar kapsamsız.

⚠ **Tasarım kararı gereken yer burası:** bir hücre iki soruyu birden soruyor — *verilsin mi* ve *ne kadar*. Bugün kod bunu "checkbox + yanında küçük select" diye çözüyor ve matris kalabalıklaşıyor. Daha okunaklı bir çözüm bekliyoruz.

### 2.3 Grup ağacı ve seviye — "rol" buradan çıkar

3E'nin organizasyonu tek bir ağaçtır: `Satış → İzmit Satış`, `Eğitmen Kadrosu → İzmit Eğitmenleri` gibi. Kişi bir veya birkaç düğüme **üye** olur, her üyelikte bir **seviyesi** vardır:

| Seviye | Etkisi |
|---|---|
| **Direktör** | Düğümü ve altını görür |
| **Grup Yöneticisi** | Düğümü ve altını görür |
| **Personel** | `group` kapsamlı yetkileri **kendi kaydına** daraltır |

⛔ **Seviye yetki taşımaz.** Kişiyi bir gruba koymak onu *yetkilendirmez*, sadece **yerleştirir**. Yetkiler tek tek verilir. Yeni açılan hesap bu yüzden hiçbir şey yapamaz durumda doğar.

**Ekranda görünen "rol" adı bir bileşimdir:** grubun dikeyi + seviye → *"Satış" + "Direktör" = Satış Direktörü*. Sistemde "satış direktörü" diye kayıtlı bir rol yoktur; on bir rol adını saklamak yerine ağaç + seviye saklanır — yeni bir dikey açıldığında üç yeni rol adı icat etmek gerekmesin diye.

⚠ Seviye yalnız `group` kapsamını daraltır. `all` ağacın dışında verilmiş bilinçli yetkidir, seviye ne olursa olsun durur.

### 2.4 Tavan kuralı (Y-4)

**Kimse sahip olmadığı yetkiyi başkasına veremez.** Üç kimlik alanında da geçerli. Yetki devretmek ayrıca kendi başına bir yetkidir (`Yetki devri` sütunu).

**Tek istisna: backoffice.** Sistem ilk açıldığında ofiste kimse yoktur; backoffice, kendisi taşımadığı ofis yetkisini atayabilir. Bu kalıcıdır.

⚠ Bunun ekran karşılığı: yetki verme ekranında **veremeyeceğin kutular kapalı gelir** ve nedenini söyler. Bugün tek satırlık bir açıklama var (*"Yalnızca kendi sahip olduğunuz yetkileri devredebilirsiniz"*); kutu bazında "neden kapalı" görünmüyor.

### 2.5 Roller — kimde var, kimde yok

| Alan | Rol var mı |
|---|---|
| **Ofis** | ❌ Yok. Yetkiler kişiye tek tek verilir |
| **Backoffice** | ✓ Var (bugün tek rol: *süper yönetici* — her şeyi açar, tek tek düzenlemeyi kapatır; sonradan eklenen yetkiler de kendiliğinden ona geçer) |
| **Müşteri** | ✓ Var. Firma kendi rollerini kurar; ilk hesap her şeyi taşıyan *"sahip"* rolüyle doğar, sonra eklenen her hesap **sıfır yetkiyle** gelir ve bu rolün kararını bekler |

Rolden gelen yetki kişide **işaretli ve kilitli** görünür — oradan kaldırılamaz, rolün kendisi değiştirilir.

⚠ **Ofiste rol yokluğu bir tasarım sorusu doğuruyor:** 24 kişilik ofiste her yeni satışçıya 53 yetkiden doğru olanları tek tek işaretlemek gerekiyor. Tasarımcıdan bu konuda bir öneri bekliyoruz (şablon? "şu kişiden kopyala"? gruba varsayılan?) — **karar Sets'in**, ama seçenekleri görmek istiyoruz.

### 2.6 Yetkisiz kalem hiç render edilmez

Menü yetkiye göre süzülür: erişilemeyen sayfa **menüde görünmez** (gri/kilitli değil — **yok**). Aynı şey rota tarafında da kapalıdır; menü ikinci savunma hattıdır.

---

## 3. Hesap yaşam döngüsü

| Durum | Anlamı |
|---|---|
| **Davet edildi** | Hesap açıldı, kişi henüz girmedi |
| **Aktif** | Çalışıyor |
| **Girişi kısıtlı** | Geçici (5 hatalı deneme → 30 dk). Ayrı bir işaret, ayrı bir aksiyon: *Kısıtı Kaldır* |
| **Dondurulmuş** | Giremez, oturumları anında kapatılır. **Üzerindeki iş durur ve onu bekler**; geri açılabilir |
| **Kapatılmış** | Geri dönüşü yok. Kişi dönerse yeni hesap açılır |

⛔ **Kullanıcı silinmez** — pasifleştirilir. Kayıt ve denetim izi olduğu gibi kalır.
⛔ **Kimse kendi hesabını donduramaz/kapatamaz.** Hesapları geri açabilecek **son** hesap da kapatılamaz.
⛔ Dondurma ve kapatma **gerekçe ister**, denetim kaydına yazılır; kapatma ayrıca **kendi şifresini** ister.
⛔ Bir hesabın yetkileri değiştiğinde bu da denetim kaydına yazılır (kim, ne zaman, hangi yetkiyi verdi/aldı).

---

## 4. Bugün ekranda ne var, nesi bozuk

**Var:** kullanıcı listesi (`/kullanicilar`), kullanıcı detayı (kimlik kartı + yetki matrisi + kişinin logları), dondur/kapat/aktifleştir/kısıt kaldır modalleri.

**Bozuk olan — tasarımcının çözmesini istediklerimiz:**

1. **Yetki matrisi ham bir tablo.** 10 satır × 5 sütun checkbox + kapsam seçici; hangi hücrenin ne açtığı ancak üstüne gelince anlaşılıyor. Kalabalık ve okunmuyor.
2. **Kapsamlı hücre iki soruyu bir kutuya sıkıştırıyor** (§2.2).
3. **Matrise sığmayan 9 ofis yetkisi** ayrı bir blokta duruyor ve neden ayrı olduğu görünmüyor: *tüm müşterileri görme* (bu bir kapsam, yetki değil), *müşteri atama*, *evrak indirme*, *özel nitelikli veri görme*, *maliyet onayı*, *iptal*, *iptal onayı*, *eğitmen atama*, *bakanlık bildirimi*. Bunlar "bir kaynağa yapılan eylem" değil, ayrı kararlar.
4. **Y-4 kapalılığı sessiz.** Veremediğin kutu kapalı ama sebebi kutunun yanında değil.
5. **Grup üyeliği ve seviye ile yetki aynı ekranda ama ilişkisi görünmüyor.** Kişi "İzmit Satış · Personel" ise `group` kapsamlı yetkileri fiilen `own`'a düşüyor — ekran bunu söylemiyor.
6. **Rolden gelen kilitli satır** deseni bugün yalnız metin olarak var.
7. **Toplu iş yok:** yeni satışçıya 53 yetkiyi tek tek işaretlemek gerekiyor (§2.5).

---

## 5. Tasarımcıdan beklenenler

**Öncelik: ofis tarafı.** Backoffice Filament olduğu için tasarım kapsamı dışı; müşteri portalı yetki ekranı ikinci turda.

| # | Ekran / durum | Beklenen |
|---|---|---|
| 1 | **Yetki düzenleme** (kullanıcı detayından açılır — sayfa mı, drawer mı: tasarımcının kararı, gerekçesiyle) | Matrisin okunabilir hâli; kapsam seçiminin matrisi boğmayan çözümü; matris dışı 9 kararın kendi bölümü |
| 2 | **Kutu neden kapalı** | Y-4 (sende yok) · rolden geliyor · o kaynakta o eylem yok (—) — üçü **farklı** görünmeli. `06 Desen Ekleri`'ndeki kilit açıklama deseni burada kullanılabilir |
| 3 | **Grup üyeliği bloğu** | Kişinin düğümleri + seviyeleri; birden çok üyelik; *"personel seviyesi grup kapsamını daraltır"* bilgisinin görünür hâli |
| 4 | **Yeni kullanıcı ekleme akışı** | Kimlik + grup yerleşimi + ilk yetkiler; §2.5'teki toplu atama önerisi |
| 5 | **Yetki değişikliği kaydetme** | Neyin verildiği/alındığı özeti + denetime yazılacağının söylenmesi; geri alma yok, kaydetmeden önce görünmesi lazım |
| 6 | **Yetki bekleyen hesap** | Yeni açılmış, hiçbir şeyi olmayan hesabın hem listede hem detayda görünümü (bugün ayrı bir rozet var) |
| 7 | **Kısıt / dondurma / kapatma** | `63`'teki desen korunur; **kısıt ile dondurma karışmasın** |
| 8 | **Kişinin yetki geçmişi** | Kim ne zaman ne verdi/aldı — `63`'teki log şeridinin yetki filtresi olabilir |
| 9 | **375px** | Matris mobilde tablo değildir; `02 Veri Gosterimi`'ndeki tablo→kart dönüşümü esas |

**Bağlayıcı:** `00 Tokenlar` token seti · `01 Form Elemanlari` kontrolleri · `02 Veri Gosterimi` tablo standardı · `04 Geri Bildirim` modal/drawer · `05 Navigasyon` · semantik renk (mavi asla sorun anlatmaz; yetki **alma** kritik tonda) · WCAG AA, dokunma hedefi ≥44px.

**Terminoloji (arayüz Türkçe):** Yetki · Kapsam (Kendi / Grubu / Tümü) · Grup · Seviye (Direktör / Grup Yöneticisi / Personel) · Görüntüleme / Ekleme / Düzenleme / Pasifleştirme / Yetki devri · Davet edildi / Aktif / Girişi kısıtlı / Dondurulmuş / Kapatılmış.
