# Review — docs/plans/egitim-belgesi-plan.md v1.1 — 2026-10-20

> **Review type:** plan-re-review
> **Previous review:** `docs/reviews/review-egitim-belgesi-plan-2026-10-20.md` (heyet 834, REJECTED, 6 bulgu)
> **Upstream document(s) read:** `design/52 Egitim Belgesi.dc.html` (tamamı), `docs/design/katilim-belgesi-brief.md`, `proje-haritasi.md` «EGT-218 kararları» madde 5, «EGT-225 belge içeriği», «EGT-225 tasarım 52 kararları» 1–5
> **Other cross-referenced documents:** `CLAUDE.md` (17 kırmızı çizgi), kod doğrulaması: `app/Domain/Invoicing/InvoiceNumber.php` (`PREFIX` regex), `app/Actions/Trainings/CompleteTraining.php`, `app/Actions/Trainings/RecordExamResult.php` (yeniden sınav/attempt mantığı), `app/Actions/Trainings/RecordCertificate.php`, `database/migrations/2026_09_17_000100_create_document_templates.php`, `database/migrations/2026_11_01_000400_3e_companies_issue_the_invoices.php` (document_templates'ın gerçek `COALESCE(issuing_company_id,0)` indeksleri), `database/migrations/2026_10_02_000100_a_person_may_hold_more_than_one_certificate.php`
> **Stage locks in effect:** Tasarım 52 + Sets kararları (harita) locked

---

## Upstream Coverage Matrix (sıfırdan üretildi)

| Upstream § / madde | Reviewed doc'ta durumu | Kanıt |
|---|---|---|
| Harita k.5 (EGT-218): düzenleyen 3E/marka + şablon yüklenirse sistem üretir | ✓ | B-1, B-5 |
| EGT-225 belge içeriği: kimlik no açık, numara sistem verir/düzenleyen başına sıralı/boşluksuz | ✓ | B-2, B-9, B-6 |
| Tasarım 52 k.1: ayrı seri öneki, fatura serisinden bağımsız (ör. WNX, 3EA) | ✓ | B-2 artık tam 3 karakter alfanümerik (`^[A-Z0-9]{3}$`), `InvoiceNumber::PREFIX` ile doğrulandı (`InvoiceNumber.php:21`) — WNX ve 3EA ikisi de uyar |
| Tasarım 52 k.2: doğrulama panel adresinde, giriş zorunlu | ✓ | B-8 (değişmedi, zaten uyumluydu) |
| Tasarım 52 k.3: PNG/tek sayfa PDF, canlıya poppler-utils | ✓ | B-4 (değişmedi) |
| Tasarım 52 k.4: yeni izin, düzeltmede yeni numara/eski geçersiz | ✓ | B-13, B-6 (indeks artık `status='valid'` ile daraltılmış, düzeltme ikinci satırı engellemiyor) |
| Tasarım Ekran 1: şablon sürümleme, «yeni sürüm eskisini değiştirmez» | ✓ | B-3 — mevcut iki indeksin gerçek anahtarı (`kind, COALESCE(issuing_company_id,0), version` / aynı `WHERE is_current`) doğru tarif edilmiş (`2026_11_01_000400:152-155` ile birebir), `WHERE kind <> 'certificate_template'` ile daraltılıp tanım-başına iki yeni kısmi indeks + CHECK ekleniyor — teknik olarak tutarlı |
| Brief §2.3: üç yüzey (ofis, portal firma, **katılımcının kendi ekranı**) | ✓ | B-11 artık üçünü de sayıyor, test satırı «katılımcı yalnız kendi belgesini» |
| Tasarım 3a dipnotu: «sınav notu girilince üretilir» = yeniden sınav da dahil | ✓ | B-5 üç tetikleyici; `RecordExamResult.php:140-166`'daki attempt/retake mantığıyla (son deneme kararı, geçmiş = final) tutarlı; test satırı «tamamlandıktan sonra yeniden sınavı geçince üretilir» |
| AD-06/kırmızı çizgi 13: üretimin audit kaydı | ✓ | B-12b, aynı işlemde `AuditWriter`, test satırı «her üretim denetim kaydı yazar» |
| **Veri modeli bölümü — B-2'nin öneki ile tutarlılık** | ❌ | satır 43 hâlâ eski `CHECK ^[A-Z]{2,4}$` taşıyor; B-2 (satır 26) `^[A-Z0-9]{3}$` diyor → **F-7 (yeni)** |
| **Görevler §3 — GenerateCertificate'ın üçüncü çağıranı** | ❌ | satır 56 yalnız «`CompleteTraining`'den ve şablon yüklemesinden çağrılır» der; B-5'in üçüncü tetikleyicisi `RecordExamResult` görev listesine hiç girmemiş → **F-8 (yeni)** |
| Diğer tüm B-maddeleri, veri modeli satırları 44-50, testler, rollout/rollback, kapsam dışı | ✓ | v1.0'dan değişmedi, önceki review'da zaten uyumlu bulunmuştu, bu turda yeniden okundu ve regresyon yok |

---

## ✅ What works

- **Altı bulgunun beşi tam, teknik olarak doğru çözülmüş.** F-1 (`InvoiceNumber::PREFIX` ile birebir hizalanmış öneki), F-2 (`status='valid'` ile daraltılmış kısmi indeks), F-4 (üçüncü tetikleyici, `RecordExamResult`'ın gerçek attempt/retake davranışıyla tutarlı), F-5 (katılımcının kendi ekranı B-11'e girmiş), F-6 (B-12b audit kaydı) — hepsi kodda doğrulanan gerçek mekanizmalarla eşleşiyor, yüzeysel değil.
- **F-3'ün çözümü özellikle dikkatli:** plan, `document_templates` üzerindeki gerçek indeks anahtarını (`kind, COALESCE(issuing_company_id,0), version`) doğru tarif ediyor — bu detay yalnız `2026_11_01_000400` migration'ını okuyarak elde edilebilir, v1.0'daki kaba tarif değil. Daraltma + iki yeni kısmi indeks + CHECK kombinasyonu teknik olarak çalışır.
- **Testler gerçekten genişlemiş**, her çözüme karşılık gelen bir senaryo eklenmiş (önek uzunluğu, şablon indeksi, yeniden sınav üretimi, denetim kaydı, düzeltme sonrası ikinci geçerli belge reddi).

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

**F-7 (yeni) — Veri modeli bölümü B-2'nin düzeltilmiş öneki ile çelişiyor.** Satır 43 hâlâ `CHECK \`^[A-Z]{2,4}\`` yazıyor; B-2 (satır 26) heyet 834 F-1'i çözerken öneki tam 3 karakter alfanümeriğe (`^[A-Z0-9]{3}$`) sabitlemişti. Aynı dokümanda aynı kolon için iki farklı CHECK ifadesi duruyor — migration'ı yazacak geliştirici hangisini uygulayacağını plandan çıkaramaz.

**F-8 (yeni) — Görevler §3, B-5'in üçüncü tetikleyicisini kaybetmiş.** B-5 düzeltmesi `GenerateCertificate`'ı üç çağırandan (CompleteTraining, RecordExamResult, şablon yükleme) tetikletir; Görevler bölümü satır 56 hâlâ yalnız ikisini sayar: «`CompleteTraining`'den ve şablon yüklemesinden çağrılır». Bu, F-4'ün çözümünün task breakdown'a sızmadığı anlamına gelir — tam da plan'ın "wire taraması" ilkesinin (kapanış adresi yazılı mı) denetlediği türden bir eksik: karar var, iş kalemi yok.

## ❓ Open Questions (carried over, still open)

1. Katılımcı/`/katilimci` oturumu `/dogrula`ya erişir mi — B-8 hâlâ yalnız «müşteri oturumu» diyor, netleşmemiş.
2. «Bulunamadı» sorgusunun erişim kaydı hangi kiracıya yazılır — B-8'de hâlâ belirsiz.
3. İki tablo arasında (marka × şirket) önek çakışması hâlâ yalnız form doğrulamasıyla engelleniyor; yeni test («marka ile şirket aynı öneki alamaz») eklenmiş ama DB düzeyinde çapraz-tablo garanti yok — bilinçli kabul mü?

## Previous Findings Status

- F-1: ✅ Resolved
- F-2: ✅ Resolved
- F-3: ✅ Resolved
- F-4: ✅ Resolved
- F-5: ✅ Resolved
- F-6: ✅ Resolved

## Verdict: ❌ REJECTED

Altı önceki bulgunun hepsi gerçek ve doğru çözülmüş — bu önemli bir ilerleme. Ancak düzeltme sürecinin kendisi iki yeni iç tutarsızlık üretti: B-2'nin yeni öneki "Veri modeli" bölümüne yansımamış (F-7) ve B-5'in üçüncü tetikleyicisi "Görevler" bölümüne yansımamış (F-8). İkisi de aynı kökten geliyor — karar satırı (B-maddeleri) düzeltildi, dokümanın geri kalanındaki tekrarı güncellenmedi. Scope içinde bulgu var, REJECTED.
