# Tasarım 41 — Eğitmen Saha · kapsama matrisi

*(01.08.2026 · `design/41 Egitmen Saha.dc.html` yeniden açılarak üretildi; bellekten değil)*

Kaynak dosya üç blok taşıyor: **eğitmen eğitim detayı** (satır 29–76), **eğitim günü desktop + 375px** (78–207), **masraf girişi drawer + 375px** (209–271).

## Blok 1 · Eğitim detayı (`/egitmen/egitimler/{training}`)

| Tasarım öğesi (satır) | ✓/⚠/❌ | Kanıt |
|---|---|---|
| Başlık: eğitim adı + "Bakanlık Onaylı" rozeti + referans kodu çipi (36–38) | ✓ | `Training.vue:60-77` — `h1`, `StatusBadge`, mono çip |
| Tek satır özet: tarih · saat · gün · katılımcı (kontenjan) (40) | ⚠ | `Training.vue:79-89` — tarih + katılımcı/kontenjan var; **saat ve gün sayısı yok** (oturum saatleri gün ekranında) |
| Ücret satırı (40) | ✓ | Tasarım revize edildi: satır **"ücret ve maliyet bu ekranda görünmez — alacağınız Cari Durumum'da"** oldu. Ekranda da öyle yazıyor (`room.no_money_here`) |
| "Eğitim Günü Ekranı →" butonu (42) | ✓ | `Training.vue:84-86` |
| 3 kolonlu ızgara `1fr 1fr 1.2fr` (44) | ✓ | `Training.vue:95` `lg:grid-cols-16` + span 5/5/6 |
| Yer kartı: harita alanı (46) | ✓ | `Training.vue:121-131` — `trainings.map_url` doluysa gömülü harita, boşsa açık adres + yol tarifi *(Sets, 01.08.2026)*. Gömme yalnız tanınan sağlayıcılara (`Training.vue:52-70`) |
| Yer kartı: ad + adres + irtibat (48–49) | ⚠ | Ad (il) ve adres var; irtibat telefonu **bilinçli kapsam dışı** *(Sets, 01.08.2026: talep gelirse)* |
| "Yol tarifi" / "Konaklama: Otel Marina" bağlantıları (50) | ✓ | Yol tarifi `Training.vue:105`; konaklama planlamanın masraf satırından `Training.vue:111-115` |
| "Uçak + araç kiralama planlamada işli" notu (51) | ✓ | Aynı masraf satırları; satır yoksa `Training.vue:117-119` |
| Katılımcılar kartı: ad + firma · görev, "salt okunur" (55–62) | ✓ | `Training.vue:122-149` |
| "Liste eğitim gününe kadar değişebilir" notu (62) | ✓ | `Training.vue:147` → `instructor_panel.room.roster_note` |
| Dokümanlar kartı + "otomatik bağlandı" rozeti (65) | ✓ | `Training.vue:152-160` |
| "ekleme/güncelleme admin ve operasyon yöneticisinde" (66) | ✓ | `Training.vue:162`; yazma yolu yalnız Filament `MaterialsRelationManager` |
| PPT/PDF ikon + başlık + sürüm + sayfa sayısı (68–71) | ✓ | `Training.vue:164-197` |
| "yalnız eğitmen görür · filigranlı" (70) | ✓ | `Training.vue:183-190`; sunucu tarafı `ReadTrainingMaterial.php:60-90` |
| "Yoklama listesi şablonu (imzalı) · eğitim günü yazdırılır" (71) | ✓ | `kind = register_template` (`2026_09_13_000200:63`), aynı listede |

## Blok 2 · Eğitim günü (`/egitmen/egitimler/{training}/gun`)

| Tasarım öğesi (satır) | ✓/⚠/❌ | Kanıt |
|---|---|---|
| Başlık + "Devam Ediyor · 2. oturum" rozeti (86–87) | ✓ | `TrainingDay.vue` — o an süren oturum rozete yazılır (`nowAt`) |
| **Gün çipleri** (revizyon) | ✓ | `TrainingDay.vue` — "1. gün · 27.07", kapanan yeşil ✓, kısa gün "yarım" |
| İmzalı liste kartında **gün rozeti** (revizyon) | ✓ | `sheet_day` rozeti + "her gün ayrı liste" notu |
| "İki ayrı kapı" açıklaması (revizyon) | ✓ | `day.handover_note` |
| Tarih · saat · salon · katılımcı · KUMS kodu (89) | ✓ | `TrainingDay.vue` — saat aralığı günün ilk/son oturumundan (`hours`) |
| "Yoklama Listesi İndir (PDF)" butonu (91) | ✓ | Şablon, materyal kartından iner (`register_template`, blok 1) |
| Izgara `1fr 320px` (93) | ✓ | `TrainingDay.vue:182` `lg:grid-cols-3` + `lg:col-span-2` |
| Oturum bazlı devam tablosu, oturum başına kolon (96–102) | ✓ | `TrainingDay.vue:194-215` |
| "işaretler zaman damgalıdır" (95) | ✓ | `TrainingDay.vue:188-190`; `MarkAttendance.php:47-52` her geçişte damgalar |
| Katılımcı altında firma + "beyan ✓ 09:02" (105) | ✓ | `TrainingDay.vue` `declaredAt()`; veri `TrainingRoster.declared_at` |
| Gelmeyen satırın kırmızı zemini (110) | ✓ | `TrainingDay.vue:220` (`no_show` satırı) |
| ✓ / ✕ / boş kare üçlü işaret (106–108) | ✓ | `atoms/AttendanceMark.vue` — üç durum, boş kare "kimse bakmadı" |
| Alt satır "18 katılımcıdan 3'ü · 16 salonda" + "Tümü →" (124) | ✓ *(21.10.2026, EGT-254)* `in_room` sayacı; «Tümü» yok — liste zaten tam | ~~⚠~~ | `TrainingDay.vue:249-256` — girilen/beklenen işaret sayacı var; **salondaki sayısı ve "Tümü" yok** (liste zaten tam) |
| İmzalı yoklama kartı, dashed alan (127–136) | ✓ | `TrainingDay.vue:260-289` + `FileDrop` |
| "yüklenmeden eğitim Tamamlandı olamaz" (131) | ✓ | Gün kapanışının kapısı: `DayReadiness::REGISTER_MISSING`, `CloseTrainingDay.php:84-88` |
| "Dosya Seç" + "Kamera (mobil)" (133–134) | ✓ | `FileDrop.vue` `camera` prop'u (bu turda eklendi) |
| Sınav notları kartı + "3. oturum sonrası" (139) | ✓ *(21.10.2026, EGT-254)* `scores_after` | ~~⚠~~ | `TrainingDay.vue:292-330` — kart var; **"3. oturum sonrası" ibaresi yok** |
| Not kutusu + Geçti/Kaldı (143–149) | ✓ | `atoms/ScoreInput.vue` |
| Gelmeyene kilitli boş kutu (152–154) | ✓ | `TrainingDay.vue:56-58` — salonda işaretlenmeyene kutu çizilmiyor |
| "Geçme notu 70 (admin tanımlı)" (157) | ✓ | `TrainingDay.vue:325-327`; değer `min_pass_score` (`TrainingDayState.php:150`) |
| "Tüm notları gir (16 eksik) →" (158) | ✓ | Liste zaten tam; eksik sayısı teslim kartında (`check_scores`) |
| Gün sonu kontrol listesi ✓/!/✕ (161–167) | ✓ | `TrainingDay.vue:334-360` |
| "Günü Kapat" butonu, koşul sağlanmadan disabled (168) | ✓ | `TrainingDay.vue:376-380`; aynı liste `CloseTrainingDay.php` reddinde |
| **"Eğitimi Tamamla"** ayrı butonu | ✓ | Tasarımda yok — *Sets, 01.08.2026 kararı*. `TrainingDay.vue:391-441`, `DeliverTraining.php` |
| 375px: başlık + oturum ilerleme çubuğu (178–182) | ✓ | `TrainingDay.vue` — ilerleme çubuğu her genişlikte; biten oturumlar dolu |
| 375px: büyük dokunmatik işaret (189–197) | ✓ | `AttendanceMark` `large` prop'u |
| 375px: "İmzalı Listeyi Çek ve Yükle" (201) | ✓ | Aynı `FileDrop` + kamera |
| "Fotoğraf netlik kontrolünden geçer" (202) | ✓ | `lib/sharpness.js` + `FileDrop` — tarayıcıda Laplacian varyansı, eşik `business.upload.sharpness_threshold`. **Uyarır, engellemez** |

## Blok 3 · Masraf girişi (`/egitmen/masraflarim`)

Bu blok **bu turdan önce** yazılmıştı (`Expenses.vue`, 30.07.2026). Bu turda yalnız kamera kapısı eklendi.

| Tasarım öğesi (satır) | ✓/⚠/❌ | Kanıt |
|---|---|---|
| Drawer başlığı + "fiş/fatura fotoğrafı zorunlu" (221) | ✓ | `Expenses.vue` — `receiptRequired` config'ten |
| Bağlı eğitim seçimi (225) | ✓ | `InstructorPanelController::expenses` → `trainings` |
| Tür çipleri (227) | ✓ | `OptionList::EXPENSE_KIND` |
| Tutar + "yakıt üst limiti ₺2.500 (admin)" (228) | ✓ | `limit` prop'u; **gösterilir, zorlamaz** (K-19) |
| Fiş fotoğrafı + "＋ ikinci fiş ekle / kamera" (233–234) | ✓ | `FileDrop` `multiple` + `camera` |
| "bulanık fiş otomatik uyarı üretir" (236) | ✓ | Aynı kontrol; fiş adıyla birlikte amber uyarı. ⛔ **OCR yok** *(Sets, 01.08.2026)*: fiş tek tip değil — fatura, A4, çakmak boyu slip, belediye otoparkının kendi formatı; tutarlı çıkarım üretilemez |
| "Onaylayan: planlama yöneticisi · sonuç bildirimi düşer" (241) | ✓ | Onay kuyruğu (`ApprovalQueue`) + `instructor.expense_decided` bildirimi |

## Açık uçlar — kapandı *(Sets, 01.08.2026)*

Matristeki beş soru cevaplandı:

1. **Eğitmen ücreti detay ekranında** → **hayır.** Ücret ve maliyet alanları yalnız planlama aşamasında ve yetki sahibinde görünür. Eğitmen kendi alacağını `Cari Durumum`'dan görür.
2. **Netlik/bulanıklık kontrolü** → **yalnız netlik kontrolü kondu**, OCR yok. Fiş tek tip olmadığı için (fatura / A4 / çakmak boyu / belediye otoparkı formatı, kalemler her birinde farklı) tutarlı çıkarım üretilemez. Netlik ölçümü tarayıcıda yapılır — sunucuya sıfır yük, yükleme öncesi, ve **engellemez**: eşik heuristiktir, soluk termal fiş gerçekten düşük kontrastlıdır.
3. **İrtibat telefonu** → şimdilik gerek yok; talep gelirse.
4. **Harita** → **konsun.** Planlamacı pin (konum URL'i) girer; girmezse açık adres gösterilir. `trainings.map_url`.
5. **Oturum ibaresi, saat aralığı, beyan saati, ilerleme çubuğu** → eklendi. Ayrıca **oturumlar artık otomatik üretiliyor**: eğitim tanımının saatleri ÷ günlük azami saat (TY-2019 md.17/1 · 8 saat, admin alanı) = gün sayısı; `session_hours` doluysa gün o kadar oturuma bölünür.
