# Birleşik Tasarım Ortamı Implementation Plan

> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.

**Goal:** Sablon editörü + widget editörü → tek birleşik `fiko-tasarim-editoru` component'i; ISablon genişletilir, IWidget kaldırılır.

**Architecture:** ISablon interface'i IWidget alanlarını absorbe eder. 6 alt component'li yeni editör (orchestrator + palet + canvas + kod + stil + veri). Sablon-renderer genişletilerek widget-renderer kaldırılır. Tüm consumer'lar güncellenir.

**Tech Stack:** Angular 20, Ng-Zorro, NzCodeEditorModule (Monaco), CDK DragDrop, signal/computed, OnPush

**Spec:** `docs/superpowers/specs/2026-03-21-birlesik-tasarim-ortami-design.md`

---

## Dosya Haritası

### Yeni Dosyalar
| Dosya | Sorumluluk |
|-------|-----------|
| `src/service/fikoyt-ui/src/lib/paylasim-sistemi/fiko-tasarim-editoru/fiko-tasarim-editoru.component.ts` | Ana orchestrator, layout, state, responsive breakpoint |
| `src/service/fikoyt-ui/src/lib/paylasim-sistemi/fiko-tasarim-editoru/fiko-tasarim-editoru.component.html` | Template |
| `src/service/fikoyt-ui/src/lib/paylasim-sistemi/fiko-tasarim-editoru/fiko-tasarim-editoru.component.less` | Stiller |
| `src/service/fikoyt-ui/src/lib/paylasim-sistemi/fiko-tasarim-editoru/te-palet.component.ts` | Element paleti (7 kategori, 45+ element) |
| `src/service/fikoyt-ui/src/lib/paylasim-sistemi/fiko-tasarim-editoru/te-canvas.component.ts` | Görsel canvas, sürükle-bırak, resize, seçim |
| `src/service/fikoyt-ui/src/lib/paylasim-sistemi/fiko-tasarim-editoru/te-kod-paneli.component.ts` | Monaco HTML/CSS/JS/Olaylar tab'ları |
| `src/service/fikoyt-ui/src/lib/paylasim-sistemi/fiko-tasarim-editoru/te-stil-paneli.component.ts` | Seçili element stil düzenleme |
| `src/service/fikoyt-ui/src/lib/paylasim-sistemi/fiko-tasarim-editoru/te-veri-paneli.component.ts` | Veri kaynağı (aggregate/soket/sabit/hesaplama) + itemler |

### Değiştirilecek Dosyalar
| Dosya | Değişiklik |
|-------|-----------|
| `sablon.interface.ts` | ISablon genişletme + IDashboardAyarlar + ElementTur birleşik |
| `sablon-renderer.component.ts` | Veri çekme + polling + soket + 30 yeni element türü + olaylarAktif |
| `sablon-renderer.component.less` | Yeni element türleri için stiller |
| `dashboard.component.ts` | IWidget → ISablon, widget-renderer → sablon-renderer |
| `dashboard.component.html` | widget-renderer tag → sablon-renderer |
| `dashboard.service.ts` | IWidget → ISablon metod imzaları |
| `hazir-widgetler.ts` | IWidget → ISablon, sablon alt alanı kök seviyeye |
| `paylas-icerik-editor.component.ts` | SablonEditoruComponent → FikoTasarimEditoruComponent |
| `hmi-pano.routes.ts` | widget-editor route → fiko-tasarim-editoru |

### Kaldırılacak Dosyalar
| Dosya | Sebep |
|-------|-------|
| `widget-editor.component.ts/html/less` | fiko-tasarim-editoru ile değiştirildi |
| `widget-renderer.component.ts/html/less` | sablon-renderer'a birleştirildi |
| `widget.interface.ts` | ISablon'a absorbe edildi |
| `sablon-editoru.component.ts/html/less` | fiko-tasarim-editoru ile değiştirildi |

---

## Task 1: ISablon Interface Genişletme

**Files:**
- Modify: `src/service/fikoyt-ui/src/lib/paylasim-sistemi/sablon-editoru/sablon.interface.ts`

- [ ] **Step 1: ISablon'a yeni alanları ekle**

ISablon interface'ine şu alanlar eklenir (mevcut alanlar korunur):

```typescript
// Kimlik & meta
id?: string;
tur?: 'widget' | 'kart' | 'serbest';
baslik?: string;
simge?: string;
aciklama?: string;
gorunur?: boolean;
silindi?: boolean;
yetki?: string[];
sira?: number;
kaynak?: 'kod' | 'db';

// Görünüm & konum
pozisyon?: ISablonPozisyon;
stil?: ISablonGorunumStil;

// Veri & olaylar
veriKaynagi?: ISablonVeriKaynagi;
olaylar?: ISablonOlaylar;
itemler?: ISablonItem[];
```

- [ ] **Step 2: Yeni interface'leri tanımla**

Aynı dosyaya ekle:

```typescript
export interface ISablonVeriKaynagi {
  mod: 'aggregate' | 'sabit' | 'soket' | 'hesaplama';
  vt?: string;
  pipeline?: any[];
  donusumFunc?: string;
  sabitVeri?: any;
  soketOlay?: string;
  soketFiltre?: Record<string, any>;
  piFunc?: string;
  yenilemeAraligi?: number;
  soketTetik?: string;
}

export interface ISablonOlaylar {
  tiklanma?: string;
  yenilendi?: string;
  esikAsimi?: string;
  ciftTiklama?: string;
  [key: string]: string | undefined;
}

export interface ISablonItem {
  id: string;
  sablon?: ISablon;
  veriKaynagi?: ISablonVeriKaynagi;
  olaylar?: ISablonOlaylar;
  [key: string]: any;
}

export interface ISablonPozisyon {
  genislik: number;
  yukseklik: number;
  x?: number;
  y?: number;
  sira?: number;
}

export interface ISablonGorunumStil {
  arkaPlan?: string;
  gradyan?: string;
  renkYazi?: string;
  borderRadius?: number;
  animasyon?: string;
  golge?: string;
}

export interface IDashboardAyarlar {
  layout: 'grid' | 'serbest';
  kolonSayisi?: number;
  aralik?: number;
  widgetler: ISablon[];
}
```

- [ ] **Step 3: ElementTur'u genişlet**

Mevcut `ElementTur` type union'ını 45+ türe genişlet:

```typescript
export type ElementTur =
  | 'sabit-metin' | 'parametre-metin' | 'parametre-render' | 'markdown'
  | 'sekil' | 'resim'
  | 'sayac' | 'ilerleme-cubugu' | 'ilerleme-halka' | 'gauge'
  | 'sparkline' | 'bar-grafik' | 'pasta-grafik' | 'alan-grafik'
  | 'radar-grafik' | 'isi-haritasi' | 'seviye-cubugu'
  | 'dijital-saat' | 'analog-saat' | 'countdown' | 'kronometr' | 'zaman-cizelgesi'
  | 'durum-dot' | 'durum-kart' | 'led-gosterge' | 'trafik-isigi' | 'sinyal-cubugu'
  | 'liste-tekrar' | 'siralama-listesi' | 'mini-tablo' | 'kanban-sutun'
  | 'avatar' | 'badge' | 'ticker' | 'qr-kod' | 'hava-durumu' | 'lottie' | 'iframe'
  | 'buton' | 'toggle' | 'slider' | 'tab-grup';
```

- [ ] **Step 4: `bosISablon()` fonksiyonunu güncelle**

Varsayılan `tur: 'kart'`, `gorunur: true` ekle.

- [ ] **Step 5: Build kontrol**

Run: `npx ng build --configuration production 2>&1 | head -30`
Expected: Build başarılı veya sadece mevcut uyarılar

---

## Task 2: Sablon-Renderer Genişletme (Veri + Olay + Yeni Elementler)

**Files:**
- Modify: `src/service/fikoyt-ui/src/lib/paylasim-sistemi/sablon-renderer/sablon-renderer.component.ts`
- Modify: `src/service/fikoyt-ui/src/lib/paylasim-sistemi/sablon-renderer/sablon-renderer.component.less`

- [ ] **Step 1: Yeni input'ları ekle**

```typescript
olaylarAktif = input(false);    // güvenlik: sadece opt-in consumer'larda aktif
```

- [ ] **Step 1.5: Mevcut @Input/@Output'ları signal syntax'ına migre et**

Mevcut sablon-renderer'daki klasik dekoratörleri signal'e çevir:
```typescript
// ESKİ:
@Input() sablon: ISablon;
@Input() parametreDegerleri: { [anahtar: string]: any } = {};
@Input() duzenlenebilir = false;
@Output() parametreTiklandi = new EventEmitter<...>();

// YENİ:
sablon = input<ISablon>();
parametreDegerleri = input<Record<string, any>>({});
duzenlenebilir = input(false);
olaylarAktif = input(false);
parametreTiklandi = output<...>();
```

Template'teki tüm `sablon.xxx` erişimleri `sablon().xxx` olarak güncellenir.

- [ ] **Step 2: Veri çekme mantığını ekle**

Widget-renderer'dan taşınacak mantık:
- `veri = signal<any>(null)` — mevcut veri
- `yukleniyor = signal(false)`
- `veriParametreleri = computed()` — veriyi parametreDegerleri'ne dönüştür
- `veriYukle()` — aggregate (FikoYTIstekKok) / sabit / hesaplama (piFunc)
- `soketBagla()` — Socket.IO event + soketFiltre
- `soketTetik` desteği: `soketTetik` alanı varsa, o socket event'i dinlenir ve geldiğinde `veriYukle()` tetiklenir (aggregate yeniden çekilir)
- `pollingKur()` — yenilemeAraligi interval
- `ngOnInit`'te: `if (this.sablon()?.veriKaynagi) this.veriYukle()`

Widget-renderer'ın `src/app/uygulamalar/hmi-pano/dashboard/widget-renderer/widget-renderer.component.ts` dosyasından birebir taşınır.

**Güvenlik notu:** Mevcut `htmlRender()` içindeki `new Function('p', jsIcerik)` çağrısı da `olaylarAktif` guard'ına alınır. `olaylarAktif = false` iken jsIcerik çalıştırılmaz.

- [ ] **Step 3: Olay yürütme ekle**

```typescript
olayTetikle(olayAdi: string) {
  if (!this.olaylarAktif()) return;
  const kod = this.sablon()?.olaylar?.[olayAdi];
  if (!kod) return;
  try {
    const fn = new Function('veri', 'sablon', 'router', 'bildirim', 'guncelle', kod);
    fn(this.veri(), this.sablon(), this.router, this.bildirimFn(), this.guncelleFn());
  } catch (e) { console.warn('Olay hatası:', olayAdi, e); }
}
```

Template'e click/dblclick binding ekle (olaylarAktif korumalı).

- [ ] **Step 4: Yeni element türlerini import et ve render et**

`widget-elementler/` altındaki 30 component'i import et. Template'teki `@switch` yapısına yeni case'ler ekle. Mevcut `sablon-renderer.component.ts` zaten 9 widget component import ediyor — geri kalanlar eklenir.

Referans: `src/app/uygulamalar/hmi-pano/dashboard/widget-elementler/` dizinindeki tüm component'ler.

- [ ] **Step 5: Renderer less dosyasına yeni element stilleri ekle**

Widget-renderer'ın `.widget-kapsayici`, `.widget-baslik`, `.widget-icerik`, `.widget-itemler` stilleri sablon-renderer'a taşınır — yeni class prefix'leriyle.

- [ ] **Step 6: Build kontrol**

Run: `npx ng build --configuration production 2>&1 | head -30`

---

## Task 3: Ana Orchestrator — FikoTasarimEditoruComponent

**Files:**
- Create: `src/service/fikoyt-ui/src/lib/paylasim-sistemi/fiko-tasarim-editoru/fiko-tasarim-editoru.component.ts`
- Create: `src/service/fikoyt-ui/src/lib/paylasim-sistemi/fiko-tasarim-editoru/fiko-tasarim-editoru.component.html`
- Create: `src/service/fikoyt-ui/src/lib/paylasim-sistemi/fiko-tasarim-editoru/fiko-tasarim-editoru.component.less`

- [ ] **Step 1: Ana component oluştur**

```typescript
@Component({
  selector: 'fiko-tasarim-editoru',
  standalone: true,
  imports: [CommonModule, TePaletComponent, TeCanvasComponent, TeKodPaneliComponent,
            TeStilPaneliComponent, TeVeriPaneliComponent, SablonRendererComponent, ...],
  changeDetection: ChangeDetectionStrategy.OnPush,
  templateUrl: './fiko-tasarim-editoru.component.html',
  styleUrl: './fiko-tasarim-editoru.component.less',
})
export class FikoTasarimEditoruComponent extends FikoYTKokBilesenComponent {
  sablon = model<ISablon>();                    // two-way binding
  parametreler = input<Record<string, any>>({});
  kaydedildi = output<ISablon>();

  seciliElementId = signal<string | null>(null);
  kodPaneliAcik = signal(true);
  kodPaneliYukseklik = signal(140);

  // Mobil panel modal durumları
  mobilPaletAcik = signal(false);
  mobilStilAcik = signal(false);
  mobilKodAcik = signal(false);
  mobilVeriAcik = signal(false);
  mobilOlaylarAcik = signal(false);

  seciliElement = computed(() => {
    const id = this.seciliElementId();
    return this.sablon()?.elementler?.find(e => e.id === id) ?? null;
  });

  onizlemeSablon = signal<ISablon | null>(null);

  private _debounceTimer: any;

  constructor() {
    super();
    // 300ms debounce ile önizleme güncelle — toObservable + debounceTime pattern
    toObservable(this.sablon).pipe(
      debounceTime(300),
      takeUntilDestroyed(),
    ).subscribe(s => this.onizlemeSablon.set(s ? structuredClone(s) : null));
  }

  sablonGuncelle(patch: Partial<ISablon>) {
    this.sablon.update(s => ({ ...s, ...patch }));
  }

  elementGuncelle(elementId: string, patch: Partial<ISablonElement>) {
    this.sablon.update(s => ({
      ...s,
      elementler: s.elementler.map(e => e.id === elementId ? { ...e, ...patch } : e)
    }));
  }

  elementEkle(tur: ElementTur) {
    const yeni = yeniSablonElement(tur);
    this.sablon.update(s => ({ ...s, elementler: [...s.elementler, yeni] }));
    this.seciliElementId.set(yeni.id);
  }

  elementSil(elementId: string) {
    this.sablon.update(s => ({
      ...s,
      elementler: s.elementler.filter(e => e.id !== elementId)
    }));
    if (this.seciliElementId() === elementId) this.seciliElementId.set(null);
  }

  kaydet() {
    this.kaydedildi.emit(this.sablon());
  }
}
```

- [ ] **Step 2: Template oluştur — masaüstü layout**

Spec'teki layout'a göre:
- Üst bar (geri, başlık, tür badge, kaydet butonu)
- Sol: `te-palet` (56px sidebar, mobilde gizli)
- Orta üst: `te-canvas` (flex)
- Orta alt: `te-kod-paneli` (resize edilebilir)
- Sağ: tab yapısı (Stil → `te-stil-paneli`, Veri → `te-veri-paneli`, Genel)
- Mobil: alt bar FAB'lar + `nz-drawer` modal'lar

Sablon-renderer canlı önizleme olarak canvas içinde gösterilir.

- [ ] **Step 3: LESS stiller — responsive breakpoints**

Masaüstü (1200px+), tablet (768-1199px), mobil (<768px) breakpoint'leri.
Mockup'taki layout uygulanır.

- [ ] **Step 4: Build kontrol**

---

## Task 4: TePaletComponent — Element Paleti

**Files:**
- Create: `src/service/fikoyt-ui/src/lib/paylasim-sistemi/fiko-tasarim-editoru/te-palet.component.ts`

- [ ] **Step 1: Component oluştur**

```typescript
@Component({
  selector: 'te-palet',
  standalone: true,
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `...`,
  styles: `...`,
})
export class TePaletComponent {
  elementEklendi = output<ElementTur>();
  darMod = input(false);        // masaüstü: true (icon-only), tablet: false (isimli)

  readonly KATEGORILER = [
    { isim: 'Metin', simge: 'T', elemanlar: [
      { tur: 'sabit-metin', isim: 'Sabit', simge: 'T' },
      { tur: 'parametre-metin', isim: 'Parametre', simge: '📝' },
      { tur: 'parametre-render', isim: 'Render', simge: '🔄' },
      { tur: 'markdown', isim: 'Markdown', simge: '📄' },
    ]},
    { isim: 'Şekil & Medya', simge: '◻', elemanlar: [...] },
    { isim: 'Veri & Grafik', simge: '📊', elemanlar: [...] },
    { isim: 'Zaman', simge: '🕐', elemanlar: [...] },
    { isim: 'Durum', simge: '💡', elemanlar: [...] },
    { isim: 'Liste & Tablo', simge: '📋', elemanlar: [...] },
    { isim: 'Kontrol', simge: '⏯', elemanlar: [...] },
  ];
}
```

7 kategori, 45+ element. `darMod` true ise sadece simge gösterilir (masaüstü sidebar). false ise isim+simge (tablet toggle panel).

- [ ] **Step 2: Build kontrol**

---

## Task 5: TeCanvasComponent — Görsel Düzenleme Alanı

**Files:**
- Create: `src/service/fikoyt-ui/src/lib/paylasim-sistemi/fiko-tasarim-editoru/te-canvas.component.ts`

- [ ] **Step 1: Component oluştur**

Mevcut sablon-editoru'nun canvas mantığı taşınır:
- Sürükle-bırak (CDK DragDrop)
- Seçim tutamaçları (4 köşe resize handle)
- Araç çubuğu (hiza, sil, kopyala)
- ArkaplanTur seçici

Input'lar:
```typescript
sablon = input<ISablon>();
seciliElementId = input<string | null>(null);
parametreDegerleri = input<Record<string, any>>({});
```

Output'lar:
```typescript
elementSecildi = output<string | null>();
elementGuncellendi = output<{id: string, patch: Partial<ISablonElement>}>();
elementSilindi = output<string>();
sablonGuncellendi = output<Partial<ISablon>>();  // arkaplan değişikliği vb.
```

- [ ] **Step 2: Mouse event'leri ngZone.runOutsideAngular() ile sar**

Drag/resize sırasında `requestAnimationFrame` throttle. Pozisyon commit sadece `mouseup`'ta. `will-change: transform` GPU layer.

- [ ] **Step 3: Sablon-renderer embed et**

Canvas içinde sablon-renderer canlı render eder. Üzerine drag overlay katmanı.

- [ ] **Step 4: Build kontrol**

---

## Task 6: TeKodPaneliComponent — Monaco Kod Editörü

**Files:**
- Create: `src/service/fikoyt-ui/src/lib/paylasim-sistemi/fiko-tasarim-editoru/te-kod-paneli.component.ts`

- [ ] **Step 1: Component oluştur**

```typescript
@Component({
  selector: 'te-kod-paneli',
  standalone: true,
  imports: [NzCodeEditorModule, NzTabsModule, ...],
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `...`,
  styles: `...`,
})
export class TeKodPaneliComponent {
  sablon = input<ISablon>();
  aktifTab = signal<'html' | 'css' | 'js' | 'olaylar'>('html');

  htmlDegisti = output<string>();
  cssDegisti = output<string>();
  jsDegisti = output<string>();
  olaylarDegisti = output<ISablonOlaylar>();
}
```

4 tab: HTML (htmlIcerik), CSS (cssIcerik), JS (jsIcerik), Olaylar (olaylar).
NzCodeEditorModule ile Monaco lazy load — tab değişince init.
Olaylar tab'ı: her olay tipi için ayrı kod alanı + şablon önerileri (mevcut widget-editor'den taşınır).

- [ ] **Step 2: Build kontrol**

---

## Task 7: TeStilPaneliComponent — Element Stil Düzenleme

**Files:**
- Create: `src/service/fikoyt-ui/src/lib/paylasim-sistemi/fiko-tasarim-editoru/te-stil-paneli.component.ts`

- [ ] **Step 1: Component oluştur**

Mevcut sablon-editoru'nun stil paneli mantığı + widget-editor'ün tasarım tab'ı birleştirilir:

Input'lar:
```typescript
seciliElement = input<ISablonElement | null>(null);
sablon = input<ISablon>();
```

Output'lar:
```typescript
elementGuncellendi = output<Partial<ISablonElement>>();
sablonStilGuncellendi = output<Partial<ISablonGorunumStil>>();
```

Bölümler:
- Boyut (genislik%, yukseklik%)
- Pozisyon (x%, y%)
- Yazı (fontSize, fontWeight, fontFamily, color, letterSpacing, lineHeight)
- Şekil (fill, stroke, borderRadius, opacity)
- Animasyon (giriş, sürekli, hover, tıklama + gecikme)
- Hizalama (sol, sağ, üst, alt, ortala)
- Arkaplan (12 hazır gradient + özel renk/gradient)
- Gölge (7 preset: none, light, medium, strong, neon)
- Tema (6 hızlı tema butonu — widget-editor'den)

Seçili element yoksa → şablon seviyesi stil (arkaplan, stil) düzenlenir.

- [ ] **Step 2: Build kontrol**

---

## Task 8: TeVeriPaneliComponent — Veri Kaynağı + İtemler

**Files:**
- Create: `src/service/fikoyt-ui/src/lib/paylasim-sistemi/fiko-tasarim-editoru/te-veri-paneli.component.ts`

- [ ] **Step 1: Component oluştur**

Widget-editor'ün Veri tab'ı + İtemler tab'ı birleştirilir:

Input:
```typescript
sablon = input<ISablon>();
```

Output:
```typescript
veriKaynagiDegisti = output<ISablonVeriKaynagi>();
itemlerDegisti = output<ISablonItem[]>();
```

İçerik:
- **Veri Kaynağı:** 4 mod kartı (aggregate/sabit/soket/hesaplama)
  - Aggregate: koleksiyon + pipeline JSON editörü + dönüşüm fonksiyonu
  - Sabit: JSON editörü
  - Soket: olay adı + filtre
  - Hesaplama: JS fonksiyon editörü
  - Yenileme aralığı slider
  - "Veri Testi Yap" butonu
- **İtemler:** CDK DragDrop sıralama + bileşen kütüphanesi (widget-editor'den BILESEN_KUTUPHANESI)
  - Per-item: genel, tasarım, veri, parametre, olaylar alt bölümleri

- [ ] **Step 2: Build kontrol**

---

## Task 9: Dashboard Migration (IWidget → ISablon)

**Files:**
- Modify: `src/app/uygulamalar/hmi-pano/dashboard/dashboard.component.ts`
- Modify: `src/app/uygulamalar/hmi-pano/dashboard/dashboard.component.html`
- Modify: `src/app/uygulamalar/hmi-pano/dashboard/dashboard.service.ts`
- Modify: `src/app/uygulamalar/hmi-pano/dashboard/hazir-widgetler.ts`

- [ ] **Step 1: DashboardService güncelle**

Tüm `IWidget` referanslarını `ISablon` olarak değiştir. Import'ları `sablon.interface.ts`'ten al. Metod adları:
- `widgetVerisiCek` → `sablonVerisiCek`
- `widgetGuncelle` → `sablonGuncelle`
- `widgetEkle` → `sablonEkle`
- `widgetSil` → `sablonSil`

İç alan referansları (`vk.vt`, `vk.piFunc`, `vk.donusumFunc`, `vk.soketFiltre`) aynı kalır.
`birlestir()` fonksiyonu `gorunur`, `silindi` filtrelerini korur.

- [ ] **Step 2: hazir-widgetler.ts güncelle**

`IWidget` → `ISablon`. Her widget'a `tur: 'widget'` ekle. `sablon:` alt alanı → kök seviyeye taşı (elementler, htmlModu, htmlIcerik, cssIcerik, jsIcerik, arkaPlan, bolgeler doğrudan ISablon'da).

- [ ] **Step 3: Dashboard component güncelle**

Template'te `widget-renderer` → `sablon-renderer` ([olaylarAktif]="true").
Tüm `IWidget` referansları → `ISablon`. Detaylı değişiklikler:

```typescript
// Import değişikliği
import type { ISablon, IDashboardAyarlar } from 'sablon.interface';
// IWidget import'u kaldırılır

// Metod imzaları
onDrop(event: CdkDragDrop<ISablon[]>)              // IWidget[] → ISablon[]
yeniWidgetEkle() → yeniSablonEkle()                 // yeni objeye tur: 'widget' eklenir
widgetDuzenle(s: ISablon) → sablonDuzenle(s: ISablon)
widgetSil(id) → sablonSil(id)

// Servis çağrıları
this.dashboardSvc.widgetEkle(w) → this.dashboardSvc.sablonEkle(s)
this.dashboardSvc.widgetSil(id) → this.dashboardSvc.sablonSil(id)
this.dashboardSvc.widgetGuncelle(id, d) → this.dashboardSvc.sablonGuncelle(id, d)

// yeniSablonEkle içinde:
const yeni: ISablon = {
  id: FikoYTId(),
  tur: 'widget',
  kaynak: 'db',
  baslik: 'Yeni Widget',
  simge: '📊',
  gorunur: true,
  pozisyon: { genislik: 2, yukseklik: 2 },
  mod: 'serbest',
  arkaPlan: { tur: 'renk', deger: '' },
  bolgeler: [],
  elementler: [],
};
```

**NOT:** DB alan yolu `veri.widgetler` korunur — geriye uyumluluk için değiştirilmez.

- [ ] **Step 4: Build kontrol**

---

## Task 10: Route & Consumer Migration

**Files:**
- Modify: `src/app/uygulamalar/hmi-pano/hmi-pano.routes.ts`
- Modify: `src/service/fikoyt-ui/src/lib/paylasim-sistemi/paylas-kutusu/IKart/paylas-icerik-editor/paylas-icerik-editor.component.ts`

- [ ] **Step 1: fikoyt-ui barrel export'a ekle (önce)**

`FikoTasarimEditoruComponent`'i `src/service/fikoyt-ui/` barrel export'una ekle. Bu adım route'dan önce yapılmalı.

- [ ] **Step 2: HMI routes güncelle**

`widget-editor/:widgetId` route → `fiko-tasarim-editoru` component'ine yönlendir. Mevcut route relative path kullanıyor — aynı pattern'i koru veya barrel import kullan:

```typescript
{
  path: 'widget-editor/:widgetId',
  loadComponent: () => import('../../service/fikoyt-ui/src/lib/paylasim-sistemi/fiko-tasarim-editoru/fiko-tasarim-editoru.component')
    .then(m => m.FikoTasarimEditoruComponent),
}
```

- [ ] **Step 3: paylas-icerik-editor güncelle**

`SablonEditoruComponent` import'unu `FikoTasarimEditoruComponent` ile değiştir.
Template'teki `<sablon-editoru>` tag'ını `<fiko-tasarim-editoru>` ile değiştir.

- [ ] **Step 4: Build kontrol**

---

## Task 11: Eski Dosyaları Kaldır

**Files:**
- Delete: `src/app/uygulamalar/hmi-pano/dashboard/widget-editor/widget-editor.component.ts`
- Delete: `src/app/uygulamalar/hmi-pano/dashboard/widget-editor/widget-editor.component.html`
- Delete: `src/app/uygulamalar/hmi-pano/dashboard/widget-editor/widget-editor.component.less`
- Delete: `src/app/uygulamalar/hmi-pano/dashboard/widget-renderer/widget-renderer.component.ts`
- Delete: `src/app/uygulamalar/hmi-pano/dashboard/widget-renderer/widget-renderer.component.html`
- Delete: `src/app/uygulamalar/hmi-pano/dashboard/widget-renderer/widget-renderer.component.less`
- Delete: `src/app/uygulamalar/hmi-pano/dashboard/interfaces/widget.interface.ts`
- Delete: `src/service/fikoyt-ui/src/lib/paylasim-sistemi/sablon-editoru/sablon-editoru.component.ts`
- Delete: `src/service/fikoyt-ui/src/lib/paylasim-sistemi/sablon-editoru/sablon-editoru.component.html`
- Delete: `src/service/fikoyt-ui/src/lib/paylasim-sistemi/sablon-editoru/sablon-editoru.component.less`

**NOT:** `sablon.interface.ts` ve `sablon-renderer` KALIR — sadece editör component'leri silinir.

- [ ] **Step 1: Kalan import referanslarını grep ile kontrol et**

```bash
grep -r "WidgetEditorComponent\|WidgetRendererComponent\|SablonEditoruComponent\|widget-editor\|widget-renderer\|widget\.interface\|IWidget\|WidgetElementTur\|IDashboardAyarlar" src/ --include="*.ts" -l
```

Eğer kalan referans varsa düzelt:
- `IWidget` → `ISablon`
- `WidgetElementTur` → `ElementTur` (artık birleşik)
- `IDashboardAyarlar` import'u → `sablon.interface.ts`'ten al
- `SablonEditoruComponent` → `FikoTasarimEditoruComponent`

- [ ] **Step 2: Dosyaları sil**

- [ ] **Step 3: Final build kontrol**

Run: `npx ng build --configuration production`
Expected: Build başarılı, sıfır hata

---

## Task Sırası & Bağımlılıklar

```
Task 1 (ISablon interface) ← bağımsız, ilk yapılmalı
Task 2 (Renderer genişletme) ← Task 1'e bağlı
Task 3 (Ana orchestrator) ← Task 1, 2'ye bağlı
Task 4 (Palet) ← Task 1'e bağlı, Task 3 ile paralel olabilir
Task 5 (Canvas) ← Task 1, 2'ye bağlı
Task 6 (Kod paneli) ← Task 1'e bağlı, Task 3 ile paralel olabilir
Task 7 (Stil paneli) ← Task 1'e bağlı, Task 3 ile paralel olabilir
Task 8 (Veri paneli) ← Task 1'e bağlı, Task 3 ile paralel olabilir
Task 9 (Dashboard migration) ← Task 1, 2'ye bağlı
Task 10 (Route migration) ← Task 3, 9'a bağlı
Task 11 (Temizlik) ← Tüm task'lara bağlı, en son
```

**Paralel çalışabilenler:** Task 4, 6, 7, 8 birbirine bağımsız — paralel subagent ile çalışabilir.
