# Review — Mevzuat dışı eğitim, marka ve belge seçenekleri planı (v1.1) — 2026-10-20

> **Review type:** plan-re-review
> **Previous review:** `docs/reviews/review-mevzuat-disi-egitim-plan-2026-10-20.md` (heyet 828, REJECTED, 7 bulgu)
> **Upstream document(s) read:** `proje-haritasi.md` «EGT-218 kararları — mevzuat dışı eğitimler ve marka» (Sets, 20.10.2026, güncel hâli — 6 madde; madde 6 heyet 828'in F-1 sorusuna cevap olarak eklendi)
> **Other cross-referenced documents:** `CLAUDE.md` (kırmızı çizgiler), kod: `app/Models/Regulation.php` (`fillable` — kurum adı alanı yok), `config/authorization.php` (`document_type.*` izin kalıbı), `app/Queries/Office/RequirementMap.php:149-156` (`group: regulation?->name`), `database/migrations/2026_08_14_000200_create_trainings.php:46-47` (`trainings.training_definition_id` FK — M-4b'nin kilit sorgusunun dayanacağı tablo), `database/migrations/2026_07_28_080000_create_settings.php` (admin-tanımlı ayar mekanizması), `app/Queries/Customer/SuggestedTrainings.php`, `app/Http/Controllers/Customer/QuoteController.php`, `app/Queries/Office/VisibleTrainings.php` (önceki turun «null-güvenli» saydığı diğer okuyucular — etiket amaçlı, gruplama değil, kontrol tekrarlandı)
> **Stage locks in effect:** Upstream kararlar (EGT-218, madde 1-6) locked.

---

## Upstream Coverage Matrix

| Upstream § / madde | Reviewed doc'ta durumu | Kanıt |
|---|---|---|
| Karar 1 — kategori; mevzuat eğitiminde mevzuat/bağlam zorunlu | ✓ Uyumlu | M-1, M-2 |
| Karar 6 — mevzuat dışı = mevzuatsız; mevzuat/ek mevzuat bağlanamaz; bakanlık akışı ve uyarılar hiç çalışmaz; evrak bağlanabilir | ✓ Uyumlu | M-2 iki yönlü CHECK + «ek mevzuat da bağlanamaz (eylem/form doğrulaması)»; M-4, M-11 bakanlık/uyarı akışını `regulatory`'ye kilitliyor; testler satır 61 evrak bağlanabilirliğini koruyor |
| Karar 2 — marka: backoffice tanımlı liste, katalog+teklif+belgede görünür | ✓ Uyumlu | M-6 + görev 4 |
| Karar 3 — belge verebilme isteğe bağlı, **düzenleyen tanımda seçilir** | ✓ Uyumlu | M-7 `certificate_issuer_kind` (seçimli tür) + `certificate_issuer_name`; `Regulation` modelinde kurum adı alanı olmadığı doğrulandı → `other`/`regulation_owner` için ad alanının gerekliliği tutarlı |
| Karar 5 — üretim iki yollu; `generated` + şablon ayrı ticket | ✓ Uyumlu | Plan satır 7, M-7 açıkça EGT-225'e bırakıyor, CHECK `none`/`issued_elsewhere` ile sınırlı |
| Heyet 828 F-1 (hibrit kayıt belirsizliği) | ✓ Uyumlu | M-2 iki yönlü CHECK kombinasyonu artık tek anlamlı |
| Heyet 828 F-2 (düzenleyen serbest metin) | ✓ Uyumlu | `certificate_issuer_kind` türü seçimli; M-8 kopyalama kuralı türe göre netleşti |
| Heyet 828 F-3 (`generated` tanımsızlığı) | ✓ Uyumlu | Kapsam dışına alındı, EGT-225 |
| Heyet 828 F-4 (kategori değişikliğine koruma yok) | ✓ Uyumlu | M-4b kilit; dayandığı sorgu (`trainings.training_definition_id` FK) koşulabilir doğrulandı |
| Heyet 828 F-5 (atlanmış okuyucu) | ✓ Uyumlu | M-10 üç liste; `RequirementMap.php:149-156`'daki `group: regulation?->name` kullanımı koda karşı doğrulandı, plan bunu kapsıyor |
| Heyet 828 F-6 (marka yetki yerleşimi yok) | ✓ Uyumlu | M-6 `BrandPolicy` + izin adları `config/authorization.php`'deki `document_type.*` kalıbıyla aynı biçimde tanımlanmış |
| Heyet 828 F-7 (test kapsamı eksik) | ✓ Uyumlu | Test listesi kilit, düzenleyen, marka yetkisi, M-9, M-11 senaryolarını içeriyor (satır 61-72) |
| Kırmızı çizgi 14 / AD-27 | ✓ Uyumlu | M-11 değişmedi; kategori/mod/düzenleyen/marka hâlâ tanım verisi |
| AD-11 / kopya ilkesi | ✓ Uyumlu | M-8 türe göre kopyalama netleşti |
| Migration güvenliği / rollback | ✓ Uyumlu | Değişmedi, `NOT NULL` geri dönüş riski hâlâ yazılı |

## ✅ What works

- Madde 6'nın getirdiği «mevzuat dışı = mevzuatsız» kararı M-2'de tam karşılığını buluyor: iki yönlü CHECK artık hibrit kaydı veritabanı seviyesinde imkânsız kılıyor, önceki turun temel belirsizliği (F-1) kapandı.
- M-7'nin `certificate_issuer_kind` türü, karar 3'ün «seçilsin» kelimesini artık gerçekten bir seçim olarak uyguluyor; `Regulation` modelinde kurum adı alanı olmadığı iddiası koddan doğrulandı (`fillable`'da yalnız `authority_reference`), bu nedenle `other`/`regulation_owner` için serbest ad alanı gerekliliği tutarlı bir mühendislik kararı.
- M-4b'nin kilit mekanizması (`trainings.training_definition_id` FK üzerinden «en az bir eğitimi var mı» sorgusu) koşulabilir bir tabloya dayanıyor; kilit canlı eğitimin bakanlık/KUMS yükümlülüğünün sessizce değişmesini önlüyor.
- M-10'un üçüncü listesi (`RequirementMap.php`) koda karşı doğrulandı — tam olarak `group: regulation?->name` satırını (149-156) hedefliyor, gerçek bir eksikti ve artık kapsanıyor.
- M-6'nın izin adlandırması (`brand.view/create/update/deactivate`) mevcut `document_type.*` kalıbıyla birebir örtüşüyor; AD-23'ün pasifleştirme ilkesi (`deactivate`, silme değil) korunmuş.
- Test listesi önceki turun yedi bulgusunun hepsine karşılık geliyor; her M kararının karşıtı bir senaryo var.

## ⚠️ Findings & Risks

**F-A (yeni) — `certificate_issuer_kind = 'brand'` için `brand_id` zorunluluğunun uygulama mekanizması veri modelinde tanımsız.** Veri modeli bölümü CHECK kurallarını açıkça sayıyor: *"`other` ve `regulation_owner` ⇒ ad dolu, `regulation_owner` ⇒ `regulatory`, `none` ⇒ tür boş"* — ama `brand` ⇒ `brand_id IS NOT NULL` kuralı bu listede yok. Oysa test listesi (satır 63) açıkça *"`brand` markası olmayan tanımda reddedilir"* diyor. `regulation_owner ⇒ regulatory` kuralı aynı satırda başka bir sütuna (kategori) bakan bir CHECK örneği olarak zaten var; aynı teknik `brand_id`'ye uygulanabilirken plan bunu atlıyor. Sonuç: test'in beklediği reddetme davranışının nerede (DB CHECK mi, form mu, eylem mi) uygulanacağı plan metninde belirsiz — "nasıl yapılacağı" sorusu plan seviyesinde açık kalan tek nokta.

## ❓ Open Questions

1. (F-A) `certificate_issuer_kind = 'brand'` iken `brand_id` boşsa reddetme hangi katmanda olacak — veri modeli bölümündeki CHECK listesine mi eklenecek, yoksa eylem/form doğrulaması olarak mı bırakılacak (M-2'nin ek mevzuat kısıtında yapıldığı gibi)?

## Previous Findings Status (re-review)

| Önceki bulgu | Durum |
|---|---|
| F-1 — hibrit kayıt belirsizliği | ✅ Resolved (M-2 iki yönlü CHECK, karar 6) |
| F-2 — düzenleyen serbest metin | ✅ Resolved (M-7 `certificate_issuer_kind`) |
| F-3 — `generated` tanımsızlığı | ✅ Resolved (EGT-225'e taşındı) |
| F-4 — kategori değişikliğine koruma yok | ✅ Resolved (M-4b kilit) |
| F-5 — atlanmış okuyucu (ofis planlama talebi) | ✅ Resolved (M-10 üç liste) |
| F-6 — marka yetki yerleşimi yok | ✅ Resolved (M-6 `BrandPolicy` + izinler) |
| F-7 — test kapsamı eksik | ✅ Resolved (test listesi genişledi) |

Düzeltmeler planın hedefinden sapmıyor; yeni bir problem (F-A) küçük ve izole — mevcut yedi bulgunun çözümünü geçersiz kılmıyor, yalnız M-7'nin kendi iç tutarlılığında bir boşluk.

## Verdict: ❌ REJECTED

Yedi önceki bulgunun yedisi de gerçek ve doğrulanabilir şekilde kapatılmış; ancak düzeltme sırasında M-7'nin veri modeli/CHECK tanımında yeni, izole bir tutarsızlık (F-A) ortaya çıktı — test listesinin vaat ettiği bir reddetme davranışının uygulama mekanizması plan metninde yok. Scope içinde tek bir bulgu da kalsa orta yol yok.
