# Rol × ekran erişim matrisi — ofis paneli

**Tarih:** 03.08.2026 · **Suite:** `tests/Browser/role-access.spec.js` · **Çıktı:** `storage/tour/role-access.json`
**Yöntem:** yedi izin paketinin her biriyle **gerçekten giriş yapılıp** 27 adreslenebilir ofis ekranı ziyaret edildi. Ölçülen şey HTTP durumu ve inilen adres.

⚠ **Sağlık turundan farkı:** tur *"bu ekran çalışıyor mu"* diye sorar, bu matris *"bu kişinin burada işi var mı"* diye. İkisi bağımsız — bir ekran kusursuz çalışıp orada işi olmayan birine açık olabilir.

## Tek iddia, gerisi rapor

⛔ **Operasyon direktörü her ekrana girebilmeli** *(Sets: "süper user")*. Suite yalnız bunu assert eder; giremediği bir sayfa ya verilmemiş bir izindir ya da kimsenin ulaşamadığı bir ekran — ikisi de hatadır.

⚠ Diğer paketler için matris **rapordur, iddia değildir.** Planlamacının neyi görüp görmeyeceği chunk6'da ve izin matrisinde kayıtlı bir karardır; burada assert etmek, yetki modelini ölçmek yerine bu dosyanın uydurması olurdu. Matris Sets'e gider; şaşırtan satır bulguya dönüşür.

## Özet

| Paket | Açık | 403 |
|---|---|---|
| Operasyon direktörü | **27** | 0 |
| Satış yöneticisi | 21 | 6 |
| Muhasebe | 19 | 8 |
| Satışçı | 18 | 9 |
| Planlamacı | 16 | 11 |
| Operasyon — başlangıç | 15 | 12 |
| Eğitmen | 7 | 20 |

## Bu matrisin bulduğu üç 500 ⬛ DÜZELTİLDİ

Direktörle gezen sağlık turunun **göremeyeceği** cinsten — üçü de yalnız dar kapsamlı paketlerde çıkıyordu:

| Ekran | Kim | Sebep |
|---|---|---|
| `/yonetim` | Operasyon (personel), Eğitmen | `OperationsAgenda` ambient kapsamla çalışıyor; bu kişilerin **erişebildiği müşteri yok** ve `TenantContext::run()` boş kapsamı reddediyor |
| `/satis/teklifler/yeni` | Satışçı | Müşteri seçicisi aynı şekilde patlıyordu |
| `/satis/planlama-talepleri/yeni` | Satışçı | Aynı |

⛔ **Boş erişim bir hata değil, bir haldir.** `TenantContext::run()`'ın boş kapsamı reddetmesi doğru: çoğu çağıran için "hiçbir şey", kimliğin hiçbir şeye çözülmesi demektir ve kapsamsız sorgu bu katmanın önlemek için var olduğu sızıntıdır. Ama bazı kişiler gerçekten kimseye erişmez — henüz ataması olmayan operasyon personeli, eğitmen, ilk gününde bir satışçı. Onların ekranı **boş liste** çizmeli, 500 değil.

`TenantContext::reachIsEmpty()` eklendi ve üç çağrı yerinde kullanıldı. Adı sorusunu söylüyor: *"bakılacak bir şey var mı"* — *"bakabilir miyim"* değil.

## Matris

Sütunlar: **Dir**ektör · **Ops** (operasyon personeli) · **Muh**asebe · **SatY** (satış yöneticisi) · **Sat**ışçı · **Plan**lamacı · **Eğt**men
✅ 200 · ⛔ 403

| Ekran | Dir | Ops | Muh | SatY | Sat | Plan | Eğt |
|---|---|---|---|---|---|---|---|
| `/` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| `/bildirimler` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| `/egitimler` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ⛔ |
| `/egitimler/yeni` | ✅ | ⛔ | ⛔ | ⛔ | ⛔ | ✅ | ⛔ |
| `/gorevlerim` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| `/kullanicilar` | ✅ | ✅ | ⛔ | ✅ | ⛔ | ⛔ | ⛔ |
| `/muhasebe` | ✅ | ⛔ | ✅ | ⛔ | ⛔ | ⛔ | ⛔ |
| `/muhasebe/faturalar` | ✅ | ⛔ | ✅ | ⛔ | ⛔ | ⛔ | ⛔ |
| `/musteriler` | ✅ | ⛔ | ✅ | ✅ | ⛔ | ✅ | ⛔ |
| `/onaylar` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| `/planlama` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ⛔ |
| `/planlama/sorgulama` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ⛔ |
| `/planlama/takvim` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ⛔ |
| `/planlama/talepler` | ✅ | ⛔ | ⛔ | ✅ | ✅ | ✅ | ⛔ |
| `/profil/guvenlik` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| `/profil/guvenlik/ikinci-faktor` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| `/satis` | ✅ | ⛔ | ✅ | ✅ | ✅ | ⛔ | ⛔ |
| `/satis/paketler` | ✅ | ⛔ | ✅ | ✅ | ✅ | ⛔ | ⛔ |
| `/satis/planlama-talepleri/yeni` | ✅ | ⛔ | ⛔ | ✅ | ✅ | ⛔ | ⛔ |
| `/satis/takvimim` | ✅ | ⛔ | ✅ | ✅ | ✅ | ⛔ | ⛔ |
| `/satis/teklifler` | ✅ | ⛔ | ✅ | ✅ | ✅ | ⛔ | ⛔ |
| `/satis/teklifler/yeni` | ✅ | ⛔ | ⛔ | ✅ | ✅ | ⛔ | ⛔ |
| `/sistem-gunlugu` | ✅ | ✅ | ⛔ | ⛔ | ⛔ | ⛔ | ⛔ |
| `/tedarikciler` | ✅ | ⛔ | ⛔ | ⛔ | ⛔ | ✅ | ⛔ |
| `/yonetim` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| `/yonetim/anketler` | ✅ | ✅ | ✅ | ⛔ | ⛔ | ✅ | ⛔ |
| `/yonetim/satiscilar` | ✅ | ✅ | ⛔ | ✅ | ⛔ | ⛔ | ⛔ |
## Matriste ölçülmeyenler ve neden

**Eğitmenin kendi ekranları (`/egitmen/*`) dışarıda.** Onlar izinle değil **o kişi olmakla** açılır — bir kişinin kendi kaydı. Oradaki 404 *"eğitmen değilsin"* demektir ve yetki bulgusu gibi okunurdu.

**Parametreli detay ekranları dışarıda.** `OpaqueId` yüzünden adres kurulamıyor; detay erişimi listeden tıklanarak ölçülür ve o sağlık turunun işi.

**Dosya ve JSON uçları dışarıda.** Ekran değiller.

## Okurken dikkat edilecek iki normal satır

- `/` her pakette ✅ ama **inilen adres farklı**: satış paketleri `/satis`'e, planlamacı `/planlama`'ya, eğitmen `/egitmen`'e düşüyor. Bu `RoleLanding` — tasarım gereği.
- `/profil/guvenlik/ikinci-faktor` her pakette `/profil/guvenlik`'e dönüyor: ikinci faktör kurulumu şifre penceresi ister, pencere açılmadan ekran kendini göstermez (spec §5.2).
