# Review — Ofis Ön Yüzü ve Kimlik Yüzeyi Spec v1.1 — 2026-07-28

> **Review type:** spec-review
> **Previous review:** N/A (ilk review)
> **Upstream document(s) read:** `docs/specs/omurga-spec.md` (§3, §3.0.2, §4, §5.1–5.5, §6, §7.5, §14, §15) · `docs/plans/omurga-plan.md` (chunk5 §5.7, §5.8, §5.9; chunk6 §6.5.1, §6.9 kriter 2f; devir kuralları :2446; kapsam dışı :2461; kriter sicili) · `design/HANDOFF.md` · `docs/arch/kod-yerlesimi.md` (§3, §4) · `docs/arch/mimari-kararlar.md` (AD-07, AD-08, AD-09, AD-19, AD-23, AD-25, AD-26, AD-27) · `CLAUDE.md`
> **Other cross-referenced documents:** `docs/issues.md` (passkey kaydı, geçmiş kapanışlar) · `current_todo.md` (§7/1 "kısıtla" sorusu, §7 uzlaştırılacak farklar) · `docs/design/tasarim-brief.md` (:25, :57) · kod doğrulamaları: `routes/office.php`, `config/security.php`, `config/passkeys.php`, `app/Support/Auth/AuthMethod.php`, `app/Support/Authorization/PermissionFamilies.php`, `app/Http/Middleware/RequireStrongAuth.php`, `app/Queries/Office/OfficeNavigation.php`, `bootstrap/app.php`, `database/migrations/0001_01_01_000000_create_users_table.php`, `package.json`, `composer.json`, `design/10 Ortak Auth.dc.html` (mockup cümlesi grep ile doğrulandı)
> **Stage locks in effect:** Omurga spec APPROVED + omurga plan APPROVED (kilitli). Bu spec'in §7'de önerdiği üst belge revizyonları kilit ihlali değildir — açıkça listelenmiş, Sets onaylı revizyon talepleridir; review bunların **kapsamının doğruluğunu** değerlendirir.

---

## Upstream Coverage Matrix

| Upstream § / madde | Reviewed doc'ta durumu | Kanıt |
|---|---|---|
| omurga-spec §5.1 — dört yöntem, yöntem–alan eşlemesi admin-ayarlı, kodda sabit eşleme yok (AD-08) | ✓ | spec §5.1: dördü ofiste açılır, `config/security.php:13` tohum varsayılan, kalıcı ayar admin panelinde |
| omurga-spec §5.2 — ofiste MFA **yetki bazlı**, alan bazlı zorunluluk yalnız backoffice | ✓ | spec karar 6, §5.3; kod doğrulandı: `config/security.php:33-38` (`user.assign_permissions` listede), `PermissionFamilies.php:94, 228-235` (izni iptal etmez, etkisizleştirir) |
| omurga-spec §5.2 — `10 Ortak Auth` "ofis hesaplarında zorunludur" çelişkisi | ✓ | mockup cümlesi dosyada mevcut (grep doğrulandı); spec karar 6 HANDOFF'un kendi çelişki kuralıyla ("çelişkide AD'ler/spec esastır", `HANDOFF.md:10`) geçersiz sayıyor — doğru okuma |
| omurga-spec §5.2 v1.16 — şifre adımı ayrı modal (e-posta/şifre değişimi, passkey ekleme/silme, 2FA kurma/kapatma) | ✓ | spec §5.3, T1 Profil-güvenlik |
| omurga-spec §5.2 — "kapı buton yokluğuyla kurulmaz" | ✓ | spec §5.3 son paragraf |
| omurga-spec §5.2 — ikinci faktörü olmayanın karşılaşacağı davranış (şifre yolunda "2FA kurulum ekranına düşer" deseni) | ⚠ | Magic link yolunda tanımsız — bkz. **F-4** |
| omurga-spec §5.3 — magic link tek kullanımlık, süreli, hash'li | ✓ | mevcut backend (chunk5 kriter 12); spec T3 ekranları bunun üstüne oturuyor |
| omurga-spec §5.3 — **her** magic link oturumunda ek kimlik teyidi zorunlu ve kapatılamaz | ❌ | Ofis akışında karşılığı yok: T3 ekran envanterinde (spec §6) teyit ekranı yok, teyidin ofiste hangi bilgiyi soracağı tanımsız — bkz. **F-3** |
| omurga-spec §5.3 — "magic link panel yetkisini açmaz" → ofis için daraltma (karar 7) | ⚠ | Daraltmanın kendisi gerekçeli ve §5.2 v1.15'in "e-posta girişi **(ya da magic link)** + 2FA" oturum modeliyle tutarlı; ancak revizyon kapsamı eksik — §5.5 ve §14 kriter 25 dokunulmadan çelişik kalır, bkz. **F-2** |
| omurga-spec §5.4 A-1 — hız sınırı, eşik ve kilit süresi admin-tanımlı | ✓ | spec §8.1 "kısıtla"yı doğru şekilde A-1'e bağlıyor; `config/security.php:66-69` tohum değerler (spec §15 madde 4 açık — biliniyor) |
| omurga-spec §5.4 A-2 — aktif oturumlar görülür ve sonlandırılır | ✓ | T1 Profil-güvenlik "aktif oturumlar"; backend `routes/office.php:37-39` |
| omurga-spec §5.4 A-5 / AD-23 — kullanıcı silinmez, pasifleştirilir; elle yaptırım dondur + kapat | ✓ | spec §8.1; `office.users.destroy` rotasının davranışı zaten chunk6'da pasifleştirme |
| omurga-spec §3.0.2 P-1/P-2 — "yetki bekleyen kullanıcınız var" uyarısı hesap **statüsünden** hesaplanır | ❌ | Ofis Kullanıcılar ekranı bu turda yazılıyor (T2) ama uyarı ne kapsamda ne adresli; kod tabanında da izi yok (tarama boş döndü) — bkz. **F-6** |
| omurga-spec §6 Y-5 / plan chunk6 kriter 2f — menü filtreli **ve** URL ile erişilemez, çift kapı | ✓ | spec §4.2 uyarısı + kriter 3 iki iddiayı ayrı ayrı istiyor; `OfficeNavigation.php` ikinci hat olduğunu kendisi yazıyor |
| omurga-spec §7.5 L-2 — sistem günlüğü ofiste yalnız ofis personelinin olayları, maskeli | ✓ | spec T2 "append-only, filtreli, maskeli değerler"; feed sınıfı (`OfficeAuditFeed`) `current_todo`'daki bilinçli orphan'ın tüketicisi olarak kapanıyor |
| omurga-plan chunk5 §5.8 — alan tespiti tek yerde (`ResolveIdentityDomain`), üç yerde ayrı host kontrolü yok | ✓ | Karar 4 bununla **çelişmiyor** — farklı eksen: §5.8 kimlik alanı/guard/oturum çözümünü tekler, karar 4 **sunum kabuğunu** route grubundan seçer; gerekçesi de doğru (`/panel` ile `/katilimci` aynı `customer` alanı, farklı kabuk — kimlik alanı kabuğu belirlemeye yetmez). Root view'ın yalnız iskelet + derleme girişi söylediği açıkça sabitlenmiş |
| omurga-plan chunk6 §6.5.1 — ofis kullanıcı yönetimi + sistem logu omurganın kendi ofis modülleri | ✓ | spec T2 tam bu iki yüzeyin ekranını yazıyor; `routes/office.php:55-66` uçlar hazır |
| omurga-plan devir kuralları (:2446) + kapsam dışı (:2461) — omurga iş ekranı üretmez, ofis ekranları sonraki tur | ✓ | spec §1 devri doğru üstleniyor |
| kod-yerlesimi §3 — atomic hiyerarşi, sayfa iş mantığı barındırmaz, üç seviye prop sınırı, token dışı yasak | ✓ | spec §4.4 birebir; panel başına derleme girişi kuralı §7'de revizyon olarak listeli (karar 5) |
| kod-yerlesimi §4 — "token'lar tek CSS değişken kaynağından hem Vue hem Filament'e" → daraltma (karar 8) | ⚠ | Daraltma gerekçeli ve §7'de listeli; ancak **aynı kural AD-25'te de yazılı** (`mimari-kararlar.md:373`) ve AD-25 revizyon tablosunda yok — bkz. **F-1** |
| AD-07 — çoklu yöntem, admin-ayarlı; magic link katılım kanıtı olamaz | ✓ | spec §5.1; kanıt sınırına dokunulmuyor |
| AD-08 / AD-27 — iş kuralı hardcode edilmez | ✓ | Yöntem–alan eşlemesi tohum + admin ayarı; spec yeni sabit kural getirmiyor |
| AD-09 — ofis panelleri Inertia + Vue, backoffice Filament | ✓ | spec §4.1, karar 8 |
| AD-26 — grup sözlüğü değişmez, test disiplini | ✓ | karar 10: ofis omurga ekranları `omurga` grubunda — mevcut ofis rota testleriyle tutarlı |
| HANDOFF bağlayıcı: token seti | ✓ | spec §4.3 `00 Tokenlar`'ın tamamını birebir listeliyor; kriter 2 token dışı değeri arch testiyle yasaklıyor |
| HANDOFF bağlayıcı: erişilebilirlik + responsive (WCAG, ≥44px, focus ring, 375px) | ✓ | kriter 7 ve 8 |
| HANDOFF bağlayıcı kural 10 — "Dondur/kısıtla gerekçeli" | ⚠ | §8.1 "kısıtı kaldır audit'lenir" diyor; dondur/kapat için **gerekçe zorunluluğu** spec'te yok — bkz. **F-7** |
| HANDOFF/63 — kullanıcı detayı (kokpit + kişinin logları), Onaylar | ⚠ | Kokpit ve Onaylar adresli şekilde kapsam dışı (✓); ama T2 hızlı aksiyonlarında "detay" duruyor ve içeriği tanımsız — bkz. **F-5** |
| CLAUDE.md dil kuralı | ✓ / ⚠ | spec §4.4 kuralı taşıyor; kriter 4'ün kanıt mekanizması iddiayı tam kanıtlamıyor — bkz. **F-8** |
| docs/issues.md — "Passkey — üç kimlik alanı, tek authenticatable model" | ✓ | spec §5.2 kaydı doğru okuyor (`config/passkeys.php` `BackofficeUser`'a bağlı — kod doğrulandı); §7'de T3'e adresleniyor |
| current_todo.md §7/1 — "kısıtla" açık sorusu | ✓ | spec §8.1 soruyu "sorulacak, varsayılmayacak" talimatına uygun biçimde Sets kararıyla kapatıyor |
| Karar 9 / §8.3 — tasarımda karşılığı olmayan iki ekleme | ✓ | İkisi de mevcut desenlerden türetilmiş (müşteri giriş kartındaki "VEYA" ayıracı, `04 Geri Bildirim` banner'ı), gerekçeli ve onaylı; yeni bileşen icat edilmiyor |
| Kabul kriterleri ölçülebilirliği (§9) | ⚠ | 1, 2 (ham hex yarısı), 3, 5, 6, 9 ölçülebilir; 7 ve 8 elle denetimle ölçülebilir; **4 ve 10'un kanıt yolu kanıtlamıyor** — bkz. **F-8**, **F-9** |

---

## ✅ What works

- **Karar 6 doğru okumadır ve kanıtı sağlamdır.** Omurga-spec §5.2 alan bazlı zorunluluğu açıkça yalnız backoffice'e verir; `10 Ortak Auth` mockup'ındaki cümle HANDOFF'un kendi hiyerarşisi gereği geçersizdir. Somut sonuç kodda birebir doğrulandı: izin listede, `requiresMfaAndLacksIt()` iptal etmiyor, etkisizleştiriyor; kriter 5 de "izin kaydı silinmiyor" diye bunu ayrıca sabitliyor.
- **Karar 7'nin çekirdeği omurga-spec'in kendi oturum modeliyle tutarlı.** §5.2 v1.15 zaten *"e-posta + şifre (ya da magic link) ile giriliyorsa 2FA zorunludur"* diyerek magic link + ikinci faktörü geçerli bir oturum tamamlama yolu sayıyordu; karar 7 bu modeli ofis panel erişimine taşıyor ve "paylaşılan bağlantının sahibi ikinci faktörü veremez" gerekçesi teknik olarak doğru. Müşteri/katılımcı tarafının aynen korunması da doğru sınır. (Kapsam eksiği için F-2, F-3.)
- **Karar 4, plan chunk5 §5.8 ile çelişmiyor.** §5.8'in yasakladığı şey kimlik alanı/guard çözümünün dağılmasıdır; karar 4 sunum kabuğunu route grubundan seçiyor ve kimlik çözümüne dokunmuyor. `/panel` ↔ `/katilimci` örneği (aynı kimlik alanı, farklı kabuk) kimlik alanının kabuk seçimine yetmediğini kanıtlıyor — eksen ayrımı doğru kurulmuş.
- **Karar 5 gerekçeli ve revizyonu adresli.** Katılımcı profili brief'ten doğru alıntılanmış (`tasarim-brief.md:25` doğrulandı); çok girişli Vite build'inde ortak modüllerin paylaşılan chunk'a düşmesi doğru varsayım; kural kod-yerlesimi §3'e revizyon olarak yazılıyor.
- **Karar 3 kapsam kayması değil.** Reddedilen paketin build-time modeli, backoffice'e planlanan çeviri paneliyle (chunk 10 kalan kalemler) yapısal olarak uyumsuz — gerekçe gerçek. İnce `t()` dar tutulmuş, bedeli (elle grup bildirimi, ham anahtar görünürlüğü) saklanmadan yazılmış.
- **§8.1 ayrımı doğru kurulmuş.** "Girişi kısıtlı" rozeti A-1'in ürettiği geçici durumdur; elle yaptırımın dondur + kapat ile sınırlanması AD-23/A-5 ile tutarlı; "kısıtı kaldır"ın tek yönlü tutulup audit'lenmesi doğru. `current_todo.md` §7/1'in "sorulacak, varsayılmayacak" talimatı usulünce kapatılmış.
- **§5.2 passkey maliyeti dürüst yazılmış.** "Altyapı kurulu, entegre et" kolaycılığına düşülmemiş; `config/passkeys.php`'nin tek-model kısıtı ve RP id host bağı kod ve `docs/issues.md` kaydıyla birebir örtüşüyor.
- **Kapsam dışı tablosu büyük ölçüde adresli.** Kokpit, Onaylar, bildirim merkezi, landing, Filament-token — hepsi gerekçe + adres taşıyor; T2/T3 devirleri de adresli. Kriter 2f'nin çift kapısı (menü + URL) spec'e doğru taşınmış.
- **Bilinçli orphan kapanıyor.** `OfficeAuditFeed`'in `current_todo.md`'de kayıtlı erteleme şartı ("ekran gelince kapanır") T2 sistem günlüğü ekranıyla karşılanıyor.

## ⚠️ Findings & Risks (in-scope for this review type)

**F-1 — Karar 8'in revizyon kapsamı eksik: AD-25 listede yok.** "Design token'ları **tek CSS değişken kaynağından** her iki tarafa beslenir" kuralı yalnız `kod-yerlesimi.md` §4'te değil, **AD-25'in kendisinde de** yazılı (`docs/arch/mimari-kararlar.md:373`). §7 tablosu yalnız kod-yerlesimi §4'ü revize ediyor; karar 8 uygulandığında AD-25 spec'le çelişik kalır. Spec'in kendi ilkesi ("hiçbiri örtük bırakılmaz", onay kuralı 6) tam bu durumu yasaklıyor.

**F-2 — Karar 7'nin revizyon kapsamı eksik: omurga-spec §5.5 ve §14 kriter 25 dokunulmuyor.** §5.5 kabul kriteri *"magic link oturumunun panel ekranlarını açmadığı gösterilir"* ve §14 kriter 25 aynı davranışı genel ifadeyle sabitliyor. §5.3 ofis için daraltıldığında bu iki nokta niteleyici almadan yanlışlanır: ofiste ikinci faktör kanıtlanmış magic link oturumu panel ekranlarını **açar**. §7 tablosu yalnız §5.3'ü sayıyor.

**F-3 — Ofis magic link akışında zorunlu ek kimlik teyidi adımı tanımsız.** Omurga-spec §5.3: *"Magic link ile açılan **her** oturumda ek kimlik teyidi adımı zorunludur ve kapatılamaz."* Bu madde karar 7'nin daraltması dışında kalıyor ve aynen yürürlükte; ama (a) T3 ekran envanterinde (§6) teyit ekranı yok — yalnız "iste / gönderildi / süresi doldu", (b) teyidin ofis kullanıcısına hangi bilgiyi soracağı tanımsız: bugünkü tek ayar `national_id_last_four` (`config/security.php:49`) ve ofis `users` tablosunda `national_id` kolonu yok (`0001_01_01_000000_create_users_table.php` — migration doğrulandı), (c) eğer niyet "ofiste teyit adımının yerini ikinci faktör kanıtı alır" ise bu da §5.3'e dokunan ayrı bir revizyon maddesidir ve §7 tablosunda yer almalıdır.

**F-4 — Edge case tanımsız: ikinci faktörü hiç kurulmamış ofis kullanıcısı magic link ile girerse ne olur?** Kriter 9 panel ekranlarının kapalı kaldığını söylüyor ama çıkış yolunu tanımlamıyor. Omurga-spec §5.2 şifre yolunda deseni tanımlar (*"2FA kurulum ekranına düşer"*); karar 6 ofiste kurulumun *"teklif edildiğini, dayatılmadığını"* söyler. Magic link oturumu bu ikisinin arasında boşta: kullanıcı kuruluma mı düşer, uyarı bandıyla kilitli bir kabukta mı kalır, yoksa oturum hiç mi tamamlanmaz — spec söylemiyor.

**F-5 — T2 "detay" aksiyonu ile §2'nin kokpit dışlaması arasındaki yüzey tanımsız.** T2 hızlı aksiyonları "detay" içeriyor; §2 ise `63`'ün kullanıcı detay kokpitini kapsam dışı bırakıyor. "Detay"ın bu turda açtığı ekranın içeriği hiçbir yerde tanımlı değil. `63`'ün kullanıcı detayı ayrıca "kişinin loglarını" içeriyor (`HANDOFF.md:41`) — o parçanın bu turdaki durumu da yazılmamış. Sessiz daralma (detay boş kalır) veya sessiz genişleme (detay kokpite doğru büyür) iki yönde de mümkün; spec'in kendi karar 9'u sessiz çıkarmayı da sapma sayıyor.

**F-6 — "Yetki bekleyen kullanıcınız var" uyarısı (omurga-spec §3.0.2 P-1/P-2) ne kapsamda ne adresli.** Uyarı hesabın statüsünden hesaplanır ve yöneticinin ekranına düşer; doğal yüzeyi tam olarak bu turda yazılan Kullanıcılar ekranıdır (T2). Spec bahsetmiyor, kapsam dışı tablosunda da yok; kod tabanında da karşılığı yok (tarama boş döndü). Bu turda yazılmayacaksa adresli erteleme gerekir — adressiz hâli bulgudur.

**F-7 — Dondur/kapat aksiyonlarında gerekçe zorunluluğu yazılmamış.** HANDOFF bağlayıcı kural 10: *"Dondur/kısıtla gerekçeli"*; `04 Geri Bildirim`'in destructive modal deseni de gerekçe alanı taşır. Spec §8.1 yalnız "kısıtı kaldır"ın audit'lendiğini söylüyor; T2'nin dondur/kapat aksiyonları için gerekçe şartı spec'te yok.

**F-8 — Kriter 4'ün kanıt mekanizması iddiayı kanıtlamıyor.** Kriter *"kullanıcıya görünen hiçbir metin Vue dosyasına gömülü değil"* diyor; kanıtı *"Türkçe karakter taraması"*. Diakritik taşımayan Türkçe metin ("Durum", "Profil", "Rapor", "Ad") taramadan geçer — kriter yeşilken ihlal yaşayabilir. Ölçüm ile iddia arasındaki boşluk spec'te ya kapatılmalı ya da bilinen sınır olarak yazılmalıdır.

**F-9 — Kriter 10'un kanıt yolu, projenin kendi kaydıyla çelişiyor.** Kriter *"ofis passkey'i backoffice'te çalışmıyor (test — T3)"* diyor; oysa proje kaydı passkey **töreninin** testle kanıtlanamadığını söylüyor (`current_todo.md` — "Passkey töreninin kendisi testle kanıtlanmaz", `FakePasskeyCeremony`). Kriterin hangi yarısının yapısal testle (ayrı tablo, ayrı model, RP id değeri), hangi yarısının gerçek cihaz doğrulamasıyla kanıtlanacağı ayrıştırılmadan kriter bu haliyle kanıtlanamaz.

**F-10 — "Ofiste dört yöntem açılır" kararının kaynağı tutarsız atfedilmiş.** §7'de iki satır (config değişikliği, passkey kaydının T3'e adreslenmesi) ve §8.3'ün ilk satırı bu kararı "karar 7"ye bağlıyor; oysa karar 7 yalnız magic link güçlü-oturum kuralını tanımlıyor — passkey'e ve "dördü de açılır" kararına dair tek kelime içermiyor. Spec'in kendi ilkesiyle (*"bir kararın nedeni kaybolduğunda karar bir sonraki turda yeniden tartışılır"*, §3 girişi) çelişen bir izlenebilirlik boşluğu: dört-yöntem kararının dayanağı §5.1'in genel tanımına dağılmış durumda, adlandırılmış bir karar değil.

## ❓ Open Questions (to be answered before next stage)

1. **Müşteri portalı satırının adresi "kendi turu"** — §2'deki diğer satırlar belge/ticket adı taşırken bu satır taşımıyor. Bir spec/ticket adına bağlanacak mı?
2. **Kriter 7 ve 8'in kanıtı** (375px akış bütünlüğü, focus ring / dokunma hedefi) elle denetim mi, Playwright mı? Karar 10 ikisini de zorunlu kılmıyor — kriterlerin kapanışını kim, hangi yolla gösterecek?
3. **Karar 7 plan aşamasına indiğinde** omurga-plan kriter sicili satır 25 ve chunk6 kriter 7c'nin ofis bacağı da güncellenecek — bu spec'in işi değil ama adresinin bir yerde (örn. §7 tablosunda plan satırı olarak) kayda geçmesi beklenir mi? (F-2 ile birlikte cevaplanabilir.)

## Verdict: ❌ REJECTED

Matrix'te üç ❌ (F-3, F-6 ve F-1'in AD-25 bacağı) ve altı ⚠ satır var; on bulgu açık. Belgenin omurgası sağlam — dokuz kararın sekizi upstream'le doğrulanabilir biçimde tutarlı, üst belge revizyon mekanizması doğru kurulmuş, kod durumu iddialarının tamamı depoda birebir doğrulandı — ancak iki revizyonun kapsamı eksik bırakılmış (AD-25, §5.5/§14-25), ofis magic link akışının kapatılamaz teyit adımı tanımsız ve T2'nin iki yüzey boşluğu (detay ekranı, yetki-bekliyor uyarısı) sessiz kalmış. Bulgular çözülüp re-review talep edilmelidir.
