@appaflytech/zeyrek-ai-mcp 0.0.40 → 0.0.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/dist/knowledge/componentCatalog.js +95 -104
  2. package/dist/knowledge/componentEvents.js +34 -18
  3. package/dist/knowledge/mobileComponentCatalog.js +119 -20
  4. package/dist/knowledge/mobileComponentEvents.js +41 -0
  5. package/dist/knowledge/motionResolve.js +252 -0
  6. package/dist/knowledge/normalize.js +117 -71
  7. package/dist/knowledge/pageDiscover.js +2 -2
  8. package/dist/knowledge/platform/batchOps.js +70 -0
  9. package/dist/knowledge/platform/heroTag.js +153 -0
  10. package/dist/knowledge/platform/lint.js +128 -6
  11. package/dist/knowledge/platform/mobile.js +1 -1
  12. package/dist/knowledge/platform/mobileLayoutLint.js +8 -1
  13. package/dist/knowledge/platform/mobileRules.js +18 -0
  14. package/dist/knowledge/platform/pageTransition.js +57 -0
  15. package/dist/knowledge/platform/web.js +1 -1
  16. package/dist/knowledge/rules.js +217 -24
  17. package/dist/knowledge/styleResolve.js +0 -1
  18. package/dist/knowledge/styleResolveNative.js +88 -4
  19. package/dist/platform/capture/actions.js +27 -1
  20. package/dist/platform/capture/capture.js +10 -13
  21. package/dist/platform/capture/persistent-browser.js +130 -0
  22. package/dist/platform/capture/summary.js +4 -1
  23. package/dist/resources/examples/flow-list-to-form.json +8 -10
  24. package/dist/resources/examples/flow-load-table.json +1 -1
  25. package/dist/resources/examples/mobile-app-shell-drawer.json +1 -0
  26. package/dist/resources/examples/mobile-list-detail-form.json +7 -3
  27. package/dist/resources/examples/mobile-scan-code.json +285 -0
  28. package/dist/resources/guides/component.md +3 -3
  29. package/dist/resources/guides/entity.md +16 -0
  30. package/dist/resources/guides/expressions.md +8 -7
  31. package/dist/resources/guides/merge.md +98 -18
  32. package/dist/resources/guides/microservice.md +3 -3
  33. package/dist/resources/guides/middleware.md +2 -0
  34. package/dist/resources/guides/mobile-layout.md +2 -1
  35. package/dist/resources/guides/mobile-publish.md +1 -0
  36. package/dist/resources/guides/mobile-steps.md +67 -0
  37. package/dist/resources/guides/mobile.md +51 -70
  38. package/dist/resources/guides/page.md +229 -137
  39. package/dist/resources/guides/translation.md +67 -1
  40. package/dist/resources/guides/workflow.md +31 -1
  41. package/dist/resources/schema-fingerprint.json +2 -2
  42. package/dist/resources/schemas/ResolveMergeConflictsCommand.json +30 -1
  43. package/dist/tools/activities.js +3 -1
  44. package/dist/tools/applications.js +16 -2
  45. package/dist/tools/components.js +12 -6
  46. package/dist/tools/designSchemaPatch.js +18 -13
  47. package/dist/tools/entities.js +41 -4
  48. package/dist/tools/layouts.js +29 -9
  49. package/dist/tools/merges.js +29 -9
  50. package/dist/tools/mobile.js +15 -1
  51. package/dist/tools/pages.js +156 -168
  52. package/dist/tools/platformInfo.js +3 -2
  53. package/dist/tools/profileWrite.js +2 -2
  54. package/dist/tools/queries.js +1 -1
  55. package/dist/tools/rows.js +14 -3
  56. package/dist/tools/schemaOps.js +132 -34
  57. package/dist/tools/screenWrite.js +3 -3
  58. package/dist/tools/screens.js +42 -3
  59. package/dist/tools/translations.js +148 -6
  60. package/package.json +2 -2
@@ -189,16 +189,16 @@ Tablonun/listenin satırları şemaya "dataSource" yazarak değil, **flow ile**
189
189
  ```
190
190
 
191
191
  **Event'ler komponent tipine göre değişir; `component_get`'in `events` alanından okunur.**
192
- Sayfa açılışında veri çekmek için `mount` kullanılır ama tek seçenek o değil — örneğin `table`
193
- 8 olay yayar:
192
+ Sayfa açılışında veri çekmek için `mount` kullanılır ama tek seçenek o değil — örneğin
193
+ `datatable` 7 olay yayar:
194
194
 
195
- `mount · pagination · filter · sort · select · selectionChange · doubleClick · rowChange`
195
+ `mount · rowClick · rowDoubleClick · save · discard · rowSelectionChange · cellSelectionChange`
196
196
 
197
- Yani "satırı seçince detay getir" (`select`), "kolondan süzünce sunucudan yeniden çek"
198
- (`filter`), "sayfa değişince yeni sayfayı çek" (`pagination`), "satıra çift tıklayınca formu aç"
199
- (`doubleClick`) akışları da aynı `set_event` mekanizmasıyla kurulur. Buna karşılık `datatable`
200
- yalnız `mount` yayar (bilinçli — Kural 1e); `page-header` 2026-09-18'den beri izdeki öğe
201
- tıklamasını `clickItem` olarak yayar (`component_get` yükü verir).
197
+ Yani "satıra tıklayınca detay getir" (`rowClick`), "satıra çift tıklayınca formu aç"
198
+ (`rowDoubleClick`), "düzenlenen satırları kaydet" (`save`) akışları da aynı `set_event`
199
+ mekanizmasıyla kurulur. Süzme, sıralama ve sayfalamanın AYRI olayı yoktur: `datatable` kendi
200
+ prop'larını yazıp `mount`'u yeniden tetikler (bilinçli — Kural 1e); `page-header` 2026-09-18'den
201
+ beri izdeki öğe tıklamasını `clickItem` olarak yayar (`component_get` yükü verir).
202
202
 
203
203
  **Olay adları `on` ÖNEKİ ALMAZ** (`button` → `click`, `form` → `submit`, `texteditor` → `change`);
204
204
  katalogda istisna yok. **Komponentin desteklemediği bir olay adı verirsen bağ
@@ -239,19 +239,18 @@ aksiyonları (`platform_guide('html')`) ve **`params`'ı da gönderen komponentl
239
239
  (`eventcalendar` · `importwizard` · `kanban` · `signature` · `stepper` · `tabs` ·
240
240
  `tree-view` · `pagination`): bunların yükü `event.data.<anahtar>` ile de okunur; `kanban` ve
241
241
  `eventcalendar` yükü `self`'e HİÇ yazmaz (`component_get` çıktısındaki sözleşme notları ayrımı
242
- söyler). Sessiz hata örneği: **tablonun kendi** sayfalama akışını (`table.pagination`)
243
- `event.data.limit`'e bağlarsan sorgu `LIMIT null OFFSET null` ile koşar ve **tüm satırları**
244
- döndürür; hata yok, sayfalama yok. (Bağımsız `pagination` komponenti bu tuzağa girmez, yükünü
245
- `params` ile de gönderir.)
242
+ söyler). Sessiz hata örneği: **tablonun** yükleme akışında sayfa değerlerini `event.data.limit` /
243
+ `event.data.offset`'ten okursan sorgu `LIMIT null OFFSET null` ile koşar ve **tüm satırları**
244
+ döndürür; hata yok, sayfalama yok — `datatable` bu değerleri `self.limit` / `self.offset`'e yazar
245
+ (ölçüm 2026-08-25, kaldırılan tablonun sayfalama olayında; kural aynı). (Bağımsız `pagination`
246
+ komponenti bu tuzağa girmez, yükünü `params` ile de gönderir.)
246
247
 
247
248
  | Komponent · olay | Yük (aynı zamanda prop adları) | Akışta nereden okunur |
248
249
  |---|---|---|
249
- | `table.sort` | `{ sortField, sortType, offset }` | `self.sortField` · `self.sortType` · `self.offset` |
250
- | `table.filter` | `{ filters, offset }` | `self.filters` · `self.offset` |
251
- | `table.pagination` | `{ offset, limit }` | `self.offset` · `self.limit` |
252
- | `table.select` · `doubleClick` | — | `self.selectedRow` |
253
- | `table.selectionChange` | — | `self.selectedRows` |
254
- | `datatable.mount` | — | `self.filters` · `self.sortField` · `self.sortType` · `self.offset` |
250
+ | `datatable.mount` | — | `self.filters` · `self.sortField` · `self.sortType` · `self.offset` · `self.limit` |
251
+ | `datatable.rowClick` · `rowDoubleClick` | — | `self.selectedRow` |
252
+ | `datatable.rowSelectionChange` | — | `self.selectedRows` |
253
+ | `datatable.save` | — | `self.operation` · `self.changeset` · `self.editedRows` · `self.deletedRows` |
255
254
  | `pagination.change` | `{ offset, limit }` | `self.offset` · `self.limit` ya da `event.data.offset` · `event.data.limit` |
256
255
  | `textinput/textarea/password.change` | `{ value }` | `self.value` |
257
256
  | `dropdown.change` · `multi-select.change` | `{ value }` | `self.value` |
@@ -282,7 +281,8 @@ dalı bulamaz ve akışı **sessizce durdurur** (`flow-engine.ts:79`); Studio da
282
281
  İstisnalar: `condition` → dal adı rule id'sidir (ve o id bir **GUID**'dir — aşağıdaki tuzak 6),
283
282
  `confirm` → `yes|no|always`, `microservice` →
284
283
  `always` (eski akışlarda `success` de çalışır) **+ `error`** — bağlarsan hata anında `always`
285
- yerine ondan sürer (2026-09-26, ADR 0004; ayrıntı aşağıdaki §"4xx de hatadır").
284
+ yerine ondan sürer (2026-09-26, ADR 0004; ayrıntı aşağıdaki §"4xx de hatadır"), `validation` →
285
+ `success` (hepsi geçti) | `error` (biri düştü), ardından her durumda `always` (kuralları aşağıda).
286
286
 
287
287
  **2. `iteratees[].type` yalnız `change` | `fill`.** `setter.ts` başka değerde hiçbir dala
288
288
  girmez — adım çalışır, hiçbir şey yapmaz. `change` tek prop'a değer yazar, `fill` diziyi
@@ -445,13 +445,15 @@ göstermek error flow'un işidir.
445
445
  > | `Steps.<adımAdı>.error.body` | Ucun hata gövdesi — eski `Steps.<adımAdı>.data`'nın taşındığı yer | `microservice.ts` `.catch` |
446
446
  > | `Steps.<adımAdı>.data` | **HER ZAMAN `null`**'dır — başarı gövdesi değil, hiçbir gövde değil (eskiden hata gövdesiydi) | `microservice.ts` `.catch` |
447
447
  >
448
- > **`alert` adımının `message`'ı DÜZ METİNDİR — ifade yazarsan ekranda o ifade görünür.**
449
- > `alert.ts` `task.argument.message`'ı doğrudan `toast.error()`'a geçirir ve `args` hiçbir yerde
450
- > değerlendirilmez (`Runtime.svelte` `argument: step.args`): `{ "type": "alert", "args": {
451
- > "message": "Steps.error.message", "alertType": "error" } }` kullanıcıya harfi harfine
452
- > `Steps.error.message` gösterir. Sabit bir uyarı yetiyorsa `alert` en ucuz adımdır; **ucun ne
453
- > dediğini göstereceksen bir `setter` (ya da `code`) adımı zorunludur** — `value.type: 'code'`
454
- > ifadeyi orada gerçekten çalıştırır:
448
+ > **`alert` adımının `message`'ı ve `description`'ı METİN ŞABLONUDUR — yalnız `{{ }}` içi çözülür.**
449
+ > Bileşen prop bağlamasıyla aynı çözücü (`@ng-apps/flow` `resolveStepText` → `runPropertyCode`; web ve
450
+ > cihaz aynı): `{ "type": "alert", "args": { "message": "{{ Steps.error?.message ?? 'İşlem başarısız' }}",
451
+ > "alertType": "error" } }` ucun mesajını gösterir, `"{{ t('kayit.tamam') }}"` etkin dildeki çeviriyi.
452
+ > `{{ }}` DIŞINDA yazılan ifade çözülmez: `"message": "Steps.error.message"` kullanıcıya harfi harfine
453
+ > `Steps.error.message` gösterir (FLOW-022 uyarır). `{{ }}` içermeyen metin olduğu gibi kalır. 2026-10-08
454
+ > öncesi runtime'da (yeniden yayımlanmamış kurulum, eski mobil derleme) bu alanlar düz metindi; orada
455
+ > ucun mesajı bir `setter` (ya da `code`) adımıyla bir bileşene yazılır — mesajı ekranda kalıcı
456
+ > göstermek için bugün de bu yol geçerlidir:
455
457
  >
456
458
  > ```jsonc
457
459
  > // errorSteps: start → bu setter. Metni bir notification/text komponentine yazar.
@@ -463,13 +465,14 @@ göstermek error flow'un işidir.
463
465
  > "branches": [{ "id": "<GUID>", "name": "always", "nextStepId": null }] }
464
466
  > ```
465
467
 
466
- > **`confirm` adımının diyalog çerçevesi de yazılabilir.** `args` dört düz metin alanı taşır:
468
+ > **`confirm` adımının diyalog çerçevesi de yazılabilir.** `args` dört metin alanı taşır:
467
469
  > `message` (gövde), `title` (başlık), `confirmText` (onay düğmesi, `yes` dalı), `cancelText`
468
470
  > (vazgeç düğmesi, `no` dalı). Son üçü isteğe bağlıdır; boş bırakılan alan dile göre sabit metne
469
471
  > düşer ("Emin misiniz?" / "Evet" / "Hayır" — `dialog.functions.ts` `resolveDialogFrame`).
470
- > Dördü de `alert`'in `message`'ı gibi DÜZ METİNDİR (FLOW-022 hepsini denetler):
471
- > `{ "type": "confirm", "args": { "message": "Bu risk ve 4 aksiyonu silinecek.", "title": "Riski sil",
472
- > "confirmText": "Sil", "cancelText": "Vazgeç" } }`.
472
+ > Dördü de `alert`'in `message`'ı gibi METİN ŞABLONUDUR (FLOW-022 hepsini denetler); çok dilli
473
+ > uygulamada çeviri anahtarıyla yazılır:
474
+ > `{ "type": "confirm", "args": { "message": "{{ t('risk.sil.onay') }}", "title": "{{ Row.name }} silinsin mi?",
475
+ > "confirmText": "{{ t('sil') }}", "cancelText": "Vazgeç" } }`.
473
476
 
474
477
  > **Hangi yolu seçeceksin — adımın kendi `error` dalı mı, `errorSteps` mi, ana akışta
475
478
  > `condition` mı?** Bir hatada sırayla denenir (yukarıdaki 4xx bölümü) — üçü birden TANIMLI
@@ -528,6 +531,30 @@ Tarif: `platform_guide('middleware')`.
528
531
  - Adım hedef akışı **bekler** (`await engine.run`), sonra `always` dalından devam eder.
529
532
  - Gateway boş/yarım `args`'ı **FLOW-014** ile yakalar.
530
533
 
534
+ **`validation` adımının kuralları `args.validations` dizisindedir** (kök ADR 0014). Her kural
535
+ `{ id?, component, property, type, errorMessage, settings }`: `component` sayfadaki bileşenin
536
+ **elementId**'si (boş → bileşensiz kural; sayfada olmayan ad 404), `property` okunacak prop
537
+ (çoğunlukla `value`), `type` ∈ `required · email · regex · min-length · max-length · min-value ·
538
+ max-value`, `errorMessage` düz metin ya da `t:` anahtarı (düşen alanın `invalidText`'ine yazılır),
539
+ `settings` tek parametredir — runtime **ilk değeri** okur (`{ "value": 8 }`, `{ "pattern": "^\\d+$" }`;
540
+ parametresiz tipte `{}`). Kurallar dizi sırasıyla koşar; kuralsız adım yükte `[]` döner ve her
541
+ çalıştırmada `success`'e gider.
542
+
543
+ ```jsonc
544
+ { "stepId": "kontrol", "name": "kontrol", "type": "validation", "kind": "normal",
545
+ "args": { "validations": [
546
+ { "component": "email", "property": "value", "type": "email", "errorMessage": "t:validation.email", "settings": {} },
547
+ { "component": "sifre", "property": "value", "type": "min-length", "errorMessage": "En az 8 karakter", "settings": { "value": 8 } } ] },
548
+ "branches": [ { "id": "<GUID>", "name": "success", "nextStepId": "kaydet" },
549
+ { "id": "<GUID>", "name": "error", "nextStepId": null } ] }
550
+ ```
551
+
552
+ - `always` `success`/`error`'dan **sonra** da koşar — kaydetmeyi `always`'e bağlarsan düşen
553
+ formda da kaydeder.
554
+ - Bu şekil komponentin kendi `validations`'ından (`set_validations { type, message, value }`)
555
+ farklıdır; `message`/`value` burada sessizce düşer. Tanınmayan `type` runtime'da **geçer** sayılır
556
+ (platform kümeyi doğrulamaz). Gateway ikisini de **FLOW-041** ile yakalar.
557
+
531
558
  > **`code` adımının gövdesi `args.value` alanındadır — düz JS metni olarak.** Runtime onu
532
559
  > `(async () => { <value> })()` içinde koşturur (`code.ts:18`), yani `await` serbesttir ve dönüş
533
560
  > değeri akışa taşınmaz; etkiyi `Page`/`state`/komponent yazarak üretirsin. **Alan boşsa adım
@@ -618,7 +645,7 @@ değer tipleri: `static · page · property · storage · variable · code · it
618
645
  > **`platform_guide('functions')`**.
619
646
  >
620
647
  > **`share` adımı ("Share")** metin ve bağlantı paylaşır: `args: { title, message, path }`. `title`
621
- > DÜZ METİNDİR (ifade yazılırsa FLOW-022 uyarır); `message` ve `path` `storage.value` gibi
648
+ > DÜZ METİNDİR — `{{ }}` şablonu da çözülmez (ifade ya da `{{ }}` yazılırsa FLOW-022 uyarır); `message` ve `path` `storage.value` gibi
622
649
  > İFADEDİR — düz metin tırnak ister (`"'Şuna bak'"`, `"'https://…/urun/' + Page.queryParams.id"`).
623
650
  > Bağlantının adı `url` DEĞİL `path`'tir: backend `Title`/`Message`/`Path` alanlarında saklar ve
624
651
  > tanımadığı anahtarı 200 ile sessizce düşürür (FLOW-035 `url`/`link`/`text`'i ve tırnaksız adresi
@@ -933,17 +960,21 @@ kapsayıcının kardeşi olarak yaşar (qm `[SY] Profil bilgilerim`: `page_conta
933
960
  > `gatewayNormalized` ile bildirir. Senin verdiğin `appearance.heightType`'a dokunmaz.
934
961
  >
935
962
  > Katalogda `isDefaultAutoHeight: false` olan (yani `fixed` damgalanan) tipler: `auth-layout`,
936
- > `html`, `image`, `layout`, `qrcode`, `table`, `text-editor`, `video`. Diğer her tip `auto`'dur.
963
+ > `html`, `image`, `layout`, `layout-region`, `layout-shell`, `qrcode`, `texteditor`, `video`
964
+ > (katalogdan ölçüldü 2026-10-13). Diğer her tip `auto`'dur.
937
965
  > Bu tiplerde `size.h` gerçek yüksekliktir — göz kararı değil, içeriğe göre hesapla
938
966
  > (bir satır ≈ 10px; Kural 1f).
939
967
 
940
- ## Kural 1d-2 — Sayfanın ve layout'un KENDİ olayları: `mount` · `destroy`
968
+ ## Kural 1d-2 — Sayfanın ve layout'un KENDİ olayları: `mount` · `destroy` (mobil sayfada + `focus`)
941
969
 
942
970
  Komponent olaylarından AYRI olarak sayfa ve layout kayıtları kendi olay listesini taşır
943
971
  (`events: [{ name, value: <flow id> }]`) ve geçerli adlar SABİTTİR: **`mount`**
944
972
  (yüklendiğinde) ve **`destroy`** (sayfadan/layouttan ayrılırken — runtime destroy akışlarını
945
- navigasyondan ÖNCE koşar). Başka ad platformca kabul edilir ama bağ sessizce ölü kalır —
946
- gateway **PAGE-011 / LAY-004** ile istek gitmeden reddeder.
973
+ navigasyondan ÖNCE koşar). **Mobil uygulamanın SAYFASI** bir ad daha alır: **`focus`** — ekran
974
+ her göründüğünde koşar (ilk açılışta `mount`'tan sonra, sonra yığından geri dönüşte ve sekme
975
+ değişiminde; `platform_guide('mobile')`). Başka ad platformca kabul edilir ama bağ sessizce ölü
976
+ kalır — gateway **PAGE-011 / LAY-004** ile istek gitmeden reddeder; `focus` layout'ta ve web
977
+ sayfasında da reddedilir (web sayfayı her gezinmede baştan kurar, `mount` yeter).
947
978
 
948
979
  - Bağlama yolu `set_event` DEĞİLDİR (o komponent hedefler): sayfada `page_create` /
949
980
  `page_update`'in `events` parametresi, layout'ta `layout_create/update`'in `events`'i.
@@ -954,107 +985,104 @@ gateway **PAGE-011 / LAY-004** ile istek gitmeden reddeder.
954
985
  - Akış kilidi burada da geçerlidir (Kural 3): önce bütün `flow_create`'ler, sonra events bağı.
955
986
  - Mevcut bağları `page_get` gösterir (`events[].value` = flow id).
956
987
 
957
- ## Kural 1e — İKİ tablo komponenti var: `table` ve `datatable`
958
-
959
- > **`data-table` KALDIRILDI (2026-08-17).** Katalogda böyle bir slug yok; eski bir örnekte ya da
960
- > eski bir sayfada görürsen `datatable` ya da `table` ile değiştir. Katalogda tablo işi gören
961
- > başka komponent yoktur — aşağıdaki iki satır listenin tamamıdır.
962
-
963
- | slug | Olaylar | Ayırt edici prop'lar |
964
- |---|---|---|
965
- | `table` | 8: `mount · pagination · filter · sort · select · selectionChange · doubleClick · rowChange` | `rowSelection` (none/single/multi), `selectedRow`/`selectedRows`, `filterMode` (panel/hide/row), `filters`, `showSort`, `sortField`/`sortType`, `isEditable`, `showColumnMenu`, `actions`, `emptyIcon/emptyText/emptyActions`, `style` (root/thead/th/tr/td), satır bazlı `_columns`/`_actions` ezmesi (Kural 1e-2) |
966
- | `datatable` | 1: `mount` | `title`, `locale` (tr/en), `tableStyle` (zebra/plain — satır zemini varyantı), **`style`** (parça bazlı CSS: `&__toolbar`/`&__title`/`&__head`/`&__th`/`&__body`/`&__row`/`&__td`), kolonlarda `isFilterable`/`isSortable`/`colorMap` (statik)/`prefix`/`suffix`/`precision`/`thousands`/`dateFormat`/`imageShape`/**`progress`** kolon tipi, `filters`/`sortField`/`sortType` (hidden), `actions` |
967
-
968
- **`datatable`'ın tek olay yayması eksiklik değil, tasarım.** Filtre paneli, sıralama ve sayfalama
969
- komponentin İÇİNDE: kullanıcı süzdüğünde/sıraladığında/sayfa değiştirdiğinde `datatable` önce
970
- kendi `filters`/`sortField`/`sortType`/`offset` prop'larını node'a yazar, sonra **`mount`'u
971
- yeniden tetikler** (`updateQuery` → `emitMount`). Yani tek bir `mount` akışı yazarsın; o akış
972
- tabloya bağlı uca bu prop'ları parametre olarak geçirir ve dönen satırları geri yazar.
973
-
974
- **`table`'da her etkileşim AYRI bir olaydır** ve her birini ayrı akışa bağlarsın (`filter`,
975
- `sort`, `pagination` olayları yükte yeni değerleri de taşır — yukarıdaki olay yükü tablosu).
976
-
977
- Her ikisinin de süzme/sıralaması sunucu taraflıdır: seçilen filtreler uca `filters` parametresi
978
- olarak gider ve ancak `enableDynamicFilters: true` olan bir uçta karşılık bulur
988
+ ## Kural 1e — Tablo komponenti `datatable`'dır
989
+
990
+ > **`table` KALDIRILDI (2026-09-30)**, `data-table` ondan önce (2026-08-17). Katalogda tablo işi
991
+ > gören tek komponent `datatable`'dır. Eski bir sayfada `type: "table"` düğümü görürsen runtime
992
+ > onu `datatable` ile çizer (takma ad), ama o düğümün eski olayları (sayfalama, süzme, sıralama,
993
+ > seçim, çift tık, satır değişimi) ve eski prop'ları (satır seçim kipi, satır bazlı `_columns`
994
+ > ezmesi, `style.thead|th|tr|td`) artık karşılık bulmaz — kurulumu aşağıdaki sözleşmeye çevir.
995
+ >
996
+ > **Kayıt defterinde durmaya devam eder.** Eşitleme kaldırılan bileşeni silmez, gizler (silmek o
997
+ > tipteki kayıtlı düğümleri de silerdi): `component_list` onu yalnız `includeHidden: true` ile ve
998
+ > `retired: true` işaretiyle gösterir — henüz eşitlenmemiş bir ortamda gizlenmeden de listelenebilir —
999
+ > `component_get` eski şemayı `retired` notuyla döner ve PLATFORM o tipte düğümü kabul eder (runtime
1000
+ > `datatable` çizer, eski olaylara kurulan bağ kaydedilir ama ölü kalır). Gateway bu yüzden emekli tipte YENİ
1001
+ > düğümü **PAGE-051** ile istek gitmeden reddeder: `add_component`, `page_create` / `layout_create` /
1002
+ > `component_create` şeması ve `layout_patch`'in eklediği düğüm. O tiple kayıtlı düğüme yazan op'lar
1003
+ > (`replace_prop`, `move_component`…) ve tam şema yazan `page_update` geçer — eski sayfa düzenlenebilir
1004
+ > kalır; düğümü silip aynı tiple yeniden eklemek ise reddedilir. Kayıtlı `table` düğümüne olay
1005
+ > bağlarken `datatable`'ın olay adlarını yaz (`rowDoubleClick`): gateway adı onun listesinden denetler.
1006
+
1007
+ | Ne | Nasıl |
1008
+ |---|---|
1009
+ | Olaylar | 7: `mount · rowClick · rowDoubleClick · save · discard · rowSelectionChange · cellSelectionChange` |
1010
+ | Süzme / sıralama / sayfalama | komponentin İÇİNDE, ayrı olayı yok: `filters`/`sortField`/`sortType`/`offset` prop'larını (hidden) yazıp `mount`'u yeniden tetikler |
1011
+ | Satır | `rowClick` · `rowDoubleClick` ve satır aksiyonları (`actions`) tıklanan satırı `selectedRow`'a yazar (7b) |
1012
+ | Düzenleme | `editMode` (`none` · `row` · `cell` · `batch`); kayıt `save` olayıyla gelir (`self.operation` + `self.changeset`) |
1013
+ | Kolon biçimi | `isFilterable`/`isSortable`/`colorMap`/`prefix`/`suffix`/`precision`/`thousands`/`dateFormat`/`imageShape`, **`progress`** kolon tipi |
1014
+ | Görünüm | `title`, `locale` (tr/en), `tableStyle` (zebra/plain — satır zemini varyantı), **`style`** (parça bazlı CSS: `&__toolbar`/`&__title`/`&__head`/`&__th`/`&__body`/`&__row`/`&__td`) |
1015
+
1016
+ **Süzme/sıralama/sayfalamanın ayrı olayı olmaması eksiklik değil, tasarım.** Filtre paneli,
1017
+ sıralama ve sayfalama komponentin İÇİNDE: kullanıcı süzdüğünde/sıraladığında/sayfa değiştirdiğinde
1018
+ `datatable` önce kendi `filters`/`sortField`/`sortType`/`offset` prop'larını node'a yazar, sonra
1019
+ **`mount`'u yeniden tetikler** (`updateQuery` → `emitMount`). Yani tek bir `mount` akışı yazarsın;
1020
+ o akış tabloya bağlı uca bu prop'ları parametre olarak geçirir ve dönen satırları geri yazar
1021
+ (`ngapps://examples/flow-load-table`).
1022
+
1023
+ Süzme/sıralama sunucu taraflıdır: seçilen filtreler uca `filters` parametresi olarak gider ve
1024
+ ancak `enableDynamicFilters: true` olan bir uçta karşılık bulur
979
1025
  (`platform_guide('microservice')`).
980
1026
 
981
- **Karar senin, dayatma yok.** Sorular:
1027
+ **Kurarken sorulacaklar:**
982
1028
 
983
- - *Kullanıcı bu listeyi ekrandan süzecek/sıralayacak mı?* Hayır ise ikisi de olur; en az kavramla
984
- kurulanı seç ve `mount` akışı yeterlidir.
985
- - *Süzme/sıralama var mı?* → `datatable` tek akışla kurar (daha az bağlama), `table` her olayı
986
- ayrı akışa bağlamanı ister ama karşılığında satır seçimi (`rowSelection`), çift tık, hücre içi
987
- düzenleme (`isEditable`) ve boş-durum aksiyonları verir.
988
- - *Satır seçimi / çift tıkla forma geçiş / hücre düzenleme gerekiyor mu?* → **`table`**; bunlar
989
- `datatable`'da yok.
1029
+ - *Kullanıcı bu listeyi ekrandan süzecek/sıralayacak mı?* Hayır ise kolonlarda
1030
+ `isFilterable`/`isSortable` açma; `mount` akışı yeterlidir.
1031
+ - *Satıra tıklayınca / çift tıklayınca bir şey olacak mı?* → `rowClick` / `rowDoubleClick` ya da
1032
+ satır aksiyonu (`actions`) — 7b.
1033
+ - *Hücre içi düzenleme gerekiyor mu?* → `editMode`; kaydı `save` akışı yazar, bağlı tabloda
1034
+ (Connect Data) runtime bağlantısı (`component_get('datatable')` → `knowledge`).
990
1035
  - *Sayı/tarih/görsel biçimlendirme (para birimi öneki, ondalık, binlik ayracı, tarih formatı,
991
- avatar şekli) gerekiyor mu?* → **`datatable`**; `prefix`/`suffix`/`precision`/`thousands`/
992
- `dateFormat`/`imageShape` yalnız onun kolon şemasındadır, `table`'da yoktur.
993
- - *Renk gerekiyor mu?* → **ikisi de yapar ama farklı şeyi.** `datatable`'ın `colorMap`'i
994
- **statiktir**: hücrenin kendi değerine bakar; satır verisinde rengi taşırsan (`{ label, color }`)
995
- dinamik de olur. `table` ise satır bazında **koşullu** renklendirir (`_columns` ezmesi,
996
- Kural 1e-2). İkisinin de `style` prop'u vardır (datatable'ınki 2026-08-27'de eklendi), yani
997
- renk uğruna stilden vazgeçmen gerekmiyor.
998
- - *Hücrenin içinde ilerleme çubuğu ya da yüzde halkası mı istiyorsun?* → **`datatable`**, kolon
999
- tipi `progress`. `progressVariant` çubuk/halka, `thresholds` yüzdeye göre renk, `captionField`
1000
- ise BAŞKA bir satır alanını çubuğun üstüne yazar — ad ve çubuk tek hücrede durur. `table`'da
1001
- böyle bir kolon tipi yok.
1002
-
1003
- **Bu, katalogdaki her komponent için geçerlidir:** hangi komponenti kullanacağını
1036
+ avatar şekli) gerekiyor mu?* → kolon şemasında `prefix`/`suffix`/`precision`/`thousands`/
1037
+ `dateFormat`/`imageShape`.
1038
+ - *Renk gerekiyor mu?* → Kural 1e-2.
1039
+ - *Hücrenin içinde ilerleme çubuğu ya da yüzde halkası mı istiyorsun?* → kolon tipi `progress`.
1040
+ `progressVariant` çubuk/halka, `thresholds` yüzdeye göre renk, `captionField` ise BAŞKA bir
1041
+ satır alanını çubuğun üstüne yazar — ad ve çubuk tek hücrede durur.
1042
+
1043
+ **Komponent seçimi sana aittir:** hangi komponenti kullanacağını
1004
1044
  `component_list`/`component_get` ile keşfedip kendin seçersin, rehberdeki örnekler tercih değil
1005
1045
  şablondur.
1006
1046
 
1007
- Kaçınılacak tek şey **yarım kurulum**: süzme arayüzünü açıp (`table` + `filterMode:'row'`, ya da
1008
- `datatable` + `isFilterable` kolonlar) arkasına statik filtreli uç bağlamak. Sayfa çalışır
1009
- görünür, kullanıcı süzer, hiçbir şey olmaz. Ya süzme arayüzünü kapat, ya ucu
1010
- `enableDynamicFilters: true` yap ve akışta `filters` parametresini geçir.
1047
+ Kaçınılacak tek şey **yarım kurulum**: süzme arayüzünü açıp (`datatable` + `isFilterable`
1048
+ kolonlar) arkasına statik filtreli uç bağlamak. Sayfa çalışır görünür, kullanıcı süzer, hiçbir şey
1049
+ olmaz. Ya süzme arayüzünü kapat, ya ucu `enableDynamicFilters: true` yap ve akışta `filters`
1050
+ parametresini geçir.
1011
1051
 
1012
1052
  > Komponenti sonradan değiştirmek pahalıdır: flow'un `setter` adımı hedefi kayıt anında
1013
1053
  > **DesignComponent id**'sine çözer (`StepIterate.component?.Id`), komponenti silip yeniden
1014
1054
  > eklersen elementId aynı olsa bile o bağ kopar ve flow'u yeniden kaydetmen gerekir. Tipi
1015
1055
  > baştan doğru seç.
1016
1056
 
1017
- ## Kural 1e-2 — Satır bazlı renk `table`'da: `_columns` ezmesi
1057
+ ## Kural 1e-2 — Satır bazlı renk: `colorMap` ve satır verisi
1058
+
1059
+ `datatable`'da renk kolonun işidir ve çizim sırası **satır verisindeki `color` → `colorMap` →
1060
+ `autoColor`**'dır (`component_get('datatable')` → `knowledge.propNotes.colorMap`):
1018
1061
 
1019
- `table` her hücreyi çizerken **satırın kendi `_columns` sözlüğünü** kolon tanımıyla birleştirir
1020
- (`column-view.ts` `resolveColumn` → `Table.svelte:1207` `<TableCell {column}>`). Yani bir satır
1021
- kendi `appearance`/`isBold`'unu dayatabilir; renk, satırın herhangi bir alanından hesaplanır:
1062
+ | istenen | yol |
1063
+ |---|---|
1064
+ | Değere göre sabit renk | `tag` kolonu + `colorMap`: `[{ value: 'Active', label: 'Aktif', color: 'success' }]` — hücrenin KENDİ değerine bakar, satırın başka alanına göre hesaplanamaz |
1065
+ | Satıra göre koşullu renk | hücre değerini `{ label, color }` nesnesi olarak yaz: renk satır verisinde taşınır |
1022
1066
 
1023
1067
  ```jsonc
1024
- // setter: rows'a yazmadan önce satırları zenginleştir
1068
+ // setter: rows'a yazmadan önce hücreyi { label, color } nesnesine çevir
1025
1069
  { "type": "change", "element": "tbl", "property": "rows", "source": "component",
1026
1070
  "mapping": { "source": "", "mappings": {} },
1027
- "value": { "type": "code", "ref": "(Steps.listele?.data || []).map(function (r) { return Object.assign({}, r, { _columns: [null, null, null, null, { appearance: r.durum === 'İptal' ? 'error' : 'success' }] }); })" } }
1071
+ "value": { "type": "code", "ref": "(Steps.listele?.data || []).map(function (r) { return Object.assign({}, r, { durum: { label: r.durum, color: r.durum === 'İptal' ? 'error' : 'success' } }); })" } }
1028
1072
  ```
1029
1073
 
1030
- **`_columns` bir DİZİDİR ve konum kolonun `columns` dizisindeki İNDEKSİDİR** — yukarıdaki dört
1031
- `null`, hedef kolon 5. sırada (indeks 4) olduğu için var; ezilmeyen kolonlar atlanır.
1032
- `buildViewColumns` `index`'i `isHidden` kolonlar elenmeden ÖNCE atar, yani **görünür sıra değil
1033
- tanım sırası**: gizli bir `id` kolonu indeksleri kaydırmaz, kullanıcının kolon menüsünden kolon
1034
- gizlemesi de kaydırmaz (`hideColumns` `buildViewColumns`'dan SONRA uygulanır).
1035
- Aynı kalıp `_actions[i]` ile satır bazlı **aksiyon** ezmesinde de çalışır (tek bir satırda "Sil"i
1036
- `{ "isHidden": true }` ile gizlemek gibi).
1037
-
1038
- > Sözleşme frontend'de belgeli ve testli: `column-view.ts` `resolveColumn` + `column-view.spec.ts`
1039
- > (`applies the row's own override fields on top`, `matches the override by the column definition
1040
- > order`). Ezilebilen alanlar `appearance` · `options` · `isBold`. CSV export'u da bu ezmeyi
1041
- > uygular, yani ekranda gördüğün renk dışa aktarımda da tutarlıdır.
1042
-
1043
- İki renk yolu var:
1044
-
1045
- | istenen | yol |
1046
- |---|---|
1047
- | Hazır palet | `tag` kolonu + `appearance`: `primary · info · success · warning · error`; `_columns` ile satır satır değişir |
1048
- | Serbest hex | `tags` kolonu + satır verisinde `[{ "value": "kritik", "color": "#da1e28" }]` |
1074
+ Renk semantik ad (`primary · info · success · warning · error` — tema token'ına çözülür, tema
1075
+ değişince izler) ya da hex/rgb/CSS renk adıdır; temalarda `info` neredeyse beyazdır, mavi için
1076
+ `primary` yaz. `colorMap` satırının `mode: 'solid'`'i o değeri dolu zemin + beyaz yazıyla çizer.
1049
1077
 
1050
- **`style` yazarken iki ayrı kural geçerli:** `style.root` emotion'dır (camelCase çalışır, iç
1051
- seçici yazılabilir); `style.thead|th|tr|td` ise satır içi `style` attribute'una basılır
1052
- (`toStyleString` anahtarı olduğu gibi yazar) — bu dördünde **kebab-case zorunludur**, `fontSize`
1053
- sessizce düşer, `font-size` çalışır.
1078
+ Satır bazlı `_columns` görünüm ezmesi `datatable`'da **yoktur** (kaldırılan tablonun özelliğiydi).
1079
+ Satıra göre değişebilen şey AKSİYONDUR: `rows[i]._actions[<aksiyon indeksi>] = { isHidden,
1080
+ isDisabled, text … }` o satırda aksiyonun üstüne biner; `actions[i].isHidden`/`isDisabled` bir kod
1081
+ ifadesi de olabilir (`{ "type": "code", "ref": "{{ !item.isCustomizable }}" }`, `item` = o satır) —
1082
+ Connect Data'ya bağlı tabloda satırlar `_actions` taşıyamadığı için tek yol budur.
1054
1083
 
1055
- > `datatable`'da `style` prop'u **yoktur** (ne şemada ne `.svelte`'de) ve `_columns` ezmesi de
1056
- > yoktur; `tableStyle` CSS değil `zebra`/`plain` varyantıdır. Tabloya CSS ya da koşullu satır
1057
- > rengi gerekiyorsa **`table`**.
1084
+ Tabloya CSS `style` prop'uyla yazılır (parça bazlı, camelCase; `designerCss` her bildirime
1085
+ `!important` ekler); `tableStyle` CSS değil `zebra`/`plain` varyantıdır.
1058
1086
 
1059
1087
  ## Kural 1f — Koordinat modeli ve layout-slot yerleşimi
1060
1088
 
@@ -1407,6 +1435,75 @@ düşer: sekme yığını kendi geçmişini tutar ve modal onu kırardı. `prese
1407
1435
 
1408
1436
  Web uygulamasında alan yok sayılır; gateway web profilinde bu konuda bulgu üretmez.
1409
1437
 
1438
+ ### `redirect.transition`
1439
+
1440
+ `redirect` adımının `args.transition` alanı hedef ekranın NASIL GİRDİĞİNİ söyler — `presentation`'ın
1441
+ yanındaki ikinci seçim, yalnız mobil. Kapalı küme:
1442
+
1443
+ - `default` — işletim sisteminin kendi geçişi
1444
+ - `none` — anında
1445
+ - `fade` — solarak
1446
+ - `slide` — yandan kayarak (iOS'ta sistemin geçişiyle aynı görünür)
1447
+ - `slideUp` — alttan kayarak
1448
+
1449
+ Öncelik: **adımın değeri → uygulamanın varsayılanı → sistem.** Alan yazılmamışsa adım uygulamanın
1450
+ varsayılanını kullanır: `application_update` `properties.mobile.transition` (aynı küme; `properties.mobile.tabs`'in
1451
+ yanındaki anahtar — `properties` yazılırken sekme ayarı da gönderilir, gövde REPLACE'tir). Adımda açıkça yazılmış
1452
+ `default` bir seçimdir ve uygulama varsayılanını ezer. Süre alanı yoktur.
1453
+
1454
+ - Küme dışı ADIM değerini backend 422 ile reddeder (iletisi kümeyi sayar); yazım gitmez. Küme dışı UYGULAMA ayarını
1455
+ backend doğrulamaz ve cihaz sessizce düşürür — onu söyleyen tek yer `application_create` / `application_update`
1456
+ yanıtındaki `platformWarnings`'tir (**MOB-029**).
1457
+ - **`modal` sunumda ve sekme hedefinde geçiş kullanılmaz:** modal sistemin kağıt animasyonuyla açılır, sekme
1458
+ hedefinde sekme değişir ve ekran itilmez. `modal` ile birlikte yazılırsa akış yazımının yanıtına MOB-029 bilgi notu
1459
+ düşer; sekme hedefi için not YOKTUR (lint sekme ayarını görmez) — hedef sayfanın sekme olup olmadığını
1460
+ `application_get` `properties.mobile.tabs.items`'tan kendiniz kontrol edin.
1461
+ - Geri dönüş (başlık çubuğunun geri düğmesi) aynı geçişin tersidir. iOS'ta kenardan geri kaydırma her geçişte
1462
+ sistemin yatay hareketidir.
1463
+ - "Hareketi azalt" açık cihazda seçilmiş geçiş oynamaz; `default` sisteme kalır.
1464
+ - `_transition` sorgu adı kabuğundur: `args.query` içinde bu adı kullanmayın — cihazda adrese yazılmaz ve sayfa onu
1465
+ `Page.queryParams`'ta görmez (web önizleme sorguyu olduğu gibi geçirir; iki yüzey bu adda ayrışır).
1466
+ - Geçiş TELEFONDA oynar. Web önizlemesi (`/dev`, `/preview`) yalnız GELEN sayfanın girişini oynatır — giden sayfa
1467
+ canlanmaz, `modal` ve sekme hedefinde giriş yoktur. `page_screenshot`'ın varsayılan karesi (`motion: 'frozen'`)
1468
+ "hareketi azalt"la alınır: giriş oynamaz, kare son hâli gösterir; `motion: 'play'` karesi girişin ortasına denk
1469
+ gelebilir.
1470
+
1471
+ Web uygulamasında alan yok sayılır; gateway web profilinde bu konuda bulgu üretmez.
1472
+
1473
+ ## Kural 1g-3 — Paylaşılan öğe: `heroTag` (liste satırındaki görselden açılan ayrıntı)
1474
+
1475
+ `heroTag` iki sayfada AYNI etiketi taşıyan iki düğümü çift yapar: kaynak sayfadaki öğeye dokunulup hedef sayfaya
1476
+ gidilince hedef sayfa o öğenin kutusundan **büyüyerek** açılır, geri dönüşte o kutuya küçülür. Sayfanın TAMAMI büyür
1477
+ (iOS'un yakınlaşma geçişi) — yalnız öğenin uçtuğu klasik Hero değildir. Alanı `image` ve `container` taşır
1478
+ (`component_get` → `propNotes.heroTag`).
1479
+
1480
+ Liste → ayrıntı, üç adım:
1481
+
1482
+ 1. **Kaynak:** satır şablonundaki `image`'a (ya da satırın kabına) `heroTag` yazın — `{ type: 'static', data: 'kapak' }`
1483
+ yeter. Satıra dokunmak (`repeater.itemPress`) satırdaki etiketli düğümden açar; dokunuşun görselin üstünde olması
1484
+ gerekmez. Liste dışında, `click`'i bağlı bir kabın içindeki etiketli düğüm de aynı kuralla kaynak olur. Satıra TEK
1485
+ etiket yazın: iç içe iki etiketli düğümde (kap ⊃ görsel) dokunuş ikisinin de dışındaysa içteki kaynak olur.
1486
+ 2. **Hedef:** ayrıntı sayfasında büyük görsele AYNI etiketi yazın. Sayfa ona hizalanarak açılır. Hedefte eş yoksa
1487
+ sayfa yine kaynaktan büyür, yalnız hizalanacak kutu olmaz.
1488
+ 3. **Gezinme:** bildiğiniz `redirect` adımı (`pageId`, `query`). Ek alan yok: etiketli öğeden çıkan itme (`push`) ve
1489
+ `modal` sunum yakınlaşır; sekme değişimi ve `replace` yakınlaşmaz.
1490
+
1491
+ - Etiketi satıra özgü yazmak GEREKMEZ (kaynak dokunulan satırdır). Hedef sayfada birden çok etiketli düğüm varsa
1492
+ doğrusunu ifade seçtirir: satırda `{{ 'urun-' + item.id }}`, hedefte `{{ 'urun-' + Page.queryParams.id }}`
1493
+ (`set_binding`). Hedef etiketini SORGU PARAMETRESİNDEN türetin: sonradan yüklenen veriye bağlı etiket ilk çizimde
1494
+ boştur, değer gelince düğüm yeniden kurulur ve `mount` akışları ikinci kez koşar.
1495
+ - **Yalnız iOS 18+ cihazda oynar.** Android'de, eski iOS'ta, `/dev` önizlemesinde, `page_screenshot`'ta ve kanvasta
1496
+ sayfa adımın geçişiyle açılır (`redirect.transition`). Yakınlaşma oynadığında adımın geçişi oynamaz. "Hareketi azalt"
1497
+ açıkken yakınlaşma yoktur. Dokunuşla başlamayan gezinme (zamanlayıcı, dokunuştan 10 sn sonra biten akış) yakınlaşmaz.
1498
+ - Hedef düğümün `motionStyle.enter`'ı oynamaz; hedef olmayan düğümlerinki oynar.
1499
+ - Aynı sayfada aynı statik etiketi iki düğüme yazmak KAYNAK sayfada olağandır (aynı etiketli kartlar). HEDEF sayfada
1500
+ hizalama kutusu tektir: ilk çizilen düğüm hizalanır — yazım bunu **MOB-030** bilgi notuyla söyler. Sayfalar arası
1501
+ eş arama yazımda yapılmaz (hedef sayfa henüz yazılmamış olabilir) ve eşi olmayan etiket için uyarı yoktur: iki
1502
+ sayfanın etiketlerini `page_runtime_get` özetindeki `heroTags`'ten (layout'unkiler dahil) karşılaştırın.
1503
+ - `_hero` sorgu adı kabuğundur (`_transition` gibi): `args.query` içinde kullanmayın.
1504
+
1505
+ Web uygulamasında alan yoktur.
1506
+
1410
1507
  ## Kural 1h — Tasarım: `style` prop'u ve tema değişkenleri
1411
1508
 
1412
1509
  Her komponentin `style` prop'u vardır ve emotion `css()` bloğudur: iç seçiciler, pseudo-class'lar
@@ -1429,12 +1526,6 @@ yapmanın yolu budur — ölçülmüş kurallar (anket-doldur, 2026-08-19):
1429
1526
  > düğümleri silip yeniden kurmaya, o da 20 setter'ın sessizce kopmasına yol açtı. Gateway artık
1430
1527
  > kebab-case anahtarı camelCase'e çevirir ve `gatewayNormalized` ile bildirir; seçici anahtarlara
1431
1528
  > (`&__body`, `:hover`, `--ng-*`) dokunmaz.
1432
- >
1433
- > **İSTİSNA — satır içi stil dalları (TB-129).** Kural `style` prop'unun emotion bloğu olan
1434
- > dalları içindir. `table.style.thead|th|tr|td` ise DOM'un `style` attribute'una string olarak
1435
- > basılır ve orada **kebab-case zorunludur**; gateway bu dört alanın altına 2026-09-20'den beri
1436
- > hiç dokunmaz (`INLINE_STYLE_FIELDS_BY_TYPE`). `table.style.root` ve öteki komponentler eskisi
1437
- > gibi çevrilir. Çeviri bu dalları da camelCase yapınca stil sessizce düşüyordu (S2-39).
1438
1529
 
1439
1530
  **1. Temayı tek yerden çevir: `page_container.style` içinde `--ng-*` değişkenlerini ez.**
1440
1531
  Runtime bütün renk/tipografi/form tokenlarını CSS değişkeni olarak basar
@@ -2144,7 +2235,7 @@ start → [setter] btn_save.isLoading = true
2144
2235
  > katalogla sınırlıdır** ama artık neredeyse her komponent tanımlıyor: **101 kaydın 99'u**
2145
2236
  > (ölçüm 2026-09-08; 2026-08-26'daki toplu ekleme öncesi 81'de 37 idi). Tanımlamayan yalnız
2146
2237
  > iki kap var: **`slot` · `widget-area`** — onların içindekini gizlemek için sarmalayıcı
2147
- > kullan. Eskiden tanımlamayan `text` · `table` · `datatable` · `dropdown` · `multi-select` ·
2238
+ > kullan. Eskiden tanımlamayan `text` · `datatable` · `dropdown` · `multi-select` ·
2148
2239
  > `tag-input` · `tabs` · `notification` · `toast` · `datepicker` ailesi gibi komponentlere
2149
2240
  > artık doğrudan `props.isHidden` yazılabilir; sırf gizlemek için `container`'a sarmak
2150
2241
  > GEREKMEZ. Tek doğru kaynak `component_get` + `page_schema_validate` kuru koşusudur.
@@ -2158,26 +2249,27 @@ start → [setter] btn_save.isLoading = true
2158
2249
 
2159
2250
  ### 7b — Liste → form geçişi
2160
2251
 
2161
- **Önce hangi tabloyu kullandığını bil — ikisi FARKLI kurulur:**
2252
+ Tablo `datatable`'dır (Kural 1e). Kaydı açmanın iki yolu var; ikisinde de tıklanan satır, akış
2253
+ koşmadan ÖNCE komponentin `selectedRow` prop'una **komponent tarafından** yazılır
2254
+ (`Table.svelte` → `setNode` + `onEmit`):
2162
2255
 
2163
- | | `table` | `datatable` |
2256
+ | Yol | Kurulum | Satır akışta |
2164
2257
  |---|---|---|
2165
- | Yaydığı olaylar | `mount` · `select` · `doubleClick` · `filter` · `sort` · `pagination` … | **yalnız `mount`** |
2166
- | Süzme/sıralama/sayfalama | her biri AYRI akışa bağlanır | komponent kendi prop'larını (`filters`/`sortField`/`sortType`/`offset`) yazıp `mount`'u yeniden tetikler → **tek akış yeter** |
2167
- | Satır seçimi / çift tık | var (`self.selectedRow`) | **YOK** — `doubleClick` bağlamak 200 döner ama bağ ölüdür (gateway PAGE-008 keser) |
2168
- | Kayıt açma | `doubleClick` akışı | satır **aksiyonu**: `actions: [{ text, kind, icon, flow: { type: 'flow', ref: <flowId> } }]` |
2169
-
2170
- `datatable` satır aksiyonunda tıklanan satır komponentin `selectedRow` prop'una **komponent
2171
- tarafından** yazılır, sonra akış çalışır (`Table.svelte:72` → `setNode` + `onEmit`): akışta
2172
- `<elementId>.selectedRow.<alan>` ile okunur. `actions[].kind` sözlüğü **butonunkinden farklıdır**
2258
+ | Satır olayı | `set_event` → `rowDoubleClick` (tek tık için `rowClick`) | `self.selectedRow.<alan>` |
2259
+ | Satır aksiyonu | `actions: [{ text, kind, icon, flow: { type: 'flow', ref: <flowId> } }]` | `<elementId>.selectedRow.<alan>` |
2260
+
2261
+ `rowClick` veri hücresine tıklamada yayılır; onay kutusu, ✏/🗑 ve aksiyon düğmeleri tetiklemez.
2262
+ `editMode` `none` DIŞINDAYKEN çift tık satırı ayrıca düzenlemeye açar — geçiş için `editMode: none`
2263
+ bırak ya da aksiyon kullan. `actions[].kind` sözlüğü **butonunkinden farklıdır**
2173
2264
  (`error · information · solid · transparent · dark · danger · warning`; butonda
2174
2265
  `success · error · info · primary · warning`) — yanlış sözlükten değer `invalid-enum-value` verir.
2266
+ Kaldırılan tablonun çift tık ve seçim olay adları `datatable`'da yoktur: bağlamak 200 dönüp ölü
2267
+ bağ bırakmaz, gateway PAGE-008 ile istek gitmeden reddeder.
2175
2268
 
2176
- Aşağıdaki `doubleClick` tarifi **`table`** içindir. Geçişi `redirect` yapar ve
2177
- **`query` bir İFADEDİR**:
2269
+ Geçişi `redirect` yapar ve **`query` bir İFADEDİR** (`ngapps://examples/flow-list-to-form`):
2178
2270
 
2179
2271
  ```jsonc
2180
- // satıra çift tıkla → edit ; self = tetikleyen komponent
2272
+ // satıra çift tıkla (rowDoubleClick) → edit ; self = tetikleyen komponent
2181
2273
  { "stepId": "go_edit", "type": "redirect", "kind": "normal",
2182
2274
  "args": { "pageId": "<form sayfası id>", "path": "departman",
2183
2275
  "query": "`id=${self.selectedRow.id}`" },
@@ -2185,7 +2277,7 @@ Aşağıdaki `doubleClick` tarifi **`table`** içindir. Geçişi `redirect` yapa
2185
2277
 
2186
2278
  // "Yeni" butonu → create (bağlamı taşıyarak; komponente ADIYLA erişim)
2187
2279
  { "args": { "pageId": "<form sayfası id>", "path": "departman",
2188
- "query": "table?.selectedRow?.id ? `parent=${table.selectedRow.id}` : ''" } }
2280
+ "query": "records_table?.selectedRow?.id ? `parent=${records_table.selectedRow.id}` : ''" } }
2189
2281
  ```
2190
2282
 
2191
2283
  Sayfalar arası veri geçmenin yolu budur: gönderen `query`'ye yazar, alan `Page.queryParams.<ad>`
@@ -2249,7 +2341,7 @@ bağlanır, filtre `source:'expression'` + `value:'user.id'` olur.
2249
2341
  | Tarih / saat / aralık | `datepicker` · `datetimepicker` · `daterangepicker` · `datetimerangepicker` · `timepicker` (yalnız HH:mm) |
2250
2342
  | Kimlik alanları | `textinput` (e-posta için `inputMask` Email hazır maskesi ya da `regex` kuralı — `email` diye bir bileşen YOK, `add_component` `unknown-type` ile reddedilir) · `password` |
2251
2343
  | Dosya | `fileUpload` (dropzone) · `fileInput` · `filebutton` · `file-viewer` |
2252
- | Liste | `table` · `datatable` (Kural 1e) · `repeater` (kart listesi VE dinamik form — Kural 1g) · `tree-view` (hiyerarşi; `isSearchable` ile istemci içi arama) · `timeline` (tarihli olay akışı) |
2344
+ | Liste | `datatable` (Kural 1e) · `repeater` (kart listesi VE dinamik form — Kural 1g) · `tree-view` (hiyerarşi; `isSearchable` ile istemci içi arama) · `timeline` (tarihli olay akışı) |
2253
2345
  | Pano / takvim | `kanban` (durum kolonlarında sürüklenebilir kartlar; taşıma `cardMove` ile `event.data`'dan okunur, kalıcılık AKIŞIN işidir) · `eventcalendar` (ay/hafta/gün/ajanda; veri `rows`'a akışla yazılır, `monthChange`/`viewChange` görünen `start`/`end` aralığıyla tazeleme kancasıdır) |
2254
2346
  | Kayıt detayı | `detailview` — tek kaydı etiket/değer ızgarası basar (alan başına format, iç içe alan yolu); OLAY YAYMAZ, tıklanabilirlik gerekiyorsa kapsayıcıya sar |
2255
2347
  | Adımlı akış | `stepper` — tabs gibi her adım kendi droppable görünümünü taşır; ileri gidiş `canProceed` kapısıyla (`{{ form1.isValid === true }}` biçimi), adım `currentStep` setter'ıyla sürülür |
@@ -2509,7 +2601,7 @@ micro-op hattına dönün.
2509
2601
  > 2026-09-20 öncesinde koruma her op'a tek başına baktığı için düğüm taşıyan her yama ikiye
2510
2602
  > bölünmek zorundaydı (S2-35). Akışı gerçekten referanssız bırakan yama hâlâ durur.
2511
2603
  >
2512
- > **Satır aksiyonları statik şemada görünmeyebilir (TB-126).** `table`/`datatable`'ın
2604
+ > **Satır aksiyonları statik şemada görünmeyebilir (TB-126).** `datatable`'ın
2513
2605
  > `actions[].flow` bağı `{ type: 'flow', ref }` olarak sayılır — ama bu prop'u çoğu zaman YÜKLEME
2514
2606
  > AKIŞI çalışma zamanında yazar (aksiyon role göre eklenip çıkarılıyorsa başka yolu da yok) ve o
2515
2607
  > hâlde şemada `actions` BOŞ durur. `flow_list` böyle bir barındırıcıda `unboundFlowIds` yanına