# Kapsama matrisi — sözleşmeler ve onay kapısı (EGT-80)

*09.08.2026 · Tasarım: `design/18 Sozlesmeler.dc.html` (364 satır) · Uygulama: `Portal/{Contracts,LegalConsent}.vue`, `organisms/LegalVersionDiff.vue`, `Portal/QuoteShow.vue`*

Tasarım dosyası **implementasyondan sonra açıldı** ve baştan sona okundu (Tasarım Uygulama Protokolü §3); matris bellekten değil dosyadan üretildi. İşaret **kodun** durumunu söyler: ✓ var · ⚠ kısmen · ❌ yok · ⛔ bilinçli sapma.

---

## 0 · Başlık rozetleri — `18:27-31`

| # | Tasarım öğesi | Durum | Kanıt |
|---|---|---|---|
| 1 | ⛔ metin düzenleme yok | ✓ | Portal tarafında hiçbir ekran metin yazmıyor; yazma yalnız backoffice'te (`LegalTextResource`) |
| 2 | ⛔ PDF üretimi yok — yazdırma tarayıcının | ✓ | `Contracts.vue:90` `printPage()` → `window.print()`; PDF üreten kod yok |
| 3 | ⛔ ekranda imza atılmaz | ✓ | Onay = kutu + düğme; imza tuvali hiçbir yerde yok |

## 1 · Ekran A — Sözleşmeler · `18:36-169`

| # | Tasarım öğesi | Durum | Kanıt |
|---|---|---|---|
| 4 | Adres `/portal/sozlesmeler` | ⛔ | `/sozlesmeler` — panel kendi host'unun kökünde, `/portal` segmenti 03.08.2026'da kaldırıldı (`routes/panel.php` başlığı). Tasarımın adresi eski kurala göre yazılmış |
| 5 | Kırıntı `Panel / Sözleşmeler` | ✓ | `Contracts.vue:109` `:trail` |
| 6 | Başlık "Sözleşmeler ve bilgilendirmeler" | ✓ | `lang/tr/legal_consent.php:41` — tasarımcının kelimesi birebir |
| 7 | Alt başlık | ✓ | `legal_consent.php:42` |
| 8 | "1 belge onayınızı bekliyor →" şeridi | ✓ | `Contracts.vue:117-124`, sayı `outstanding` prop'undan, tıklayınca kapıya gidiyor |
| 9 | İki kolonlu ızgara (`1fr 420px`) | ✓ | `Contracts.vue:144-145` `lg:grid-cols-3` + `lg:col-span-2` (token ölçeğinde karşılığı; keyfi değer arch testiyle yasak) |

### A2 — Onayladıklarım · `18:50-83`

| # | Tasarım öğesi | Durum | Kanıt |
|---|---|---|---|
| 10 | Başlık + "onayladığınız sürüm ve tarih — hak dayanağınız" | ✓ | `Contracts.vue:132-133` |
| 11 | Kolon başlıkları BELGE · TÜR · ONAYIM | ✓ | `Contracts.vue:163-166`; 768px altında gizli, satır orada yığılıyor |
| 12 | Satır: ad + "Yeni sürüm var — onayınız bekleniyor" (amber) | ✓ | `Contracts.vue:149-153`, satır zemini `bg-warning-bg/40` `:146` |
| 13 | Tür rozeti | ✓ | `Contracts.vue:183-187`, etiket kaynağı satırın kendi sözlüğü (`kindLabel`, `:75`) |
| 14 | ONAYIM: `v1 · tarih` + `yürürlükte: v2` | ✓ | `Contracts.vue:190-205` |
| 15 | Eylem "Onayla →" | ✓ | `Contracts.vue:210-216` — kapıya götürüyor, ikinci bir onay kontrolü çizmiyor |
| 16 | Eylem "Görüntüle" | ✓ | `Contracts.vue:218-223` |
| 17 | Çerçeve sözleşme A2'de bir satır | ⛔ | **Sets, 06.08.2026:** "Uygulanacak olan yalnız A5'teki ayrı kart." `CustomerContracts.php:203` `where('key', '!=', FrameworkAgreement::KEY)` |
| 18 | Boş durum | ✓ | `Contracts.vue:153-156` `EmptyState` |

### A3 — Bilgilendirme metinleri · `18:86-110`

| # | Tasarım öğesi | Durum | Kanıt |
|---|---|---|---|
| 19 | Başlık + `ONAY İSTEMEZ` rozeti + ipucu | ✓ | `Contracts.vue:231-238` |
| 20 | Satır: ad + "yürürlük :date" + tür rozeti + Görüntüle | ✓ | `Contracts.vue:248-264` |
| 21 | ⛔ Bu blokta onay kutusu yok | ✓ | `CustomerContracts.php:70-74` — liste `acceptable = false` olanlardan üretiliyor; ekranda hiçbir kontrol yok |
| 22 | Alt not ("iki liste bilinçli olarak farklı") | ✓ | `Contracts.vue:268-270` |

### A4 — Geri çekilebilir rızalarım · `18:113-128`

| # | Tasarım öğesi | Durum | Kanıt |
|---|---|---|---|
| 23 | Başlık + "KVKK m.7 · yalnız açık rızalar" | ✓ | `Contracts.vue:277-278` |
| 24 | Satır: ad + "v2 · :date tarihinde verdiniz" | ✓ | `Contracts.vue:293-305` |
| 25 | Rozet `Verildi` / `Geri çekildi` | ✓ | `Contracts.vue:307-312` |
| 26 | Düğme `Rızamı Geri Çek` / `Yeniden Ver` | ✓ | `Contracts.vue:314-324` |
| 27 | Yalnız cevaplanmış rızalar listeleniyor | ✓ | `CustomerContracts.php:80-83` — verilmemiş bir rızanın "geri çekme" düğmesi arkasında hiçbir şey yok |

### A5 — Firma sözleşmesi kartı · `18:133-145`

| # | Tasarım öğesi | Durum | Kanıt |
|---|---|---|---|
| 28 | Kart + `YALNIZ YETKİLİ` rozeti (mor) | ✓ | `Contracts.vue:332-338`, `role-*` token üçlüsü (tasarımın #5D5488'i) |
| 29 | `YÜRÜRLÜKTE` rozeti + `v3 · tarih` | ✓ | `Contracts.vue:340-350` |
| 30 | Satır "Kabul eden" | ✓ | `Contracts.vue:353-356` |
| 31 | Satır "Yöntem" | ✓ | ✅ **EGT-81'de kapandı** — `customer_agreements.method`; kart artık "Portalda kabul edildi" ya da "Islak imzalı nüsha" diyor |
| 32 | Satır "Nüsha" | ✓ | ✅ **EGT-81'de kapandı** — kart nüshanın 3E'de saklı olduğunu yazıyor. ⚠ Müşterinin kendi kopyasını İNDİRMESİ hâlâ verilmiş bir karar değil (`docs/reviews/brief-a5b-kapsama.md` sonu) |
| 33 | Not: "Fesih ayrı bir süreçtir, buradan yapılmaz" | ✓ | `legal_consent.php:92`, `Contracts.vue:377-379` |
| 34 | Kabul edilmemiş hâl | ✓ | `Contracts.vue:369-375` — şerit, kapı değil; yetkisi olmayana "yetkili kimdir" cümlesi |

### A6 — Görüntüleyici · `18:148-164`

| # | Tasarım öğesi | Durum | Kanıt |
|---|---|---|---|
| 35 | Başlık + `v2 · yürürlük :date` | ✓ | `Contracts.vue:390-399` |
| 36 | "Yazdır" | ✓ | `Contracts.vue:401-405` |
| 37 | Kaydırılabilir gövde | ✓ | `Contracts.vue:411` `max-h-96 overflow-y-auto`, gövde `Markdown::toHtml` |
| 38 | "Kapat" | ✓ | `Contracts.vue:414-417` |
| 39 | Alt bilgi "yaklaşık 5.400 karakter" | ✓ | `Contracts.vue` `viewingLength` — işaretler sökülüp sayılıyor, başlıklarla dolu bir metin okunduğundan uzun görünmesin diye |
| 40 | Gövde altındaki solma (fade) | ✓ | `Contracts.vue` görüntüleyici — `pointer-events-none` ile, altındaki son satırın tıklamasını yutmasın diye |

## 2 · Ekran B — Onay kapısı · `18:173-228`

| # | Tasarım öğesi | Durum | Kanıt |
|---|---|---|---|
| 41 | ⛔ Menüsüz kabuk | ✓ | `resources/js/portal.js:31` — `Portal/LegalConsent` layout'tan muaf tutuldu |
| 42 | Logo + kişi · firma + "Çıkış yap" | ✓ | `LegalConsent.vue:94-112`; çıkış POST ile (`signOut`, `:71`) |
| 43 | Üstte okuma çubuğu | ✓ | `LegalConsent.vue:117-119`, oran `ScrollToAccept`'ten geliyor (`:120` `report()`) |
| 44 | "ONAYINIZ BEKLENİYOR · 1 / 3" | ✓ | `LegalConsent.vue` `position` / `total`; toplam **turun başında sabitlenir** (`LegalConsentController` `TOTAL` oturum anahtarı) — kalan sayısı üçüncü belgede "1 / 1" derdi |
| 45 | Tür rozeti | ✓ | `LegalConsent.vue:127-129` |
| 46 | "%74 okundu" | ✓ | `LegalConsent.vue:131-133` |
| 47 | Başlık + açıklama (bilgilendirici ton) | ✓ | `LegalConsent.vue:136-140`, `legal_consent.php:17` |
| 48 | "v1'i :date onaylamıştınız · 2 madde değişti" şeridi | ✓ | `LegalConsent.vue:145-164`; `previous` prop'u `LegalConsentController:118` |
| 49 | "v1'den farkları gör →" | ✓ | `LegalConsent.vue:156-163` — yalnız karşılaştırma **üretilebildiğinde** çiziliyor |
| 50 | Metin kartı | ✓ | `ScrollToAccept` (AD-14) |
| 51 | "Metnin sonuna kadar okundu — onay kutusu etkinleşti" | ✓ | `LegalConsent.vue:195-200` |
| 52 | Onay kutusu + cümle | ✓ | `LegalConsent.vue:202-210` |
| 53 | "Onayınız kaydınıza işlenir…" | ✓ | `LegalConsent.vue:213-215` |
| 54 | "Onayla ve Devam Et" | ✓ | `LegalConsent.vue:217-222` |
| 55 | "Sonraki: <ad> (2/3)" + Çıkış yap | ✓ | `LegalConsent.vue:225-236`; ad `LegalConsentController:82` `next` |

## 3 · Sürüm farkı deseni · `18:233-258`

| # | Tasarım öğesi | Durum | Kanıt |
|---|---|---|---|
| 56 | ⛔ Kalem tablosu değil, **madde bloğu** | ✓ | `LegalVersionDiff.vue:75-112`; karşılaştırma `Domain/Legal/ArticleDiff.php` |
| 57 | Başlık + `v1 → v2` şeridi + "2 madde değişti · 1 eklendi" | ✓ | `LegalVersionDiff.vue:59-72` |
| 58 | `DEĞİŞTİ` bloğu, iki kolon yan yana | ✓ | `LegalVersionDiff.vue:94-104` |
| 59 | `EKLENDİ` bloğu | ✓ | `ArticleDiff.php:56-62` + aynı şablon |
| 60 | `KALDIRILDI` — gri, üstü çizili | ✓ | `ArticleDiff.php:93-105`, `LegalVersionDiff.vue:107` `line-through` |
| 61 | Renk kodu: mor değişti · yeşil eklendi · gri kaldırıldı | ✓ | `LegalVersionDiff.vue:44-54` — `role-*` / `success-*` / `neutral-*` |
| 62 | Değişen **ibarenin** vurgusu (`<mark>`) | ✓ | `ArticleDiff::mark()` — kelime bazlı ortak alt dizi (LCS); ortadan eklenen cümle yalnız kendisini işaretler. `LegalVersionDiff.vue` `after_parts` |
| 63 | "Değişmeyen 7 madde gizli" | ✓ | `LegalVersionDiff.vue:117-127` |
| 64 | "Tüm metni göster" | ✓ | `LegalVersionDiff.vue:129-136` + `:140-146` tam gövde |
| 65 | ⛔ Yapı **saklanır**, düzyazıdan çıkarılmaz | ✓ | `legal_texts.articles` kolonu (migration `2026_10_06_000100`), backoffice'te repeater (`LegalTextResource`), yoksa `ArticleDiff` `null` döner |

## 4 · Rıza geri çekme — sonucu söyleyen onay · `18:262-287`

| # | Tasarım öğesi | Durum | Kanıt |
|---|---|---|---|
| 66 | Başlık "Rızanızı geri çekiyorsunuz" + belge adı | ✓ | `Contracts.vue:400-407` `ConfirmModal` |
| 67 | "Bundan sonra ne olacak" kutusu | ✓ | `Contracts.vue:412-431` |
| 68 | Üç madde, üç ayrı renk noktası | ✓ | `Contracts.vue:418-430` — yeşil/mavi/amber, tasarımın sırasıyla |
| 69 | "tarih ve saatle kaydınıza işlenir" notu | ✓ | `Contracts.vue:433-435` |
| 70 | Vazgeç · **Rızamı Geri Çek** (kırmızı) | ✓ | `Contracts.vue:404-406` `confirm-variant="destructive"` |
| 71 | ⛔ Kayıt silinmez, tarih yazılır | ✓ | `WithdrawCustomerLegalConsent.php:63` `withdrawn_at`; veritabanı silmeyi de reddediyor (`app.deny_consent_delete`) |

## 5 · Kenar hâller · `18:289-312`

| # | Tasarım öğesi | Durum | Kanıt |
|---|---|---|---|
| 72 | `YETKİLİ DEĞİL — KAPI ÇIKMAZ` şeridi | ✓ | `Contracts.vue:369-375` — çerçeve sözleşme kapı değil, şerit |
| 73 | `REDDETTİ` kartı (Çıkış Yap / Metne Dön) | ✓ | `LegalConsent.vue` `refusing` — "Onaylamak istemiyorum" şeridi açar; kayıt üretmez, ekranın hâlidir |
| 74 | `DAHA ÖNCE GERİ ÇEKİLMİŞ` şeridi | ✓ | `Portal/Participant/Panel.vue` — geri çekilmişse blok *"…tarihinde geri çekmiştiniz, kayıt zorunlu olduğu için yeniden istiyoruz"* diyerek çıkıyor (Sets, 09.08.2026) |
| 75 | `METİN YÜKLENEMEDİ — KİLİTLENME YOK` | ✓ | `LegalConsent.vue` `bodyMissing` — gövde boşsa onay kutusu açılmaz, "Tekrar Dene" çizilir |

## 6 · 375px · `18:319-343`

| # | Tasarım öğesi | Durum | Kanıt |
|---|---|---|---|
| 76 | Kapı birincil hâl, dar ekranda tam genişlik | ✓ | `LegalConsent.vue:121` `max-w-3xl` + `px-6` |
| 77 | Okuma çubuğu | ✓ | `LegalConsent.vue:117` |
| 78 | ⛔ İç kaydırma yok — metin sayfanın kendisi | ✓ | `ScrollToAccept.vue:158-176` — `md` altında pane'in kendi yüksekliği yok, ölçüm pencereden |
| 79 | Altta sabit onay şeridi | ✓ | `LegalConsent.vue:190-192` `fixed inset-x-0 bottom-0 … md:static` |
| 80 | Tam genişlik düğme | ✓ | Aynı blok; `md` altında şeridin içinde |
| 81 | Sabit şeridin altında kalan boşluk | ✓ | `LegalConsent.vue:226` `pb-40 md:pb-0` |

## 7 · AÇIK KARAR kutusu · `18:345-359`

| # | Tasarım öğesi | Durum | Kanıt |
|---|---|---|---|
| 82 | "Çerçeve sözleşme olmadan teklif onayı — **önerimiz: engellensin**" | ⛔ | **Sets, 09.08.2026: "kabul et ve devam et şeklinde olmak zorunda."** Tasarımın önerdiği pasif düğme + "yetkiliye hatırlat" şeridi uygulanmadı; yerine sözleşme teklif onayının İÇİNDE gösteriliyor (`QuoteShow.vue:300-343`) ve tek transaction'da iki kayıt düşüyor (`ApproveQuote.php:152-168`, `:183-190`) |

---

## Sonuç

82 öğenin **79'u karşılanıyor**, 3'ü bilinçli sapma (⛔). ⚠ Kısmi ya da eksik satır kalmadı.

⚠ **09.08.2026 akşamı güncellendi:** #31 ve #32 EGT-81'de kapandı, #74 video rızası bağlanınca. Kalan üç satırın üçü de kayıtlı karardır.

⛔ **İlk turda ❌/⚠ kalan altı öğe aynı gün yazıldı** *(Sets: "tasarımda var mı bunlar?" → beşi de çizilmişti)*. Kural zaten bunu söylüyordu: teslim edilen eksiksiz uygulanır, sapma yalnız Sets söylediğinde olur. Matrisin ilk hâli o altısını "soru" diye bıraktı; doğru davranış sormadan önce **tasarımda var mı** diye bakmaktı.

## Kalan sapmalar ve tek ⚠

| # | Ne | Neden |
|---|---|---|
| 4 | Adres `/portal/sozlesmeler` → `/sozlesmeler` | Panel kendi host'unun kökünde; `/portal` segmenti 03.08.2026'da kaldırıldı |
| 17 | Çerçeve sözleşme A2'de satır değil | Sets, 06.08.2026 — yalnız A5 kartı |
| 82 | "Engellensin" önerisi | Sets, 09.08.2026 — "kabul et ve devam et" |
