# Mevzuat dışı eğitim, marka ve belge seçenekleri — implementasyon planı

*v1.2 · 20.10.2026 · EGT-218 · heyet 828 (7 bulgu) ve 829 (1 bulgu) sonrası · Kararlar: `proje-haritasi.md` «EGT-218 kararları» (Sets, 20.10.2026) · Tetikleyen: Tayfun — WeNexus'un hazırladığı zorunlu olmayan eğitimler (ör. Sürdürülebilirlik) nasıl eklenecek ve teklif edilecek*

**Hedef:** Mevzuata bağlı olmayan bir eğitim tanımlanabilsin, satılabilsin, planlanabilsin, başlatılıp bitirilebilsin; içeriğin sahibi bir **marka** olarak görünsün; belge verilip verilmeyeceği ve kimin düzenlediği eğitim tanımında seçilsin.

**Bu planın dışında (EGT-225):** şablondan **yazdırılabilir belge üretimi** (karar 5) — şablon alanı, `generated` belge yolu, üretim ve yerleşim (tasarım brief'i `docs/design/katilim-belgesi-brief.md`). Bu plan `generated` yolunu **eklemez** (F-3); EGT-225 CHECK'i genişletir ve şablon alanını getirir. Bu planın verdiği düzenleyen türü (M-7) o ticket'ın okuyacağı sözleşmedir.

## Doğrulanmış mevcut durum (20.10.2026, koddan)

| Konu | Bugün | Kanıt |
|---|---|---|
| Eğitimin mevzuatı | Zorunlu: kolon `NOT NULL` + FK `restrictOnDelete`; backoffice formunda `required()` | `2026_08_02_000100_create_training_definitions.php:77,147`; `TrainingDefinitionForm.php:83-93` |
| Ek mevzuatlar | Ayrı pivot, ana mevzuattan bağımsız | `2026_10_11_000100_…:35-64` |
| Bakanlık bildirim türü / süresi | Zaten boş geçilebilir; süre okuyanların hepsi boşu atlıyor | `notification_type`, `notification_days` nullable; `OpenMinistryNotificationTasks.php:57-61` vb. |
| ⛔ Eğitimin durum makinesi | `Planned` → yalnız `MinistryNotified` / `MinistryApproved` → `InProgress`. Mevzuat dışı eğitim **başlatılamaz** | `app/Support/Trainings/TrainingStatus.php:34-41`; `StartTraining.php:31` |
| ⛔ Bitirme koşulu | Her katılımcı için bakanlık (KUMS) kanıtı zorunlu | `CompleteTraining.php:62`; `FinishTrainingRequest.php:25` (`required`) |
| Sınav | Sınavsız eğitimde sonuç puansız kaydedilir (tasarım gereği, hata değil); sınav kâğıdı yalnız `exam_required` ise istenir | `RecordExamResult.php`; `CompleteTraining.php:124` |
| Belge | Sistem belge **üretmez**; bakanlığın verdiği belgeyi kaydeder (`certificate_records`: numara, tarih, geçerlilik). Düzenleyen alanı yok | `CertificateRecord.php`, `RecordCertificate.php` docblock'ları |
| Plan ekranı mevzuat kartları | Mevzuat kartı seçilince ana mevzuatı olmayan tanım gizlenir; «mevzuat dışı» kartı yok | `TrainingDefinitionOptions.php:41-52`; `Office/Trainings/Plan.vue:308-330` |
| Mevzuat kartı sayıları | Tanım sayısı `groupBy('regulation_id')` — boş mevzuat hiçbir karta sayılmaz | `RegulationOptions.php:53-64` |
| Portal firma profili ilgi alanları | Mevzuata göre gruplanır; boş mevzuat başlıksız grup olur | `CompanyProfile.php:102-120`; `Portal/CompanyProfile.vue:295-296` |
| Sistem hazırlığı | Yenileme süresi olmayan aktif tanımı «eksik iş» sayar | `SystemReadiness.php:186-205` |
| Uyum hesabı | Yalnız belge kayıtlarından; belgesi olmayan eğitim uyumu etkilemez | `ComplianceSummary.php:78-108`, `StaffCompliance.php:378-450` |
| Diğer okuyucular | `regulation?->name` ile null-güvenli: `VisibleTrainings`, `RequirementMap`, `TrainingRequestController`, `Customer/QuoteController`, `SuggestedTrainings`, `PlanTraining::currentRegulationVersion` (boşta sürüm dondurulmaz) | ilgili dosyalar |

## Kararlar (teknik)

| # | Karar | Gerekçe |
|---|---|---|
| M-1 | `training_definitions.category` — `regulatory` / `non_regulatory` (string + CHECK), mevcut satırlar `regulatory`. | Sets: «seçenek değil kategori». Kategori eğitimin ne olduğunu söyler; zorunluluklar ondan okunur. |
| M-2 | `regulation_id` **nullable** olur; CHECK iki yönlü: `(category = 'regulatory' AND regulation_id IS NOT NULL) OR (category = 'non_regulatory' AND regulation_id IS NULL)`. Mevzuat dışı tanıma **ek mevzuat** (pivot) ve mevzuata bağlı müfredat da bağlanamaz (eylem/form doğrulaması). Form: kategori mevzuat dışıysa mevzuat, ek mevzuat, bakanlık bildirim alanları ve rehber paneli gizlenir; evrak (müşteri belgesi beklentisi) bölümü iki kategoride de açık. | Sets kararı 6: mevzuat dışı = mevzuatsız (heyet 828 F-1). Ara durum olmaz; M-3/M-4/M-11 tek anlamlı kalır. |
| M-3 | `RegulationOptions` ve plan ekranına **«Mevzuat dışı eğitimler» kartı**; kart seçilince yalnız `non_regulatory` tanımlar listelenir, sayısı doğru sayılır. `TrainingDefinitionOptions` boş mevzuatı `0` değil `null` gönderir. | Bugün mevzuat kartı seçilince bu tanımlar görünmez oluyor. |
| M-4 | **Durum makinesi:** mevzuat dışı eğitimde `Planned` → `InProgress` doğrudan (bakanlık adımı yok); mevzuat eğitiminde akış değişmez. Bakanlık bildirim görevleri ve hatırlatmaları mevzuat dışı eğitimde açılmaz. Kural tanımın kategorisinden okunur. | Bugün başlatılamaz. |
| M-4b | **Kategori kilidi:** tanımın en az bir eğitimi varsa (iptal edilmiş ya da vazgeçilmiş olanlar dahil) kategori değiştirilemez — eylem reddeder, form alanı kilitli ve sebebi yazar. | Heyet 828 F-4: kategori canlı okunduğu için, değişirse yürüyen eğitimin bakanlık/KUMS yükümlülüğü sessizce değişirdi. Kilit, eğitime kopya kolonundan basit ve geçmişi de korur (biten eğitimin dayanağı değişmez). |
| M-5 | **Bitirme:** KUMS kanıtı yalnız mevzuat eğitiminde istenir; `FinishTrainingRequest` alanı kategoriye göre `required`/`nullable`. | Bugün sahte kanıt girmeden bitirilemez. |
| M-6 | **Marka:** `brands` tablosu (ad, isteğe bağlı kısa ad, aktif) — backoffice'te kaynak, yetkisi diğer tanım tablolarının kalıbında: `BrandPolicy` + `brand.view` / `brand.create` / `brand.update` / `brand.deactivate` izinleri `config/authorization.php` backoffice listesine, etiketleri lang'e (heyet 828 F-6); `training_definitions.brand_id` nullable FK. Görünür: ofis ve portal kataloglarında eğitim adının yanında, teklif belgesinde/çıktısında kalemin altında, belge üretiminde (ayrı ticket). Faturada **görünmez** (karar: katalog + teklif + belge). | Sets: «brand gibi kurgulayalım». |
| M-7 | **Belge seçenekleri tanımda** (iki kategoride de, Sets): `certificate_mode` — `none` (belge yok) · `issued_elsewhere` («dışarıda hazırlanır», yalnız numara/tarih/geçerlilik kaydı — bugünkü akış); `generated` EGT-225'in işi (F-3). **Düzenleyen bir tür olarak seçilir** (F-2): `certificate_issuer_kind` — `regulation_owner` (mevzuatın sahibi; yalnız mevzuat eğitiminde) · `institution` (3E) · `brand` (tanımın markası; marka seçiliyse) · `other`; `certificate_issuer_name` `regulation_owner` ve `other`'da zorunlu (ör. «T.C. Ulaştırma ve Altyapı Bakanlığı», akredite kuruluş) — mevzuat kaydında kurum adı alanı yok (`Regulation` yalnız `authority_reference` taşır). Mevcut tanımlar `issued_elsewhere` + düzenleyen **boş** (ad bilinmiyor; yönetici girene kadar belge kaydı düzenleyensiz yazılır — bugünkü hâl); CHECK yalnız tür seçildiğinde ad ister. `none`'da düzenleyen alanları boş. | Sets: belge her iki kategoride isteğe bağlı; düzenleyen tanımda seçilir; yüklenen şablon varsa sistem üretir, yoksa yalnız gereklilikler tutulur. |
| M-8 | `certificate_mode = none` olan eğitimde «belge kaydet» adımı sunulmaz; bitirme koşulu belgeyi zaten istemiyor. Belge kaydı düzenleyenin o anki **adını** kopyalar (`certificate_records.issuer`: mevzuatın sahibi ve diğer → girilen ad, 3E → varsayılan 3E şirketinin unvanı, marka → marka adı). | Kayıt sonradan değişen tanıma bağlı kalmasın (fatura kopyası ilkesi). |
| M-9 | Mevzuat dışı tanımda **yenileme süresi zorunlu değil**: `SystemReadiness` yalnız `regulatory` + belge veren tanımlarda arar. | Yenileme mevzuattan gelir. |
| M-10 | Mevzuata göre gruplanan **her** liste mevzuatsız tanımı «Mevzuat dışı eğitimler» başlığı altında toplar: portal firma profili ilgi alanları (`CompanyProfile.php:102-120`), ofis planlama talebi eğitim seçimi (`TrainingRequestController.php:122-131` → `Office/Requests/Create.vue:85`, heyet 828 F-5), eğitmen eğitebilir listesi (`RequirementMap.php:149-156`). | Başlıksız ya da `null` grup basılıyor. |
| M-11 | Mevzuat uyarıları, bakanlık bildirimi, ek mevzuat zinciri yalnız `regulatory` tanımda hesaplanır; mevzuat dışında boş döner (hata vermez). | Kırmızı çizgi 14 değişmez: sayılar yine tanımın admin alanları. |

## Veri modeli (yalnız ekleme + bir gevşetme)

- `training_definitions`: `category` (string, default `regulatory`, CHECK), `brand_id` (nullable FK `brands`), `certificate_mode` (string, default `issued_elsewhere`, CHECK `none`/`issued_elsewhere`), `certificate_issuer_kind` (nullable string, CHECK), `certificate_issuer_name` (nullable string), CHECK: `other` ve `regulation_owner` ⇒ ad dolu, `brand` ⇒ `brand_id IS NOT NULL` (heyet 829 F-A; form da aynı kuralı alan hatası olarak söyler, CHECK son savunma), `regulation_owner` ⇒ `regulatory`, `none` ⇒ tür boş; `regulation_id` → nullable + iki yönlü CHECK (M-2). ⚠ `regulation_id`'in nullable yapılması kolon tipini değiştirmez, veri kaybı yok; geri dönüşte mevzuatsız satır varsa `NOT NULL` geri konamaz — rollback'e bakınız.
- `brands`: `id`, `name` (unique), `short_name` nullable, `is_active`, zaman damgaları; denetim izi (model audit).
- `certificate_records.issuer` nullable string (M-8).

## Görevler

1. Migration + modeller (`TrainingDefinition`, `Brand`, `CertificateRecord`) + backoffice: marka kaynağı (`BrandPolicy`, izinler); tanım formunda kategori (en üstte, eğitimi varsa kilitli — M-4b), mevzuat alanlarının kategoriye göre görünürlüğü ve zorunluluğu, marka seçimi, belge bölümü (mod + düzenleyen türü + ad); tablo sütunu/filtresi.
2. Durum makinesi ve başlatma (M-4), bakanlık görevleri/hatırlatmaları (M-4), bitirme (M-5), belge kaydı (M-8).
3. Plan ekranı kartı ve sayıları (M-3), `TrainingDefinitionOptions` null; mevzuata göre gruplanan üç liste (M-10); `SystemReadiness` (M-9); uyarı/zincir okuyucuları (M-11).
4. Marka görünürlüğü (M-6): ofis katalogları (plan, teklif kalemi seçimi), portal teklif isteği ve açık eğitimler, `QuoteDocument` ve teklif çıktısı kalem satırı.
5. Yardım (backoffice eğitim tanımı yok; ofis: plan ekranı ve teklif; portal: teklif isteği), changelog, harita.
6. Kapsama: etkilenen ekranlar tasarımda yok (kart ve rozet ekleri) — Sets kararıyla eklenir; tasarım dosyasına karşı matris yalnız plan ekranı (kart) ve teklif çıktısı (marka satırı) için.

## Testler

- Kategori: mevzuatsız `regulatory` tanım reddedilir (form + CHECK); `non_regulatory` mevzuatsız kaydedilir, mevzuatlı kaydedilemez, ek mevzuat bağlanamaz; evrak (müşteri belgesi beklentisi) bağlanabilir.
- Kategori kilidi: eğitimi olan tanımın kategorisi değiştirilemez (eylem reddeder); eğitimi olmayanınki değişir.
- Düzenleyen: `other` ve `regulation_owner` adsız reddedilir; `regulation_owner` mevzuat dışında reddedilir; `brand` markası olmayan tanımda reddedilir.
- Marka kaynağı: izni olmayan backoffice kullanıcısı göremez/yazamaz.
- Durum: mevzuat dışı eğitim `Planned`'dan doğrudan başlar, bakanlık görevi açılmaz; mevzuat eğitimi bugünkü gibi başlayamaz.
- Bitirme: mevzuat dışında KUMS kanıtsız biter; mevzuat eğitiminde kanıt yine zorunlu.
- Belge: `none` → belge kaydı reddedilir/sunulmaz; `issued_elsewhere` → kayıt düzenleyeni kopyalar; tanımın düzenleyeni sonra değişse kayıt değişmez.
- Plan ekranı: «Mevzuat dışı» kartı doğru sayar ve süzer; mevzuat kartı seçiliyken mevzuat dışı tanım görünmez (bugünkü davranış, artık bilinçli).
- Marka: teklif belgesinde ve portal kataloğunda görünür, faturada görünmez.
- Gruplama: portal firma profili, ofis planlama talebi ve eğitmen eğitebilir listesinde mevzuatsız tanım «Mevzuat dışı eğitimler» başlığı altında.
- Sistem hazırlığı (M-9): yenileme süresi olmayan mevzuat dışı tanım ya da belge vermeyen tanım «eksik» sayılmaz; mevzuat eğitiminde sayılmaya devam eder.
- Uyarı/zincir (M-11): mevzuat dışı tanım için uyarı, bildirim süresi ve zincir okuyucuları hatasız boş döner; plan ekranında mevzuat dışı tanımla eğitim planlanabilir.
- Mevcut testler (planlama, bakanlık, bitirme, belge) değişmeden geçer.

## Rollout

Mevcut tanımlar `regulatory` + `issued_elsewhere` olur; davranış değişmez. Backoffice'te WeNexus markası ve ilk mevzuat dışı tanım yönetici tarafından açılır (veri girişi, kod değil).

## Rollback

`git revert` + migration `down`: yeni kolonlar ve `brands` düşer. ⚠ O ana kadar mevzuatsız tanım girildiyse `regulation_id NOT NULL` geri konamaz — `down` bu durumda durur ve hangi tanımların mevzuatsız olduğunu yazar; karar Sets'indir (tanımı pasifleştirmek ya da bir mevzuata bağlamak). Veri silinmez.

## Kapsam dışı

Şablondan yazdırılabilir belge üretimi ve şablon yüklemesi (ayrı ticket, tasarım brief'i ile); marka logosu; faturada marka; mevzuat dışı eğitimin uyum (compliance) hesabına katılması — belgesi olmayan eğitim uyumu etkilemez (bugünkü kural).
